From beca11e4969f7d312b2307251e28dec18193a93f Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 18 Mar 2015 13:59:57 +0000 Subject: Added an empty file for wc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@486 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fd12027f5ae859c8caaa6a04182c19ff734bdf43 --- src/CMakeLists.txt | 1 + .../include/gudhi/Witness_complex.h | 183 +++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 src/Witness_complex/include/gudhi/Witness_complex.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b67ab2f8..04c4369c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,5 +37,6 @@ else() add_subdirectory(example/Skeleton_blocker) add_subdirectory(example/Contraction) add_subdirectory(example/Hasse_complex) + add_subdirectort(example/Witness_complex) endif() diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h new file mode 100644 index 00000000..fbebea57 --- /dev/null +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -0,0 +1,183 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_WITNESS_COMPLEX_H_ +#define GUDHI_WITNESS_COMPLEX_H_ + +#include +#include +#include +#include "gudhi/reader_utils.h" +#include "gudhi/Simplex_tree.h" +#include +#include + +namespace Gudhi { + + /* +template +class Simplex_tree; + */ + + /* +template +class Witness_complex: public Simplex_tree { + //class Witness_complex: public Simplex_tree { +public: + +// typedef int Simplex_handle; //index in vector complex_ + +// typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; +// typedef boost::iterator_range Boundary_simplex_range; + +// typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator; +// typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range; + +// typedef IndexingTag Indexing_tag; + /** \brief Type for the value of the filtration function. + * + * Must be comparable with <. */ +// typedef FiltrationValue Filtration_value; + /** \brief Key associated to each simplex. + * + * Must be a signed integer type. */ +// typedef SimplexKey Simplex_key; + /** \brief Type for the vertex handle. + * + * Must be a signed integer type. It admits a total order <. */ +// typedef VertexHandle Vertex_handle; + + /* Type of node in the simplex tree. */ +// typedef Simplex_tree_node_explicit_storage Node; + /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ +// typedef typename boost::container::flat_map Dictionary; + +/* + friend class Simplex_tree_node_explicit_storage< Simplex_tree >; + friend class Simplex_tree_siblings< Simplex_tree, Dictionary>; + friend class Simplex_tree_simplex_vertex_iterator< Simplex_tree >; + friend class Simplex_tree_boundary_simplex_iterator< Simplex_tree >; + friend class Simplex_tree_complex_simplex_iterator< Simplex_tree >; + friend class Simplex_tree_skeleton_simplex_iterator< Simplex_tree >; +*/ + + /* \brief Set of nodes sharing a same parent in the simplex tree. */ + /* \brief Set of nodes sharing a same parent in the simplex tree. */ +// typedef Simplex_tree_siblings Siblings; + +/* + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + +Witness_complex(int number_of_landmarks, std::string file_name) +{ + /* + Point_Vector & points; + read_points(file_name, points); + landmark_extraction(points); + */ +/* +} + +private: + + +/** + * \brief Permutes the vector in such a way that the landmarks appear first + */ + +/* +void landmark_extraction(int nbP, Point_Vector & points, int inL) +{ + int i,j; + for (i = 0; i != nbP; ++i) + { + for (j = 0; j != nbP; ) + } +} +*/ + + /* + +double distPoints(Point_t &p, Point_t &q) { + double dist = 0.; + Point_t::iterator itp = p.begin(); + Point_t::iterator itq = q.begin(); + while(itp!=p.end()) { + dist += (*itp - *itq)*(*itp - *itq); + itp++; itq++;} + return dist; +} + +void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) { + //std::cout << "Enter furthestPoints "<< endl; + //Point_Vector *L = new Point_Vector(); + double density = 5.; + int current_number_of_landmarks=0; + double curr_max_dist; + double curr_dist; + double mindist = 10005.; + int curr_max_w=0; + int curr_w=0; + srand(354698); + int rand_int = rand()% nbP; + //std::cout << rand_int << endl; + L.push_back(W[rand_int]);// first landmark is random + current_number_of_landmarks++; + while (1) { + curr_w = 0; + curr_max_dist = -1; + for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { + //compute distance from w and L + mindist = 100000.; + for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { + curr_dist = distPoints(*itW,*itL); + if(curr_dist < mindist) { + mindist = curr_dist; + } + } + if(mindist > curr_max_dist) { + curr_max_w = curr_w; //??? + curr_max_dist = mindist; + } + curr_w++; + } + L.push_back(W[curr_max_w]); + current_number_of_landmarks++; + density = sqrt(curr_max_dist); + //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; + if(L.size() == nbL) break; + } + //std::cout << endl; + return L; +} + */ +}; //class Witness_complex +*/ + +} // namespace Guhdi + +#endif -- cgit v1.2.3 From 246aa7e8de4d6dbfd8ab3fd745a8322e9d5db5dd Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 18 Mar 2015 14:02:17 +0000 Subject: added an empty example file as well git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@487 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 72220440cab950b50ecc192d27bc319bb4dd2d2d --- src/Witness_complex/example/CMakeLists.txt | 17 ++++++++++ .../example/simple_witness_complex.cpp | 37 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Witness_complex/example/CMakeLists.txt create mode 100644 src/Witness_complex/example/simple_witness_complex.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt new file mode 100644 index 00000000..d02522f8 --- /dev/null +++ b/src/Witness_complex/example/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.6) +project(GUDHIWitnessComplex) + +add_executable ( simple_witness_complex simple_witness_complex.cpp ) +add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) + + +# An example with Simplex-tree using CGAL alpha_shapes_3 +#if(GMP_FOUND AND CGAL_FOUND) +# message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") +# message("GMP_LIBRARIES = ${GMP_LIBRARIES}") +# INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) +# INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) +# add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) +# target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY}) +# add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) +#endif() diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp new file mode 100644 index 00000000..9147763f --- /dev/null +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -0,0 +1,37 @@ +/* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" + +using namespace Gudhi; + +//typedef std::vector< Vertex_handle > typeVectorVertex; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +int main (int argc, char * const argv[]) +{ + std::cout << "Howdy world!\n"; +} -- cgit v1.2.3 From 6536cb935d5702425f33d10f514fa450c470096a Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 18 Mar 2015 17:35:25 +0000 Subject: Added witness_complex function carcas git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@489 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 542dd6740b0ae233ea5fb8ea5c6fe313bf1f27d9 --- CMakeLists.txt | 2 + .../include/gudhi/Witness_complex.h | 113 ++++++++++++++------- 2 files changed, 79 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 3afec463..0c8f6ea3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ else() include_directories(src/Persistent_cohomology/include/) include_directories(src/Simplex_tree/include/) include_directories(src/Skeleton_blocker/include/) + include_directories(src/Witness_complex/include/) add_subdirectory(src/Simplex_tree/test) add_subdirectory(src/Simplex_tree/example) @@ -83,6 +84,7 @@ else() add_subdirectory(src/Skeleton_blocker/example) add_subdirectory(src/Contraction/example) add_subdirectory(src/Hasse_complex/example) + add_subdirectory(src/Witness_complex/example) endif() diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index fbebea57..0651e38e 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -27,8 +27,10 @@ #include #include #include "gudhi/reader_utils.h" +#include "gudhi/distance_functions.h" #include "gudhi/Simplex_tree.h" #include +#include #include namespace Gudhi { @@ -40,14 +42,16 @@ template -class Witness_complex: public Simplex_tree { - //class Witness_complex: public Simplex_tree { + class Witness_complex: public Simplex_tree<> { + //class Witness_complex: public Simplex_tree { + //class Witness_complex { public: +//Simplex_tree<> st; // typedef int Simplex_handle; //index in vector complex_ // typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; @@ -88,50 +92,86 @@ public: /* \brief Set of nodes sharing a same parent in the simplex tree. */ // typedef Simplex_tree_siblings Siblings; -/* - typedef std::vector< double > Point_t; - typedef std::vector< Point_t > Point_Vector; +typedef std::vector< double > Point_t; +typedef std::vector< Point_t > Point_Vector; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::pair typeSimplex; +typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; +/* Witness_complex(int number_of_landmarks, std::string file_name) { - /* - Point_Vector & points; - read_points(file_name, points); - landmark_extraction(points); - */ -/* } - -private: - +*/ /** - * \brief Permutes the vector in such a way that the landmarks appear first + * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. + * Landmarks are supposed to be in [0,nbL-1] */ -/* -void landmark_extraction(int nbP, Point_Vector & points, int inL) +template< typename KNearestNeighbours > +void witness_complex(KNearestNeighbours & knn) { - int i,j; - for (i = 0; i != nbP; ++i) - { - for (j = 0; j != nbP; ) + int k=1; /* current dimension in iterative construction */ + //Construction of the active witness list + int nbW = knn.size(); + int nbL = knn.at(0).size(); + VertexHandle vh; + typeVectorVertex vv; + typeSimplex simplex; + typePairSimplexBool returnValue; + /* The list of still useful witnesses + * it will diminuish in the course of iterations + */ + std::forward_list active_w = new std::forward_list(); + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + active_w.push_front(i); } + for (int i=0; i != nbL; ++i) { + // initial fill of 0-dimensional simplices + // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore + vh = (Vertex_handle)i; + vv = {i}; + /* TODO Filtration */ + simplex = std::make_pair(vv,Filtration_value(0.0)); + returnValue = this.insert_simplex(simplex.first, simplex.second); + /* TODO Error if not inserted : normally no need here though*/ + } + while (!active_w.empty() && k+1 < nbL ) { + std::forward_list::iterator it = active_w.begin(); + while (it != active_w.end()) { + typeVectorVertex simplex_vector; + for (int i=0; i != k+1; ++i) { + // create a (k+1) element array for the given active landmark + /* + typeVectorVertex::iterator itSV = simplex_vector.begin(); + while (itSV != simplex_vector.end() && *itSV < knn[*it][i]) { + itSV++; + } + simplex_vector.insert(itSV,knn[*it][i]); + */ + simplex_vector.push_back(knn[*it][i]); + } + /* THE INSERTION: Checking if all the subfaces are in the simplex tree is mandatory */ + bool ok = all_faces_in(simplex_vecter); + returnValue = this.insert_simplex(simplex_vector,0.0); + } + } } -*/ - /* - -double distPoints(Point_t &p, Point_t &q) { - double dist = 0.; - Point_t::iterator itp = p.begin(); - Point_t::iterator itq = q.begin(); - while(itp!=p.end()) { - dist += (*itp - *itq)*(*itp - *itq); - itp++; itq++;} - return dist; +private: + +bool all_faces_in(typeVectorVertex v) +{ +return true; } +/** + * \brief Permutes the vector in such a way that the landmarks appear first + */ + void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) { //std::cout << "Enter furthestPoints "<< endl; //Point_Vector *L = new Point_Vector(); @@ -154,7 +194,8 @@ void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, in //compute distance from w and L mindist = 100000.; for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { - curr_dist = distPoints(*itW,*itL); + //curr_dist = distPoints(*itW,*itL); + curr_dist = euclidean_distance(*itW,*itL); if(curr_dist < mindist) { mindist = curr_dist; } @@ -174,9 +215,9 @@ void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, in //std::cout << endl; return L; } - */ + }; //class Witness_complex -*/ + } // namespace Guhdi -- cgit v1.2.3 From b364c0f0f5a6a6e8cd363403c85480be1e63bcf5 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 19 Mar 2015 15:51:54 +0000 Subject: fixed the edge addition git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@494 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 63206a9ddb444046e6b4202f600637780c0acc05 --- .../include/gudhi/Witness_complex.h | 107 +++++++++++++++------ 1 file changed, 76 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 0651e38e..62ce9187 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -30,7 +30,7 @@ #include "gudhi/distance_functions.h" #include "gudhi/Simplex_tree.h" #include -#include +#include #include namespace Gudhi { @@ -42,17 +42,43 @@ template - class Witness_complex: public Simplex_tree<> { +class Witness_complex: public Simplex_tree<> { //class Witness_complex: public Simplex_tree { //class Witness_complex { -public: +private: + + /* + template < typename Witness_id = int, + typename Landmark_id = int, + typename Simplex_handle = Simplex_handle > + struct Active_witness { + Witness_id witness_id; + Landmark_id landmark_id; + Simplex_handle simplex_handle; + }; + */ + +struct Active_witness { + int witness_id; + int landmark_id; + Simplex_handle simplex_handle; +}; + + + +public: + //Simplex_tree<> st; -// typedef int Simplex_handle; //index in vector complex_ // typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; // typedef boost::iterator_range Boundary_simplex_range; @@ -69,16 +95,18 @@ public: * * Must be a signed integer type. */ // typedef SimplexKey Simplex_key; + /** \brief Type for the vertex handle. * * Must be a signed integer type. It admits a total order <. */ -// typedef VertexHandle Vertex_handle; + typedef VertexHandle Vertex_handle; - /* Type of node in the simplex tree. */ -// typedef Simplex_tree_node_explicit_storage Node; + /* Type of node in the simplex tree. */ + typedef Simplex_tree_node_explicit_storage Node; /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ -// typedef typename boost::container::flat_map Dictionary; - + typedef typename boost::container::flat_map Dictionary; + typedef typename Dictionary::iterator Simplex_handle; + /* friend class Simplex_tree_node_explicit_storage< Simplex_tree >; friend class Simplex_tree_siblings< Simplex_tree, Dictionary>; @@ -93,17 +121,16 @@ public: // typedef Simplex_tree_siblings Siblings; -typedef std::vector< double > Point_t; -typedef std::vector< Point_t > Point_Vector; + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + + typedef std::vector< Vertex_handle > typeVectorVertex; + typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; + typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; -typedef std::vector< Vertex_handle > typeVectorVertex; -typedef std::pair typeSimplex; -typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; -/* -Witness_complex(int number_of_landmarks, std::string file_name) -{ -} -*/ + typedef int Witness_id; + typedef int Landmark_id; + typedef std::list< Active_witness > ActiveWitnessList; /** * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. @@ -124,27 +151,41 @@ void witness_complex(KNearestNeighbours & knn) /* The list of still useful witnesses * it will diminuish in the course of iterations */ - std::forward_list active_w = new std::forward_list(); - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - active_w.push_front(i); - } + ActiveWitnessList active_w = new ActiveWitnessList(); for (int i=0; i != nbL; ++i) { // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore vh = (Vertex_handle)i; vv = {i}; /* TODO Filtration */ - simplex = std::make_pair(vv,Filtration_value(0.0)); + simplex = std::make_pair(vv, Filtration_value(0.0)); returnValue = this.insert_simplex(simplex.first, simplex.second); /* TODO Error if not inserted : normally no need here though*/ } + int u,v; // two extremities of an edge + if (nbL > 1) // if the supposed dimension of the complex is >0 + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if (u > v) { + u = v; + v = knn[i][0]; + } + //Siblings * curr_sib = &root_; + vh = (Vertex_handle)i; + vv = {u,v}; + returnValue = this.insert_simplex(vv,Filtration_value(0.0)); + active_w.push_back(i,v,returnValue.first); + //Simplex_handle sh = root_.members_.begin()+u; + //active_w.push_front(i); + } while (!active_w.empty() && k+1 < nbL ) { - std::forward_list::iterator it = active_w.begin(); + typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { typeVectorVertex simplex_vector; for (int i=0; i != k+1; ++i) { - // create a (k+1) element array for the given active landmark + // create a (k+1) element array for the given active witness /* typeVectorVertex::iterator itSV = simplex_vector.begin(); while (itSV != simplex_vector.end() && *itSV < knn[*it][i]) { @@ -152,11 +193,14 @@ void witness_complex(KNearestNeighbours & knn) } simplex_vector.insert(itSV,knn[*it][i]); */ - simplex_vector.push_back(knn[*it][i]); + // simplex_vector.push_back(knn[*it][i]); } /* THE INSERTION: Checking if all the subfaces are in the simplex tree is mandatory */ - bool ok = all_faces_in(simplex_vecter); - returnValue = this.insert_simplex(simplex_vector,0.0); + bool ok = all_faces_in(simplex_vector); + if (ok) + returnValue = this.insert_simplex(simplex_vector,0.0); + else + active_w.erase(it++); //First increase the iterator and then erase the previous element } } } @@ -165,6 +209,7 @@ private: bool all_faces_in(typeVectorVertex v) { + return true; } -- cgit v1.2.3 From bd9882e11ba5c8602196d416d04849766226e6ed Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 20 Mar 2015 14:02:39 +0000 Subject: witness_complex now compiles git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@495 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8699acb60641842e40874ece61a5a0ecad3fa039 --- .../example/simple_witness_complex.cpp | 20 ++- .../include/gudhi/Witness_complex.h | 177 ++++++++++++++------- 2 files changed, 137 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 9147763f..5eb39eb0 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -27,11 +27,27 @@ using namespace Gudhi; -//typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::vector< Vertex_handle > typeVectorVertex; //typedef std::pair typeSimplex; //typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; int main (int argc, char * const argv[]) { - std::cout << "Howdy world!\n"; + Witness_complex<> wc; + std::vector< typeVectorVertex > KNN; + typeVectorVertex witness0 = {1,7,5,2,6,3,4}; KNN.push_back(witness0 ); + typeVectorVertex witness1 = {2,6,4,5,7,1,3}; KNN.push_back(witness1 ); + typeVectorVertex witness2 = {3,4,2,1,5,6,7}; KNN.push_back(witness2 ); + typeVectorVertex witness3 = {4,2,1,3,5,6,7}; KNN.push_back(witness3 ); + typeVectorVertex witness4 = {5,1,6,7,2,3,4}; KNN.push_back(witness4 ); + typeVectorVertex witness5 = {6,7,5,2,1,3,4}; KNN.push_back(witness5 ); + typeVectorVertex witness6 = {7,5,6,1,2,3,4}; KNN.push_back(witness6 ); + typeVectorVertex witness7 = {2,6,4,5,3,1,7}; KNN.push_back(witness7 ); + typeVectorVertex witness8 = {1,2,5,4,3,6,7}; KNN.push_back(witness8 ); + typeVectorVertex witness9 = {3,4,5,2,6,3,4}; KNN.push_back(witness9 ); + typeVectorVertex witness10 = {5,7,1,3,6,2,4}; KNN.push_back(witness10); + typeVectorVertex witness11 = {5,6,1,7,2,3,4}; KNN.push_back(witness11); + typeVectorVertex witness12 = {1,6,7,5,2,3,4}; KNN.push_back(witness12); + wc.witness_complex(KNN); + std::cout << "Howdy world!\n"; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 62ce9187..624b2a51 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -71,6 +71,12 @@ struct Active_witness { int witness_id; int landmark_id; Simplex_handle simplex_handle; + + Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + : witness_id(witness_id_), + landmark_id(landmark_id_), + simplex_handle(simplex_handle_) + {} }; @@ -144,22 +150,22 @@ void witness_complex(KNearestNeighbours & knn) //Construction of the active witness list int nbW = knn.size(); int nbL = knn.at(0).size(); - VertexHandle vh; + //VertexHandle vh; typeVectorVertex vv; typeSimplex simplex; typePairSimplexBool returnValue; /* The list of still useful witnesses * it will diminuish in the course of iterations */ - ActiveWitnessList active_w = new ActiveWitnessList(); + ActiveWitnessList active_w;// = new ActiveWitnessList(); for (int i=0; i != nbL; ++i) { // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore - vh = (Vertex_handle)i; + //vh = (Vertex_handle)i; vv = {i}; /* TODO Filtration */ simplex = std::make_pair(vv, Filtration_value(0.0)); - returnValue = this.insert_simplex(simplex.first, simplex.second); + returnValue = this->insert_simplex(simplex.first, simplex.second); /* TODO Error if not inserted : normally no need here though*/ } int u,v; // two extremities of an edge @@ -173,10 +179,10 @@ void witness_complex(KNearestNeighbours & knn) v = knn[i][0]; } //Siblings * curr_sib = &root_; - vh = (Vertex_handle)i; + //vh = (Vertex_handle)i; vv = {u,v}; - returnValue = this.insert_simplex(vv,Filtration_value(0.0)); - active_w.push_back(i,v,returnValue.first); + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + active_w.push_back(Active_witness(i,v,returnValue.first)); //Simplex_handle sh = root_.members_.begin()+u; //active_w.push_front(i); } @@ -184,21 +190,19 @@ void witness_complex(KNearestNeighbours & knn) typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { typeVectorVertex simplex_vector; - for (int i=0; i != k+1; ++i) { + typeVectorVertex suffix; + /* + for (int i=0; i != k; ++i) { // create a (k+1) element array for the given active witness - /* - typeVectorVertex::iterator itSV = simplex_vector.begin(); - while (itSV != simplex_vector.end() && *itSV < knn[*it][i]) { - itSV++; - } - simplex_vector.insert(itSV,knn[*it][i]); - */ - // simplex_vector.push_back(knn[*it][i]); + simplex_vector.push_back(knn[it->witness_id][i]); } + + sort(simplex_vector.begin(),simplex_vector.end()); + */ /* THE INSERTION: Checking if all the subfaces are in the simplex tree is mandatory */ - bool ok = all_faces_in(simplex_vector); + bool ok = all_faces_in(knn[it->witness_id][k],it->simplex_handle); if (ok) - returnValue = this.insert_simplex(simplex_vector,0.0); + returnValue = insert_simplex(simplex_vector,0.0); else active_w.erase(it++); //First increase the iterator and then erase the previous element } @@ -207,59 +211,116 @@ void witness_complex(KNearestNeighbours & knn) private: -bool all_faces_in(typeVectorVertex v) -{ - -return true; -} + bool all_faces_in(VertexHandle last, Simplex_handle sh) + { + std::list< VertexHandle > suffix; + Simplex_handle curr_sh = sh; + Siblings * curr_sibl = self_siblings(sh); + VertexHandle curr_vh = curr_sh->first; + while (curr_vh > last) { + suffix.push_front(curr_vh); + curr_vh = curr_sibl->parent(); + curr_sibl = curr_sibl->oncles(); + curr_sh = curr_sibl->find(curr_vh); + } + suffix.push_front(last); + typename std::list< VertexHandle >::iterator itVV = suffix.begin(); + Simplex_handle sh_bup = curr_sh; // Back up the pointer + while (itVV != suffix.end() && curr_sh->second.children()->find(*itVV) != null_simplex()) { + // If the node doesn't exist then stop, else go down the tree + curr_sh = curr_sh->second.children()->find(*itVV); + } + if (itVV == suffix.end()) { + // the simplex is already in the tree + return true; + } + else if (itVV != suffix.end()) { + // the father of the simplex is not in the tree + return false; + } + else { + // CHECK ALL THE FACETS + curr_sh = sh_bup; + while (curr_sibl != root()) { + suffix.push_front(curr_vh); + curr_vh = curr_sibl->parent(); + curr_sibl = curr_sibl->oncles(); + curr_sh = curr_sibl->find(curr_vh); + } + suffix.push_front(curr_vh); + sh_bup = curr_sh; // the first vertex lexicographicly + for (typename std::list< VertexHandle >::iterator itExcl = suffix.begin(); itExcl != suffix.end(); ++itExcl) { + if (*itExcl != last) { + itVV = suffix.begin(); + while (itVV != itExcl) { + if (curr_sibl->find(*itVV) == null_simplex()) + return false; + curr_sh = curr_sibl->find(*itVV); + curr_sibl = self_siblings(curr_sh); + itVV++; + } + itVV++; + while (itVV != suffix.end()) { + if (curr_sibl->find(*itVV) == null_simplex()) + return false; + curr_sh = curr_sibl->find(*itVV); + curr_sibl = self_siblings(curr_sh); + itVV++; + } //endwhile + } //endif + } //endfor + return true; + } //end check all the facets + } /** * \brief Permutes the vector in such a way that the landmarks appear first */ -void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) { + void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) + { //std::cout << "Enter furthestPoints "<< endl; //Point_Vector *L = new Point_Vector(); - double density = 5.; - int current_number_of_landmarks=0; - double curr_max_dist; - double curr_dist; - double mindist = 10005.; - int curr_max_w=0; - int curr_w=0; - srand(354698); - int rand_int = rand()% nbP; - //std::cout << rand_int << endl; - L.push_back(W[rand_int]);// first landmark is random - current_number_of_landmarks++; - while (1) { - curr_w = 0; - curr_max_dist = -1; - for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { - //compute distance from w and L - mindist = 100000.; - for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { + double density = 5.; + int current_number_of_landmarks=0; + double curr_max_dist; + double curr_dist; + double mindist = 10005.; + int curr_max_w=0; + int curr_w=0; + srand(354698); + int rand_int = rand()% nbP; + //std::cout << rand_int << endl; + L.push_back(W[rand_int]);// first landmark is random + current_number_of_landmarks++; + while (1) { + curr_w = 0; + curr_max_dist = -1; + for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { + //compute distance from w and L + mindist = 100000.; + for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { //curr_dist = distPoints(*itW,*itL); curr_dist = euclidean_distance(*itW,*itL); - if(curr_dist < mindist) { - mindist = curr_dist; + if(curr_dist < mindist) { + mindist = curr_dist; + } } + if(mindist > curr_max_dist) { + curr_max_w = curr_w; //??? + curr_max_dist = mindist; + } + curr_w++; } - if(mindist > curr_max_dist) { - curr_max_w = curr_w; //??? - curr_max_dist = mindist; - } - curr_w++; + L.push_back(W[curr_max_w]); + current_number_of_landmarks++; + density = sqrt(curr_max_dist); + //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; + if(L.size() == nbL) break; } - L.push_back(W[curr_max_w]); - current_number_of_landmarks++; - density = sqrt(curr_max_dist); - //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; - if(L.size() == nbL) break; + //std::cout << endl; + return L; } - //std::cout << endl; - return L; -} }; //class Witness_complex -- cgit v1.2.3 From fe296c664a0655fbc4814c51105570773731fb88 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 20 Mar 2015 15:55:02 +0000 Subject: Started tests git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@496 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cd644bc64c0183dbadb8bbdecde6ccc77e7d3c84 --- .../example/simple_witness_complex.cpp | 29 ++++++++++--------- .../include/gudhi/Witness_complex.h | 33 ++++++++++++++-------- 2 files changed, 37 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 5eb39eb0..853918b8 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -33,21 +33,22 @@ typedef std::vector< Vertex_handle > typeVectorVertex; int main (int argc, char * const argv[]) { - Witness_complex<> wc; + Witness_complex<> witnessComplex = Witness_complex<>(); std::vector< typeVectorVertex > KNN; - typeVectorVertex witness0 = {1,7,5,2,6,3,4}; KNN.push_back(witness0 ); - typeVectorVertex witness1 = {2,6,4,5,7,1,3}; KNN.push_back(witness1 ); - typeVectorVertex witness2 = {3,4,2,1,5,6,7}; KNN.push_back(witness2 ); - typeVectorVertex witness3 = {4,2,1,3,5,6,7}; KNN.push_back(witness3 ); - typeVectorVertex witness4 = {5,1,6,7,2,3,4}; KNN.push_back(witness4 ); - typeVectorVertex witness5 = {6,7,5,2,1,3,4}; KNN.push_back(witness5 ); - typeVectorVertex witness6 = {7,5,6,1,2,3,4}; KNN.push_back(witness6 ); - typeVectorVertex witness7 = {2,6,4,5,3,1,7}; KNN.push_back(witness7 ); - typeVectorVertex witness8 = {1,2,5,4,3,6,7}; KNN.push_back(witness8 ); + typeVectorVertex witness0 = {1,0,5,2,6,3,4}; KNN.push_back(witness0 ); + typeVectorVertex witness1 = {2,6,4,5,0,1,3}; KNN.push_back(witness1 ); + typeVectorVertex witness2 = {3,4,2,1,5,6,0}; KNN.push_back(witness2 ); + typeVectorVertex witness3 = {4,2,1,3,5,6,0}; KNN.push_back(witness3 ); + typeVectorVertex witness4 = {5,1,6,0,2,3,4}; KNN.push_back(witness4 ); + typeVectorVertex witness5 = {6,0,5,2,1,3,4}; KNN.push_back(witness5 ); + typeVectorVertex witness6 = {0,5,6,1,2,3,4}; KNN.push_back(witness6 ); + typeVectorVertex witness7 = {2,6,4,5,3,1,0}; KNN.push_back(witness7 ); + typeVectorVertex witness8 = {1,2,5,4,3,6,0}; KNN.push_back(witness8 ); typeVectorVertex witness9 = {3,4,5,2,6,3,4}; KNN.push_back(witness9 ); - typeVectorVertex witness10 = {5,7,1,3,6,2,4}; KNN.push_back(witness10); - typeVectorVertex witness11 = {5,6,1,7,2,3,4}; KNN.push_back(witness11); - typeVectorVertex witness12 = {1,6,7,5,2,3,4}; KNN.push_back(witness12); - wc.witness_complex(KNN); + typeVectorVertex witness10 = {5,0,1,3,6,2,4}; KNN.push_back(witness10); + typeVectorVertex witness11 = {5,6,1,0,2,3,4}; KNN.push_back(witness11); + typeVectorVertex witness12 = {1,6,0,5,2,3,4}; KNN.push_back(witness12); + std::cout << "Let the carnage begin!\n"; + witnessComplex.witness_complex(KNN); std::cout << "Howdy world!\n"; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 624b2a51..985660d4 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -33,6 +33,8 @@ #include #include +#include + namespace Gudhi { /* @@ -143,13 +145,17 @@ public: * Landmarks are supposed to be in [0,nbL-1] */ + template< typename KNearestNeighbours > void witness_complex(KNearestNeighbours & knn) +//void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) { - int k=1; /* current dimension in iterative construction */ + std::cout << "**Start the procedure witness_complex" << std::endl; + int k=2; /* current dimension in iterative construction */ //Construction of the active witness list int nbW = knn.size(); int nbL = knn.at(0).size(); + std::cout << "Eh?\n"; //VertexHandle vh; typeVectorVertex vv; typeSimplex simplex; @@ -164,10 +170,12 @@ void witness_complex(KNearestNeighbours & knn) //vh = (Vertex_handle)i; vv = {i}; /* TODO Filtration */ - simplex = std::make_pair(vv, Filtration_value(0.0)); - returnValue = this->insert_simplex(simplex.first, simplex.second); + //simplex = std::make_pair(vv, Filtration_value(0.0)); + //returnValue = this->insert_simplex(simplex.first, simplex.second); + returnValue = this->insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ } + std::cout << "Successfully added landmarks" << std::endl; int u,v; // two extremities of an edge if (nbL > 1) // if the supposed dimension of the complex is >0 for (int i=0; i != nbW; ++i) { @@ -183,22 +191,17 @@ void witness_complex(KNearestNeighbours & knn) vv = {u,v}; returnValue = this->insert_simplex(vv,Filtration_value(0.0)); active_w.push_back(Active_witness(i,v,returnValue.first)); + if (returnValue.second) std::cout << "Added edge " << u << v << std::endl; //Simplex_handle sh = root_.members_.begin()+u; //active_w.push_front(i); } + std::cout << "Successfully added edges" << std::endl; while (!active_w.empty() && k+1 < nbL ) { + std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { typeVectorVertex simplex_vector; typeVectorVertex suffix; - /* - for (int i=0; i != k; ++i) { - // create a (k+1) element array for the given active witness - simplex_vector.push_back(knn[it->witness_id][i]); - } - - sort(simplex_vector.begin(),simplex_vector.end()); - */ /* THE INSERTION: Checking if all the subfaces are in the simplex tree is mandatory */ bool ok = all_faces_in(knn[it->witness_id][k],it->simplex_handle); if (ok) @@ -206,6 +209,7 @@ void witness_complex(KNearestNeighbours & knn) else active_w.erase(it++); //First increase the iterator and then erase the previous element } + k++; } } @@ -213,16 +217,23 @@ private: bool all_faces_in(VertexHandle last, Simplex_handle sh) { + std::cout << "All face in with the landmark " << last << std::endl; std::list< VertexHandle > suffix; Simplex_handle curr_sh = sh; Siblings * curr_sibl = self_siblings(sh); VertexHandle curr_vh = curr_sh->first; while (curr_vh > last) { + std::cout << "We are at " << curr_vh << "\n"; suffix.push_front(curr_vh); + std::cout << "Still fine 1\n"; curr_vh = curr_sibl->parent(); + std::cout << "Still fine 2\n"; curr_sibl = curr_sibl->oncles(); + std::cout << "Still fine 3\n"; curr_sh = curr_sibl->find(curr_vh); + std::cout << "Still fine 4\n"; } + std::cout << "Arrived at the mid-parent" << std::endl; suffix.push_front(last); typename std::list< VertexHandle >::iterator itVV = suffix.begin(); Simplex_handle sh_bup = curr_sh; // Back up the pointer -- cgit v1.2.3 From 14278a8f1a9a066636a595372cf41025b17fe1d8 Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 23 Mar 2015 10:02:28 +0000 Subject: Wild Bug appeared git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@497 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b057061087ac0442ec51ee18c40c227dc721f9b5 --- .../include/gudhi/Witness_complex.h | 105 ++++++++++++++++++--- 1 file changed, 92 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 985660d4..3deb8bc3 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -23,6 +23,7 @@ #ifndef GUDHI_WITNESS_COMPLEX_H_ #define GUDHI_WITNESS_COMPLEX_H_ +#include #include #include #include @@ -155,11 +156,11 @@ void witness_complex(KNearestNeighbours & knn) //Construction of the active witness list int nbW = knn.size(); int nbL = knn.at(0).size(); - std::cout << "Eh?\n"; //VertexHandle vh; typeVectorVertex vv; typeSimplex simplex; typePairSimplexBool returnValue; + int counter = 0; /* The list of still useful witnesses * it will diminuish in the course of iterations */ @@ -168,33 +169,73 @@ void witness_complex(KNearestNeighbours & knn) // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore //vh = (Vertex_handle)i; + counter++; vv = {i}; /* TODO Filtration */ //simplex = std::make_pair(vv, Filtration_value(0.0)); //returnValue = this->insert_simplex(simplex.first, simplex.second); - returnValue = this->insert_simplex(vv, Filtration_value(0.0)); + //returnValue = insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ } + vv = {0}; + returnValue = insert_simplex(vv,Filtration_value(0.0)); std::cout << "Successfully added landmarks" << std::endl; + // PRINT2 + print_sc(root()); int u,v; // two extremities of an edge if (nbL > 1) // if the supposed dimension of the complex is >0 - for (int i=0; i != nbW; ++i) { + /* + // THE BUGGY CODE + for (int i=0; i != nbW; ++i) { // initial fill of active witnesses list u = knn[i][0]; v = knn[i][1]; - if (u > v) { - u = v; - v = knn[i][0]; - } //Siblings * curr_sib = &root_; //vh = (Vertex_handle)i; vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - active_w.push_back(Active_witness(i,v,returnValue.first)); - if (returnValue.second) std::cout << "Added edge " << u << v << std::endl; + counter++; + returnValue = this->insert_simplex(vv,Filtration_value((double)counter)); + //std::cout << "Null simplex is " << null_simplex()->first << std::endl; + if (returnValue.first != null_simplex()) + { + active_w.push_back(*(new Active_witness(i,v,returnValue.first))); + } + for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) + std::cout << it1->simplex_handle->first << " "; + std::cout << std::endl; //Simplex_handle sh = root_.members_.begin()+u; //active_w.push_front(i); } + */ + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + //Siblings * curr_sib = &root_; + //vh = (Vertex_handle)i; + vv = {u,v}; + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if ( u > v) { + u = v; + v = knn[i][0]; + } + Simplex_handle sh; + vv = {u,v}; + sh = (root()->find(u))->second.children()->find(v); + + active_w.push_back(*(new Active_witness(i,v,sh))); + for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) + std::cout << it1->simplex_handle->first << " "; + std::cout << std::endl; + } + std::cout << "Successfully added edges" << std::endl; while (!active_w.empty() && k+1 < nbL ) { std::cout << "Started the step k=" << k << std::endl; @@ -202,12 +243,14 @@ void witness_complex(KNearestNeighbours & knn) while (it != active_w.end()) { typeVectorVertex simplex_vector; typeVectorVertex suffix; - /* THE INSERTION: Checking if all the subfaces are in the simplex tree is mandatory */ + /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ + std::cout << it->simplex_handle->first << std::endl; bool ok = all_faces_in(knn[it->witness_id][k],it->simplex_handle); if (ok) returnValue = insert_simplex(simplex_vector,0.0); else - active_w.erase(it++); //First increase the iterator and then erase the previous element + active_w.erase(it); //First increase the iterator and then erase the previous element + it++; } k++; } @@ -215,6 +258,34 @@ void witness_complex(KNearestNeighbours & knn) private: + void print_sc(Siblings * sibl) + { + if (sibl == NULL) + std::cout << "&"; + else + print_children(sibl->members_); + } + + void print_children(Dictionary map) + { + std::cout << "("; + if (!map.empty()) + { + std::cout << map.begin()->first; + print_sc(map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + std::cout << "," << it->first; + } + } + std::cout << ")\n"; + } + + + /** Check if all the facets of a simplex we are going to insert are in the simplex tree or not. + * The only purpose is to test if the witness is still active or not. + */ bool all_faces_in(VertexHandle last, Simplex_handle sh) { std::cout << "All face in with the landmark " << last << std::endl; @@ -223,7 +294,7 @@ private: Siblings * curr_sibl = self_siblings(sh); VertexHandle curr_vh = curr_sh->first; while (curr_vh > last) { - std::cout << "We are at " << curr_vh << "\n"; + std::cout << "We are at " << curr_sh->first << " " << sh->first << "\n"; suffix.push_front(curr_vh); std::cout << "Still fine 1\n"; curr_vh = curr_sibl->parent(); @@ -239,14 +310,22 @@ private: Simplex_handle sh_bup = curr_sh; // Back up the pointer while (itVV != suffix.end() && curr_sh->second.children()->find(*itVV) != null_simplex()) { // If the node doesn't exist then stop, else go down the tree + std::cout << "DOWN!" << curr_sh->first << " -> " << *itVV << std::endl; + std::cout << "Children of " << curr_sh->first << " are "; + for (typename Dictionary::iterator itt = curr_sh->second.children()->members_.begin(); itt != curr_sh->second.children()->members_.end(); ++itt) + std::cout << itt->first << ","; + std::cout << std::endl; curr_sh = curr_sh->second.children()->find(*itVV); + itVV++; } if (itVV == suffix.end()) { // the simplex is already in the tree + std::cout << "The simplex is there" << std::endl; return true; } else if (itVV != suffix.end()) { // the father of the simplex is not in the tree + std::cout << "The father is not there. Deleting witness." << std::endl; return false; } else { -- cgit v1.2.3 From b11daa7d34fc4f3870d8f247895dd5da28526ada Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 23 Mar 2015 15:28:11 +0000 Subject: Fixed the print bug git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@498 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 89201b558bfb27542e9e187b53a2307fb0054fbc --- CMakeLists.txt | 1 + src/Simplex_tree/include/gudhi/Simplex_tree.h | 1 + src/Witness_complex/include/gudhi/Witness_complex.h | 20 ++++++++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c8f6ea3..f3b29994 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ else() add_subdirectory(src/Skeleton_blocker/example) add_subdirectory(src/Contraction/example) add_subdirectory(src/Hasse_complex/example) + add_subdirectory(src/Witness_complex/test) add_subdirectory(src/Witness_complex/example) endif() diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index a1758680..e52fe1ae 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace Gudhi { diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 3deb8bc3..e999928f 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -174,14 +174,14 @@ void witness_complex(KNearestNeighbours & knn) /* TODO Filtration */ //simplex = std::make_pair(vv, Filtration_value(0.0)); //returnValue = this->insert_simplex(simplex.first, simplex.second); - //returnValue = insert_simplex(vv, Filtration_value(0.0)); + returnValue = insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ } - vv = {0}; - returnValue = insert_simplex(vv,Filtration_value(0.0)); + //vv = {0}; + //returnValue = insert_simplex(vv,Filtration_value(0.0)); std::cout << "Successfully added landmarks" << std::endl; // PRINT2 - print_sc(root()); + print_sc(root()); std::cout << std::endl; int u,v; // two extremities of an edge if (nbL > 1) // if the supposed dimension of the complex is >0 /* @@ -215,6 +215,7 @@ void witness_complex(KNearestNeighbours & knn) //vh = (Vertex_handle)i; vv = {u,v}; returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + print_sc(root()); std::cout << std::endl; //std::cout << "Added edges" << std::endl; } //print_sc(root()); @@ -272,14 +273,21 @@ private: if (!map.empty()) { std::cout << map.begin()->first; - print_sc(map.begin()->second.children()); + if (map.begin()->second.children() == root()) + std::cout << "Sweet potato"; + if (has_children(map.begin())) + print_sc(map.begin()->second.children()); typename Dictionary::iterator it; for (it = map.begin()+1; it != map.end(); ++it) { std::cout << "," << it->first; + if (map.begin()->second.children() == root()) + std::cout << "Sweet potato"; + if (has_children(it)) + print_sc(it->second.children()); } } - std::cout << ")\n"; + std::cout << ")"; } -- cgit v1.2.3 From 4544ed4a3f4ae834a2c7bd0a8f7139a40889657d Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 23 Mar 2015 19:02:01 +0000 Subject: Added an altrnative Witness_complex.h git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@499 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6a7014da8d37c88e0e87317f185d1daa989c87d1 --- .../example/simple_witness_complex.cpp | 2 +- .../include/gudhi/Witness_complex.h | 18 +- .../include/gudhi/Witness_complex1.h | 400 +++++++++++++++++++++ 3 files changed, 410 insertions(+), 10 deletions(-) create mode 100644 src/Witness_complex/include/gudhi/Witness_complex1.h (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 853918b8..6c70d300 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -23,7 +23,7 @@ #include #include //#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Witness_complex.h" +#include "gudhi/Witness_complex1.h" using namespace Gudhi; diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index e999928f..1a96128f 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -231,10 +231,10 @@ void witness_complex(KNearestNeighbours & knn) vv = {u,v}; sh = (root()->find(u))->second.children()->find(v); - active_w.push_back(*(new Active_witness(i,v,sh))); - for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) - std::cout << it1->simplex_handle->first << " "; - std::cout << std::endl; + active_w.push_back(Active_witness(i,v,sh)); + /*for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) + std::cout << it1->simplex->first << " "; + std::cout << std::endl; */ } std::cout << "Successfully added edges" << std::endl; @@ -245,7 +245,7 @@ void witness_complex(KNearestNeighbours & knn) typeVectorVertex simplex_vector; typeVectorVertex suffix; /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ - std::cout << it->simplex_handle->first << std::endl; + // std::cout << it->simplex->first << std::endl; bool ok = all_faces_in(knn[it->witness_id][k],it->simplex_handle); if (ok) returnValue = insert_simplex(simplex_vector,0.0); @@ -304,13 +304,13 @@ private: while (curr_vh > last) { std::cout << "We are at " << curr_sh->first << " " << sh->first << "\n"; suffix.push_front(curr_vh); - std::cout << "Still fine 1\n"; + //std::cout << "Still fine 1\n"; curr_vh = curr_sibl->parent(); - std::cout << "Still fine 2\n"; + //std::cout << "Still fine 2\n"; curr_sibl = curr_sibl->oncles(); - std::cout << "Still fine 3\n"; + //std::cout << "Still fine 3\n"; curr_sh = curr_sibl->find(curr_vh); - std::cout << "Still fine 4\n"; + //std::cout << "Still fine 4\n"; } std::cout << "Arrived at the mid-parent" << std::endl; suffix.push_front(last); diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h new file mode 100644 index 00000000..911dcbe7 --- /dev/null +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -0,0 +1,400 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_WITNESS_COMPLEX_H_ +#define GUDHI_WITNESS_COMPLEX_H_ + +#include +#include +#include +#include +#include "gudhi/reader_utils.h" +#include "gudhi/distance_functions.h" +#include "gudhi/Simplex_tree.h" +#include +#include +#include + +#include + +namespace Gudhi { + + /* +template +class Simplex_tree; + */ + + /* + typedef int Witness_id; +typedef int Landmark_id; +typedef int Simplex_handle; //index in vector complex_ + */ + +template +class Witness_complex: public Simplex_tree<> { + //class Witness_complex: public Simplex_tree { + //class Witness_complex { +private: + + /* + template < typename Witness_id = int, + typename Landmark_id = int, + typename Simplex_handle = Simplex_handle > + struct Active_witness { + Witness_id witness_id; + Landmark_id landmark_id; + Simplex_handle simplex_handle; + }; + */ + +struct Active_witness { + int witness_id; + int landmark_id; + Simplex_handle simplex_handle; + + Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + : witness_id(witness_id_), + landmark_id(landmark_id_), + simplex_handle(simplex_handle_) + {} +}; + + + + +public: + +//Simplex_tree<> st; + +// typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; +// typedef boost::iterator_range Boundary_simplex_range; + +// typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator; +// typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range; + +// typedef IndexingTag Indexing_tag; + /** \brief Type for the value of the filtration function. + * + * Must be comparable with <. */ +// typedef FiltrationValue Filtration_value; + /** \brief Key associated to each simplex. + * + * Must be a signed integer type. */ +// typedef SimplexKey Simplex_key; + + /** \brief Type for the vertex handle. + * + * Must be a signed integer type. It admits a total order <. */ + typedef VertexHandle Vertex_handle; + + /* Type of node in the simplex tree. */ + typedef Simplex_tree_node_explicit_storage Node; + /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ + typedef typename boost::container::flat_map Dictionary; + typedef typename Dictionary::iterator Simplex_handle; + +/* + friend class Simplex_tree_node_explicit_storage< Simplex_tree >; + friend class Simplex_tree_siblings< Simplex_tree, Dictionary>; + friend class Simplex_tree_simplex_vertex_iterator< Simplex_tree >; + friend class Simplex_tree_boundary_simplex_iterator< Simplex_tree >; + friend class Simplex_tree_complex_simplex_iterator< Simplex_tree >; + friend class Simplex_tree_skeleton_simplex_iterator< Simplex_tree >; +*/ + + /* \brief Set of nodes sharing a same parent in the simplex tree. */ + /* \brief Set of nodes sharing a same parent in the simplex tree. */ +// typedef Simplex_tree_siblings Siblings; + + + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + + typedef std::vector< Vertex_handle > typeVectorVertex; + typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; + typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + typedef int Witness_id; + typedef int Landmark_id; + typedef std::list< Vertex_handle > ActiveWitnessList; + +/** + * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. + * Landmarks are supposed to be in [0,nbL-1] + */ + + +template< typename KNearestNeighbours > +void witness_complex(KNearestNeighbours & knn) +//void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) +{ + std::cout << "**Start the procedure witness_complex" << std::endl; + int k=2; /* current dimension in iterative construction */ + //Construction of the active witness list + int nbW = knn.size(); + int nbL = knn.at(0).size(); + //VertexHandle vh; + typeVectorVertex vv; + typeSimplex simplex; + typePairSimplexBool returnValue; + int counter = 0; + /* The list of still useful witnesses + * it will diminuish in the course of iterations + */ + ActiveWitnessList active_w;// = new ActiveWitnessList(); + for (int i=0; i != nbL; ++i) { + // initial fill of 0-dimensional simplices + // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore + //vh = (Vertex_handle)i; + counter++; + vv = {i}; + /* TODO Filtration */ + //simplex = std::make_pair(vv, Filtration_value(0.0)); + //returnValue = this->insert_simplex(simplex.first, simplex.second); + returnValue = insert_simplex(vv, Filtration_value(0.0)); + /* TODO Error if not inserted : normally no need here though*/ + } + //vv = {0}; + //returnValue = insert_simplex(vv,Filtration_value(0.0)); + std::cout << "Successfully added landmarks" << std::endl; + // PRINT2 + print_sc(root()); std::cout << std::endl; + int u,v; // two extremities of an edge + if (nbL > 1) // if the supposed dimension of the complex is >0 + /* + // THE BUGGY CODE + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + //Siblings * curr_sib = &root_; + //vh = (Vertex_handle)i; + vv = {u,v}; + counter++; + returnValue = this->insert_simplex(vv,Filtration_value((double)counter)); + //std::cout << "Null simplex is " << null_simplex()->first << std::endl; + if (returnValue.first != null_simplex()) + { + active_w.push_back(*(new Active_witness(i,v,returnValue.first))); + } + for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) + std::cout << it1->simplex_handle->first << " "; + std::cout << std::endl; + //Simplex_handle sh = root_.members_.begin()+u; + //active_w.push_front(i); + } + */ + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + //Siblings * curr_sib = &root_; + //vh = (Vertex_handle)i; + vv = {u,v}; + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + print_sc(root()); std::cout << std::endl; + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + for (int i=0; i != nbW; ++i) { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if ( u > v) { + u = v; + v = knn[i][0]; + knn[i][0] = knn[i][1]; + knn[i][1] = v; + } + Simplex_handle sh; + vv = {u,v}; + sh = (root()->find(u))->second.children()->find(v); + + active_w.push_back(i); + /*for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) + std::cout << it1->simplex->first << " "; + std::cout << std::endl; */ + } + + std::cout << "Successfully added edges" << std::endl; + while (!active_w.empty() && k+1 < nbL ) { + std::cout << "Started the step k=" << k << std::endl; + typename ActiveWitnessList::iterator it = active_w.begin(); + while (it != active_w.end()) { + typeVectorVertex simplex_vector; + /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ + // First sort the first k landmarks + int i = k; + int temp_swap; + VertexHandle inserted_vertex = knn[*it][k]; + while (i>0 && knn[*it][i-1] > knn[*it][i]) + { + temp_swap = knn[*it][i]; + knn[*it][i] = knn[*it][i-1]; + knn[*it][i-1] = temp_swap; + i--; + } + bool ok = all_faces_in(knn, *it, k, inserted_vertex); + if (ok) + { + for (i = 0; i != k+1; ++i) + { + simplex_vector.push_back(knn[*it][i]); + } + returnValue = insert_simplex(simplex_vector,0.0); + } + else + active_w.erase(it); //First increase the iterator and then erase the previous element + it++; + } + print_sc(root()); + k++; + } +} + +private: + + void print_sc(Siblings * sibl) + { + if (sibl == NULL) + std::cout << "&"; + else + print_children(sibl->members_); + } + + void print_children(Dictionary map) + { + std::cout << "("; + if (!map.empty()) + { + std::cout << map.begin()->first; + /*if (map.begin()->second.children() == root()) + std::cout << "Sweet potato"; */ + if (has_children(map.begin())) + print_sc(map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + std::cout << "," << it->first; + /*if (map.begin()->second.children() == root()) + std::cout << "Sweet potato";*/ + if (has_children(it)) + print_sc(it->second.children()); + } + } + std::cout << ")"; + } + + + /** Check if all the facets of a simplex we are going to insert are in the simplex tree or not. + * The only purpose is to test if the witness is still active or not. + * Assuming here that the list of the first k witnessed landmarks is sorted + */ + template< typename KNearestNeighbours > + bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) + { + std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + //std::list< VertexHandle > suffix; + Simplex_handle curr_sh = root()->find(knn[witness_id][0]); + Siblings * curr_sibl = root(); + //VertexHandle curr_vh = curr_sh->first; + // CHECK ALL THE FACETS + Simplex_handle sh_bup = curr_sh; // the first vertex lexicographicly + for (int i = 0; i != k+1; ++i) + { + curr_sh = sh_bup; + if (knn[witness_id][i] != inserted_vertex) + { + for (int j = 0; j != k+1; ++j) + { + if (j != i) + { + if (curr_sibl->find(knn[witness_id][j]) == null_simplex()) + return false; + curr_sh = curr_sibl->find(knn[witness_id][j]); + curr_sibl = self_siblings(curr_sh); + }//endif j!=i + }//endfor + }//endif + } //endfor + return true; + } + +/** + * \brief Permutes the vector in such a way that the landmarks appear first + */ + + void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) + { + //std::cout << "Enter furthestPoints "<< endl; + //Point_Vector *L = new Point_Vector(); + double density = 5.; + int current_number_of_landmarks=0; + double curr_max_dist; + double curr_dist; + double mindist = 10005.; + int curr_max_w=0; + int curr_w=0; + srand(354698); + int rand_int = rand()% nbP; + //std::cout << rand_int << endl; + L.push_back(W[rand_int]);// first landmark is random + current_number_of_landmarks++; + while (1) { + curr_w = 0; + curr_max_dist = -1; + for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { + //compute distance from w and L + mindist = 100000.; + for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { + //curr_dist = distPoints(*itW,*itL); + curr_dist = euclidean_distance(*itW,*itL); + if(curr_dist < mindist) { + mindist = curr_dist; + } + } + if(mindist > curr_max_dist) { + curr_max_w = curr_w; //??? + curr_max_dist = mindist; + } + curr_w++; + } + L.push_back(W[curr_max_w]); + current_number_of_landmarks++; + density = sqrt(curr_max_dist); + //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; + if(L.size() == nbL) break; + } + //std::cout << endl; + return L; + } + +}; //class Witness_complex + + +} // namespace Guhdi + +#endif -- cgit v1.2.3 From 5b97c28ac4414198458de285768460500531e7ec Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 23 Mar 2015 19:11:13 +0000 Subject: Adding everything to the simplex tree, but no more segmentation fault. 500th commit :-) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@500 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2f8d28811e6801ba18f53ca627a3839878c46708 --- src/Witness_complex/example/simple_witness_complex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 6c70d300..7a46ffb3 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -44,7 +44,7 @@ int main (int argc, char * const argv[]) typeVectorVertex witness6 = {0,5,6,1,2,3,4}; KNN.push_back(witness6 ); typeVectorVertex witness7 = {2,6,4,5,3,1,0}; KNN.push_back(witness7 ); typeVectorVertex witness8 = {1,2,5,4,3,6,0}; KNN.push_back(witness8 ); - typeVectorVertex witness9 = {3,4,5,2,6,3,4}; KNN.push_back(witness9 ); + typeVectorVertex witness9 = {3,4,0,6,5,1,2}; KNN.push_back(witness9 ); typeVectorVertex witness10 = {5,0,1,3,6,2,4}; KNN.push_back(witness10); typeVectorVertex witness11 = {5,6,1,0,2,3,4}; KNN.push_back(witness11); typeVectorVertex witness12 = {1,6,0,5,2,3,4}; KNN.push_back(witness12); -- cgit v1.2.3 From b33bcf4bb496870b73ee6c4783777bf794e28fb7 Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 23 Mar 2015 19:16:09 +0000 Subject: Prevented a possible bug in witness_complex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@501 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fa192bb3623622dde84686e8eaa36d2cc51db2c5 --- src/Witness_complex/include/gudhi/Witness_complex1.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index 911dcbe7..acb83647 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -265,10 +265,10 @@ void witness_complex(KNearestNeighbours & knn) simplex_vector.push_back(knn[*it][i]); } returnValue = insert_simplex(simplex_vector,0.0); + it++ } else - active_w.erase(it); //First increase the iterator and then erase the previous element - it++; + active_w.erase(it++); //First increase the iterator and then erase the previous element } print_sc(root()); k++; -- cgit v1.2.3 From 1ec3e1ae82dab1109ce871f690df716fb05c6a16 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 24 Mar 2015 12:31:43 +0000 Subject: Now at every loop curr_sibl to root() as it should git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@502 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 618fbf7be18e0caa150132a63466d77205634479 --- src/Witness_complex/include/gudhi/Witness_complex1.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index acb83647..6950c3bf 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -265,12 +265,12 @@ void witness_complex(KNearestNeighbours & knn) simplex_vector.push_back(knn[*it][i]); } returnValue = insert_simplex(simplex_vector,0.0); - it++ + it++; } else active_w.erase(it++); //First increase the iterator and then erase the previous element + print_sc(root()); std::cout << std::endl; } - print_sc(root()); k++; } } @@ -326,16 +326,28 @@ private: for (int i = 0; i != k+1; ++i) { curr_sh = sh_bup; + curr_sibl = root(); if (knn[witness_id][i] != inserted_vertex) { for (int j = 0; j != k+1; ++j) { if (j != i) { + std::cout << "+++ We are at vertex=" << knn[witness_id][j] << std::endl; if (curr_sibl->find(knn[witness_id][j]) == null_simplex()) return false; + std::cout << "++++ the simplex is there\n"; curr_sh = curr_sibl->find(knn[witness_id][j]); - curr_sibl = self_siblings(curr_sh); + std::cout << "++++ curr_sh affectation is OK\n"; + if (has_children(curr_sh)) + curr_sibl = curr_sh->second.children(); + else + if (j < k || (j < k-1 && i == k)) + { + std::cout << "++++ the values: j=" << j << ", k=" << k << std::endl; + return false; + } + std::cout << "++++ finished loop safely\n"; }//endif j!=i }//endfor }//endif -- cgit v1.2.3 From 932b79f06816cf9425f9ff37e09ee5daf2c65597 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 25 Mar 2015 15:36:42 +0000 Subject: witness_complex worked on a small example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@506 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 77a0284610e0376a827adfe516aeedfcd634348d --- .../include/gudhi/Witness_complex1.h | 47 +++++++++++++++++----- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index 49ba7529..5333e5a8 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -313,6 +313,8 @@ private: * The only purpose is to test if the witness is still active or not. * Assuming here that the list of the first k witnessed landmarks is sorted */ + + /* template< typename KNearestNeighbours > bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) { @@ -334,19 +336,17 @@ private: if (j != i) { std::cout << "+++ We are at vertex=" << knn[witness_id][j] << std::endl; - if (curr_sibl->members().find(knn[witness_id][j]) == null_simplex()) + if (curr_sibl->find(knn[witness_id][j]) == null_simplex()) return false; std::cout << "++++ the simplex is there\n"; - curr_sh = curr_sibl->members().find(knn[witness_id][j]); + curr_sh = curr_sibl->find(knn[witness_id][j]); std::cout << "++++ curr_sh affectation is OK\n"; - if (has_children(curr_sh)) - curr_sibl = curr_sh->second.children(); - else - if (j < k || (j < k-1 && i == k)) - { - std::cout << "++++ the values: j=" << j << ", k=" << k << std::endl; - return false; - } + if (!has_children(curr_sh) && (j < k || (j < k-1 && i == k))) + { + std::cout << "++++ the values: j=" << j << ", k=" << k << std::endl; + return false; + } + curr_sibl = curr_sh->second.children(); std::cout << "++++ finished loop safely\n"; }//endif j!=i }//endfor @@ -354,6 +354,33 @@ private: } //endfor return true; } + */ + template + bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) + { + std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + std::vector< VertexHandle > facet; + //VertexHandle curr_vh = curr_sh->first; + // CHECK ALL THE FACETS + for (int i = 0; i != k+1; ++i) + { + if (knn[witness_id][i] != inserted_vertex) + { + facet = {}; + for (int j = 0; j != k+1; ++j) + { + if (j != i) + { + facet.push_back(knn[witness_id][j]); + } + }//endfor + if (find(facet) == null_simplex()) + return false; + std::cout << "++++ finished loop safely\n"; + }//endif + } //endfor + return true; + } /** * \brief Permutes the vector in such a way that the landmarks appear first -- cgit v1.2.3 From db7c80ba7f521ab63af8c2759a76ea1f0c27e525 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 26 Mar 2015 10:02:13 +0000 Subject: witness_complex_from_file finally compiles git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@507 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 86f8c736d4a5260a54e58ce2deb4045d27bd3524 --- src/Witness_complex/example/CMakeLists.txt | 4 +- .../include/gudhi/Witness_complex.h | 2 +- .../include/gudhi/Witness_complex1.h | 220 +++++++++------------ 3 files changed, 102 insertions(+), 124 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index d02522f8..74007c65 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -3,7 +3,9 @@ project(GUDHIWitnessComplex) add_executable ( simple_witness_complex simple_witness_complex.cpp ) add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) - + +add_executable( witness_complex_from_file witness_complex_from_file.cpp ) +add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 ) # An example with Simplex-tree using CGAL alpha_shapes_3 #if(GMP_FOUND AND CGAL_FOUND) diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index c6968e44..8bc04022 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -373,7 +373,7 @@ private: void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) { - //std::cout << "Enter furthestPoints "<< endl; + std::cout << "Enter furthestPoints "<< std::endl; //Point_Vector *L = new Point_Vector(); double density = 5.; int current_number_of_landmarks=0; diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index 5333e5a8..e1e81b0f 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -32,6 +32,7 @@ #include "gudhi/Simplex_tree.h" #include #include +#include #include #include @@ -184,97 +185,75 @@ void witness_complex(KNearestNeighbours & knn) print_sc(root()); std::cout << std::endl; int u,v; // two extremities of an edge if (nbL > 1) // if the supposed dimension of the complex is >0 - /* - // THE BUGGY CODE - for (int i=0; i != nbW; ++i) { + { + for (int i=0; i != nbW; ++i) + { // initial fill of active witnesses list u = knn[i][0]; v = knn[i][1]; //Siblings * curr_sib = &root_; //vh = (Vertex_handle)i; vv = {u,v}; - counter++; - returnValue = this->insert_simplex(vv,Filtration_value((double)counter)); - //std::cout << "Null simplex is " << null_simplex()->first << std::endl; - if (returnValue.first != null_simplex()) + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + print_sc(root()); std::cout << std::endl; + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if ( u > v) { - active_w.push_back(*(new Active_witness(i,v,returnValue.first))); + u = v; + v = knn[i][0]; + knn[i][0] = knn[i][1]; + knn[i][1] = v; } - for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) - std::cout << it1->simplex_handle->first << " "; - std::cout << std::endl; - //Simplex_handle sh = root_.members_.begin()+u; - //active_w.push_front(i); - } - */ - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - //Siblings * curr_sib = &root_; - //vh = (Vertex_handle)i; - vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; - } - //print_sc(root()); - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - if ( u > v) { - u = v; - v = knn[i][0]; - knn[i][0] = knn[i][1]; - knn[i][1] = v; + Simplex_handle sh; + vv = {u,v}; + sh = (root()->find(u))->second.children()->find(v); + active_w.push_back(i); } - Simplex_handle sh; - vv = {u,v}; - sh = (root()->find(u))->second.children()->find(v); - - active_w.push_back(i); - /*for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) - std::cout << it1->simplex->first << " "; - std::cout << std::endl; */ } - std::cout << "Successfully added edges" << std::endl; - while (!active_w.empty() && k+1 < nbL ) { - std::cout << "Started the step k=" << k << std::endl; + while (!active_w.empty() && k+1 < nbL ) + { + std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); - while (it != active_w.end()) { + while (it != active_w.end()) + { typeVectorVertex simplex_vector; /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ // First sort the first k landmarks - int i = k; - int temp_swap; VertexHandle inserted_vertex = knn[*it][k]; - while (i>0 && knn[*it][i-1] > knn[*it][i]) - { - temp_swap = knn[*it][i]; - knn[*it][i] = knn[*it][i-1]; - knn[*it][i-1] = temp_swap; - i--; - } bool ok = all_faces_in(knn, *it, k, inserted_vertex); if (ok) { - for (i = 0; i != k+1; ++i) - { - simplex_vector.push_back(knn[*it][i]); - } + for (int i = 0; i != k+1; ++i) + simplex_vector.push_back(knn[*it][i]); returnValue = insert_simplex(simplex_vector,0.0); it++; } else active_w.erase(it++); //First increase the iterator and then erase the previous element print_sc(root()); std::cout << std::endl; - } + } k++; } } + void witness_complex_from_file(std::string file_name, int nbL) + { + //READ THE FILE INTO A POINT VECTOR + std::vector< std::vector< double > > point_vector; + read_points(file_name, point_vector); + std::vector > WL; + furthestPoints(point_vector, point_vector.size(), nbL, WL); + witness_complex(WL); + } + private: void print_sc(Siblings * sibl) @@ -308,53 +287,6 @@ private: std::cout << ")"; } - - /** Check if all the facets of a simplex we are going to insert are in the simplex tree or not. - * The only purpose is to test if the witness is still active or not. - * Assuming here that the list of the first k witnessed landmarks is sorted - */ - - /* - template< typename KNearestNeighbours > - bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) - { - std::cout << "All face in with the landmark " << inserted_vertex << std::endl; - //std::list< VertexHandle > suffix; - Simplex_handle curr_sh = root()->find(knn[witness_id][0]); - Siblings * curr_sibl = root(); - //VertexHandle curr_vh = curr_sh->first; - // CHECK ALL THE FACETS - Simplex_handle sh_bup = curr_sh; // the first vertex lexicographicly - for (int i = 0; i != k+1; ++i) - { - curr_sh = sh_bup; - curr_sibl = root(); - if (knn[witness_id][i] != inserted_vertex) - { - for (int j = 0; j != k+1; ++j) - { - if (j != i) - { - std::cout << "+++ We are at vertex=" << knn[witness_id][j] << std::endl; - if (curr_sibl->find(knn[witness_id][j]) == null_simplex()) - return false; - std::cout << "++++ the simplex is there\n"; - curr_sh = curr_sibl->find(knn[witness_id][j]); - std::cout << "++++ curr_sh affectation is OK\n"; - if (!has_children(curr_sh) && (j < k || (j < k-1 && i == k))) - { - std::cout << "++++ the values: j=" << j << ", k=" << k << std::endl; - return false; - } - curr_sibl = curr_sh->second.children(); - std::cout << "++++ finished loop safely\n"; - }//endif j!=i - }//endfor - }//endif - } //endfor - return true; - } - */ template bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) { @@ -384,30 +316,73 @@ private: /** * \brief Permutes the vector in such a way that the landmarks appear first + * \arg W is the vector of points which will be the witnesses + * \arg nbP is the number of witnesses + * \arg nbL is the number of landmarks + * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) */ - void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) + template + void furthestPoints(Point_Vector &W, int nbP, int nbL, KNearestNeighbours &WL) + //void furthestPoints(Point_Vector &W, int nbP, int nbL, Point_Vector &L) { - //std::cout << "Enter furthestPoints "<< endl; - //Point_Vector *L = new Point_Vector(); - double density = 5.; + std::cout << "Enter furthestPoints "<< std::endl; + // What is density and why we need it. + // basically it is the stop indicator for "no more landmarks" + + //double density = 5.; + std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + std::vector< int > chosen_landmarks; // landmark list + WL = KNearestNeighbours(nbP,std::vector()); //nbP copies of empty vectors int current_number_of_landmarks=0; - double curr_max_dist; + double curr_max_dist = 0; double curr_dist; - double mindist = 10005.; + //double infty = std::numeric_limits::infinity(); + // double mindist = infty; int curr_max_w=0; - int curr_w=0; + int j; + int temp_swap_int; + double temp_swap_double; + + //CHOICE OF THE FIRST LANDMARK + std::cout << "Enter the first landmark stage\n"; srand(354698); int rand_int = rand()% nbP; - //std::cout << rand_int << endl; - L.push_back(W[rand_int]);// first landmark is random - current_number_of_landmarks++; + curr_max_w = rand_int; + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + chosen_landmarks.push_back(curr_max_w); // first landmark is random + for (auto v: WL) + v.push_back(current_number_of_landmarks); + for (unsigned int i = 0; i < wit_land_dist.size(); ++i) + { + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + wit_land_dist[i].push_back(curr_dist); + if (curr_dist > curr_max_dist) + { + curr_max_dist = curr_dist; + curr_max_w = i; + } + j = current_number_of_landmarks; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + } + } + } + /* while (1) { curr_w = 0; curr_max_dist = -1; for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { //compute distance from w and L - mindist = 100000.; + mindist = infty; for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { //curr_dist = distPoints(*itW,*itL); curr_dist = euclidean_distance(*itW,*itL); @@ -423,12 +398,13 @@ private: } L.push_back(W[curr_max_w]); current_number_of_landmarks++; - density = sqrt(curr_max_dist); + //density = sqrt(curr_max_dist); //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; if(L.size() == nbL) break; } + */ //std::cout << endl; - return L; + //return L; } }; //class Witness_complex -- cgit v1.2.3 From 9c81b9f5e5308091e9f10d5df4bfc6fd8f303b12 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 26 Mar 2015 12:59:39 +0000 Subject: witness_complex_from_file works on small examples + corrected a small bug in witness_complex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@508 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3294e22959ca0c5f43a843e851870edfce0999ad --- .../include/gudhi/Witness_complex1.h | 82 +++++++++++++++++----- 1 file changed, 65 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index e1e81b0f..c9d421c4 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -180,9 +180,9 @@ void witness_complex(KNearestNeighbours & knn) } //vv = {0}; //returnValue = insert_simplex(vv,Filtration_value(0.0)); - std::cout << "Successfully added landmarks" << std::endl; + //std::cout << "Successfully added landmarks" << std::endl; // PRINT2 - print_sc(root()); std::cout << std::endl; + //print_sc(root()); std::cout << std::endl; int u,v; // two extremities of an edge if (nbL > 1) // if the supposed dimension of the complex is >0 { @@ -195,7 +195,7 @@ void witness_complex(KNearestNeighbours & knn) //vh = (Vertex_handle)i; vv = {u,v}; returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - print_sc(root()); std::cout << std::endl; + //print_sc(root()); std::cout << std::endl; //std::cout << "Added edges" << std::endl; } //print_sc(root()); @@ -217,10 +217,10 @@ void witness_complex(KNearestNeighbours & knn) active_w.push_back(i); } } - std::cout << "Successfully added edges" << std::endl; - while (!active_w.empty() && k+1 < nbL ) + //std::cout << "Successfully added edges" << std::endl; + while (!active_w.empty() && k < nbL ) { - std::cout << "Started the step k=" << k << std::endl; + //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { @@ -238,17 +238,17 @@ void witness_complex(KNearestNeighbours & knn) } else active_w.erase(it++); //First increase the iterator and then erase the previous element - print_sc(root()); std::cout << std::endl; } k++; - } + } + print_sc(root()); std::cout << std::endl; } - void witness_complex_from_file(std::string file_name, int nbL) + void witness_complex_from_file(Point_Vector point_vector, int nbL) { //READ THE FILE INTO A POINT VECTOR - std::vector< std::vector< double > > point_vector; - read_points(file_name, point_vector); + //std::vector< std::vector< double > > point_vector; + //read_points(file_name, point_vector); std::vector > WL; furthestPoints(point_vector, point_vector.size(), nbL, WL); witness_complex(WL); @@ -290,7 +290,7 @@ private: template bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) { - std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; std::vector< VertexHandle > facet; //VertexHandle curr_vh = curr_sh->first; // CHECK ALL THE FACETS @@ -314,6 +314,38 @@ private: return true; } + template + void print_vector(std::vector v) + { + std::cout << "["; + if (!v.empty()) + { + std::cout << *(v.begin()); + for (auto it = v.begin()+1; it != v.end(); ++it) + { + std::cout << ","; + std::cout << *it; + } + } + std::cout << "]"; + } + + template + void print_vvector(std::vector< std::vector > vv) + { + std::cout << "["; + if (!vv.empty()) + { + print_vector(*(vv.begin())); + for (auto it = vv.begin()+1; it != vv.end(); ++it) + { + std::cout << ","; + print_vector(*it); + } + } + std::cout << "]\n"; + } + /** * \brief Permutes the vector in such a way that the landmarks appear first * \arg W is the vector of points which will be the witnesses @@ -329,7 +361,7 @@ private: std::cout << "Enter furthestPoints "<< std::endl; // What is density and why we need it. // basically it is the stop indicator for "no more landmarks" - + //std::cout << "W="; print_vvector(W); //double density = 5.; std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks std::vector< int > chosen_landmarks; // landmark list @@ -345,26 +377,41 @@ private: double temp_swap_double; //CHOICE OF THE FIRST LANDMARK - std::cout << "Enter the first landmark stage\n"; + //std::cout << "Enter the first landmark stage\n"; srand(354698); int rand_int = rand()% nbP; curr_max_w = rand_int; for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) { - chosen_landmarks.push_back(curr_max_w); // first landmark is random + chosen_landmarks.push_back(curr_max_w); + //std::cout << "Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; for (auto v: WL) v.push_back(current_number_of_landmarks); - for (unsigned int i = 0; i < wit_land_dist.size(); ++i) + for (int i = 0; i < nbP; ++i) { - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + if (i != chosen_landmarks[current_number_of_landmarks]) + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + else + curr_dist = 0; + //std::cout << "The problem is not in distance function\n"; wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; if (curr_dist > curr_max_dist) { curr_max_dist = curr_dist; curr_max_w = i; } j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) { temp_swap_int = WL[i][j]; @@ -374,6 +421,7 @@ private: wit_land_dist[i][j] = wit_land_dist[i][j-1]; wit_land_dist[i][j-1] = temp_swap_double; } + //std::cout << "End loop\n"; } } /* -- cgit v1.2.3 From c41277f640fa6d59af11970e7c281ff9d5221d06 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 26 Mar 2015 13:43:55 +0000 Subject: fixed bug in landmark sorting + fixed bug in landmark choice git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@509 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 862c72f48dd6fe24e4e6c02a9cda5d99645c3f71 --- .../include/gudhi/Witness_complex1.h | 29 ++++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h index c9d421c4..f75c3e66 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ b/src/Witness_complex/include/gudhi/Witness_complex1.h @@ -308,7 +308,7 @@ private: }//endfor if (find(facet) == null_simplex()) return false; - std::cout << "++++ finished loop safely\n"; + //std::cout << "++++ finished loop safely\n"; }//endif } //endfor return true; @@ -365,11 +365,13 @@ private: //double density = 5.; std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks std::vector< int > chosen_landmarks; // landmark list + WL = KNearestNeighbours(nbP,std::vector()); //nbP copies of empty vectors int current_number_of_landmarks=0; double curr_max_dist = 0; double curr_dist; - //double infty = std::numeric_limits::infinity(); + double infty = std::numeric_limits::infinity(); + std::vector< double > dist_to_L(nbP,infty); // double mindist = infty; int curr_max_w=0; int j; @@ -385,15 +387,16 @@ private: for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) { chosen_landmarks.push_back(curr_max_w); - //std::cout << "Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + curr_max_dist = 0; + std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + std::cout << "WL="; print_vvector(WL); + std::cout << "WLD="; print_vvector(wit_land_dist); + std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; for (auto v: WL) v.push_back(current_number_of_landmarks); for (int i = 0; i < nbP; ++i) { - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; if (i != chosen_landmarks[current_number_of_landmarks]) curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); @@ -403,15 +406,15 @@ private: wit_land_dist[i].push_back(curr_dist); WL[i].push_back(current_number_of_landmarks); //std::cout << "Push't back\n"; - if (curr_dist > curr_max_dist) + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + if (dist_to_L[i] > curr_max_dist) { curr_max_dist = curr_dist; curr_max_w = i; } j = current_number_of_landmarks; //std::cout << "First half complete\n"; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) { temp_swap_int = WL[i][j]; @@ -420,8 +423,12 @@ private: temp_swap_double = wit_land_dist[i][j]; wit_land_dist[i][j] = wit_land_dist[i][j-1]; wit_land_dist[i][j-1] = temp_swap_double; + --j; } - //std::cout << "End loop\n"; + std::cout << "result WL="; print_vvector(WL); + std::cout << "result WLD="; print_vvector(wit_land_dist); + + std::cout << "End loop\n"; } } /* -- cgit v1.2.3 From 4b8b6dce9c433b8a0081d3310a123ee2abda76c8 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 27 Mar 2015 13:09:02 +0000 Subject: Added witness_complex_from_file git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@510 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 22b61b82bae5fa75545c1eff22619426d5b8b469 --- .../example/witness_complex_from_file.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/Witness_complex/example/witness_complex_from_file.cpp (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp new file mode 100644 index 00000000..a0e192f7 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -0,0 +1,89 @@ +/* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex1.h" + + +using namespace Gudhi; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::vector< std::vector > Point_Vector; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + if (point.size() != 1) + points.push_back(point); + } + in_file.close(); +} + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + + clock_t start, end; + //Construct the Simplex Tree + Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + start = clock(); + Point_Vector point_vector; + read_points_cust(file_name, point_vector); + witnessComplex.witness_complex_from_file(point_vector, nbL); + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + +} -- cgit v1.2.3 From dfc3485f4a497c8dca7b160f5eb76a17c3556045 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 31 Mar 2015 09:29:45 +0000 Subject: Added a bit more of comments git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@518 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b00e0c8a2a48efd443c943d3b76a12c5581e79bc --- .../include/gudhi/Witness_complex.h | 631 ++++++++++----------- 1 file changed, 295 insertions(+), 336 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 8bc04022..57b89af8 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -32,388 +32,347 @@ #include "gudhi/Simplex_tree.h" #include #include +#include #include #include namespace Gudhi { - /* -template -class Simplex_tree; - */ - /* - typedef int Witness_id; -typedef int Landmark_id; -typedef int Simplex_handle; //index in vector complex_ - */ + /** \addtogroup simplex_tree + * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: + * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ + * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that + * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. + */ + template + class Witness_complex: public Simplex_tree<> { -template -class Witness_complex: public Simplex_tree<> { - //class Witness_complex: public Simplex_tree { - //class Witness_complex { -private: - - /* - template < typename Witness_id = int, - typename Landmark_id = int, - typename Simplex_handle = Simplex_handle > - struct Active_witness { - Witness_id witness_id; - Landmark_id landmark_id; - Simplex_handle simplex_handle; - }; - */ + private: + + struct Active_witness { + int witness_id; + int landmark_id; + Simplex_handle simplex_handle; -struct Active_witness { - int witness_id; - int landmark_id; - Simplex_handle simplex_handle; - - Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) - : witness_id(witness_id_), - landmark_id(landmark_id_), - simplex_handle(simplex_handle_) - {} -}; + Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + : witness_id(witness_id_), + landmark_id(landmark_id_), + simplex_handle(simplex_handle_) + {} + }; -public: - -//Simplex_tree<> st; - -// typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; -// typedef boost::iterator_range Boundary_simplex_range; - -// typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator; -// typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range; - -// typedef IndexingTag Indexing_tag; - /** \brief Type for the value of the filtration function. - * - * Must be comparable with <. */ -// typedef FiltrationValue Filtration_value; - /** \brief Key associated to each simplex. - * - * Must be a signed integer type. */ -// typedef SimplexKey Simplex_key; - - /** \brief Type for the vertex handle. - * - * Must be a signed integer type. It admits a total order <. */ - typedef VertexHandle Vertex_handle; - - /* Type of node in the simplex tree. */ - typedef Simplex_tree_node_explicit_storage Node; - /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ - typedef typename boost::container::flat_map Dictionary; - typedef typename Dictionary::iterator Simplex_handle; + public: -/* - friend class Simplex_tree_node_explicit_storage< Simplex_tree >; - friend class Simplex_tree_siblings< Simplex_tree, Dictionary>; - friend class Simplex_tree_simplex_vertex_iterator< Simplex_tree >; - friend class Simplex_tree_boundary_simplex_iterator< Simplex_tree >; - friend class Simplex_tree_complex_simplex_iterator< Simplex_tree >; - friend class Simplex_tree_skeleton_simplex_iterator< Simplex_tree >; -*/ - - /* \brief Set of nodes sharing a same parent in the simplex tree. */ - /* \brief Set of nodes sharing a same parent in the simplex tree. */ -// typedef Simplex_tree_siblings Siblings; - - - typedef std::vector< double > Point_t; - typedef std::vector< Point_t > Point_Vector; - - typedef std::vector< Vertex_handle > typeVectorVertex; - typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; - typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - - typedef int Witness_id; - typedef int Landmark_id; - typedef std::list< Active_witness > ActiveWitnessList; - -/** - * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. - * Landmarks are supposed to be in [0,nbL-1] - */ - + + /** \brief Type for the vertex handle. + * + * Must be a signed integer type. It admits a total order <. */ + typedef VertexHandle Vertex_handle; + + /* Type of node in the simplex tree. */ + typedef Simplex_tree_node_explicit_storage Node; + /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ + typedef typename boost::container::flat_map Dictionary; + typedef typename Dictionary::iterator Simplex_handle; -template< typename KNearestNeighbours > -void witness_complex(KNearestNeighbours & knn) -//void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) -{ - std::cout << "**Start the procedure witness_complex" << std::endl; - int k=2; /* current dimension in iterative construction */ - //Construction of the active witness list - int nbW = knn.size(); - int nbL = knn.at(0).size(); - //VertexHandle vh; - typeVectorVertex vv; - typeSimplex simplex; - typePairSimplexBool returnValue; - int counter = 0; - /* The list of still useful witnesses - * it will diminuish in the course of iterations + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + + typedef std::vector< Vertex_handle > typeVectorVertex; + typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; + typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + typedef int Witness_id; + typedef int Landmark_id; + typedef std::list< Vertex_handle > ActiveWitnessList; + + /** + * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. + * Landmarks are supposed to be in [0,nbL-1] */ - ActiveWitnessList active_w;// = new ActiveWitnessList(); - for (int i=0; i != nbL; ++i) { + + template< typename KNearestNeighbours > + void witness_complex(KNearestNeighbours & knn) + //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) + { + std::cout << "**Start the procedure witness_complex" << std::endl; + int k=2; /* current dimension in iterative construction */ + //Construction of the active witness list + int nbW = knn.size(); + int nbL = knn.at(0).size(); + //VertexHandle vh; + typeVectorVertex vv; + typeSimplex simplex; + typePairSimplexBool returnValue; + int counter = 0; + /* The list of still useful witnesses + * it will diminuish in the course of iterations + */ + ActiveWitnessList active_w;// = new ActiveWitnessList(); + for (int i=0; i != nbL; ++i) { // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore - //vh = (Vertex_handle)i; - counter++; + counter++; vv = {i}; /* TODO Filtration */ - //simplex = std::make_pair(vv, Filtration_value(0.0)); - //returnValue = this->insert_simplex(simplex.first, simplex.second); returnValue = insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ - } - //vv = {0}; - //returnValue = insert_simplex(vv,Filtration_value(0.0)); - std::cout << "Successfully added landmarks" << std::endl; - // PRINT2 - print_sc(root()); std::cout << std::endl; - int u,v; // two extremities of an edge - if (nbL > 1) // if the supposed dimension of the complex is >0 - /* - // THE BUGGY CODE - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - //Siblings * curr_sib = &root_; - //vh = (Vertex_handle)i; - vv = {u,v}; - counter++; - returnValue = this->insert_simplex(vv,Filtration_value((double)counter)); - //std::cout << "Null simplex is " << null_simplex()->first << std::endl; - if (returnValue.first != null_simplex()) - { - active_w.push_back(*(new Active_witness(i,v,returnValue.first))); - } - for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) - std::cout << it1->simplex_handle->first << " "; - std::cout << std::endl; - //Simplex_handle sh = root_.members_.begin()+u; - //active_w.push_front(i); - } - */ - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - //Siblings * curr_sib = &root_; - //vh = (Vertex_handle)i; - vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; } - //print_sc(root()); - for (int i=0; i != nbW; ++i) { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - if ( u > v) { - u = v; - v = knn[i][0]; + //std::cout << "Successfully added landmarks" << std::endl; + // PRINT2 + //print_sc(root()); std::cout << std::endl; + int u,v; // two extremities of an edge + if (nbL > 1) // if the supposed dimension of the complex is >0 + { + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + vv = {u,v}; + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + //print_sc(root()); std::cout << std::endl; + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if ( u > v) + { + u = v; + v = knn[i][0]; + knn[i][0] = knn[i][1]; + knn[i][1] = v; + } + Simplex_handle sh; + vv = {u,v}; + sh = (root()->find(u))->second.children()->find(v); + active_w.push_back(i); + } } - Simplex_handle sh; - vv = {u,v}; - sh = (root()->find(u))->second.children()->find(v); - - active_w.push_back(Active_witness(i,v,sh)); - /*for (typename ActiveWitnessList::iterator it1 = active_w.begin(); it1 != active_w.end(); ++it1) - std::cout << it1->simplex->first << " "; - std::cout << std::endl; */ - } - - std::cout << "Successfully added edges" << std::endl; - while (!active_w.empty() && k+1 < nbL ) { - std::cout << "Started the step k=" << k << std::endl; - typename ActiveWitnessList::iterator it = active_w.begin(); - while (it != active_w.end()) { - typeVectorVertex simplex_vector; - typeVectorVertex suffix; - /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ - // std::cout << it->simplex->first << std::endl; - bool ok = all_faces_in(knn[it->witness_id][k],it->simplex_handle); - if (ok) - returnValue = insert_simplex(simplex_vector,0.0); - else - active_w.erase(it); //First increase the iterator and then erase the previous element - it++; + //std::cout << "Successfully added edges" << std::endl; + while (!active_w.empty() && k < nbL ) + { + //std::cout << "Started the step k=" << k << std::endl; + typename ActiveWitnessList::iterator it = active_w.begin(); + while (it != active_w.end()) + { + typeVectorVertex simplex_vector; + /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ + // First sort the first k landmarks + VertexHandle inserted_vertex = knn[*it][k]; + bool ok = all_faces_in(knn, *it, k, inserted_vertex); + if (ok) + { + for (int i = 0; i != k+1; ++i) + simplex_vector.push_back(knn[*it][i]); + returnValue = insert_simplex(simplex_vector,0.0); + it++; + } + else + active_w.erase(it++); //First increase the iterator and then erase the previous element + } + k++; } - k++; - } -} - -private: - - void print_sc(Siblings * sibl) - { - if (sibl == NULL) - std::cout << "&"; - else - print_children(sibl->members_); - } + //print_sc(root()); std::cout << std::endl; + } - void print_children(Dictionary map) + /** \brief Construction of witness complex from points given explicitly + */ + void witness_complex_from_file(Point_Vector point_vector, int nbL) { - std::cout << "("; - if (!map.empty()) - { - std::cout << map.begin()->first; - if (has_children(map.begin())) - print_sc(map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - std::cout << "," << it->first; - if (has_children(it)) - print_sc(it->second.children()); - } - } - std::cout << ")"; + std::vector > WL; + furthestPoints(point_vector, point_vector.size(), nbL, WL); + witness_complex(WL); } + +private: - - /** Check if all the facets of a simplex we are going to insert are in the simplex tree or not. - * The only purpose is to test if the witness is still active or not. - */ - bool all_faces_in(VertexHandle last, Simplex_handle sh) - { - std::cout << "All face in with the landmark " << last << std::endl; - std::list< VertexHandle > suffix; - Simplex_handle curr_sh = sh; - Siblings * curr_sibl = self_siblings(sh); - VertexHandle curr_vh = curr_sh->first; - while (curr_vh > last) { - std::cout << "We are at " << curr_sh->first << " " << sh->first << "\n"; - suffix.push_front(curr_vh); - //std::cout << "Still fine 1\n"; - curr_vh = curr_sibl->parent(); - //std::cout << "Still fine 2\n"; - curr_sibl = curr_sibl->oncles(); - //std::cout << "Still fine 3\n"; - curr_sh = curr_sibl->find(curr_vh); - //std::cout << "Still fine 4\n"; + /** \brief Print functions + */ + void print_sc(Siblings * sibl) + { + if (sibl == NULL) + std::cout << "&"; + else + print_children(sibl->members_); } - std::cout << "Arrived at the mid-parent" << std::endl; - suffix.push_front(last); - typename std::list< VertexHandle >::iterator itVV = suffix.begin(); - Simplex_handle sh_bup = curr_sh; // Back up the pointer - while (itVV != suffix.end() && curr_sh->second.children()->find(*itVV) != null_simplex()) { - // If the node doesn't exist then stop, else go down the tree - std::cout << "DOWN!" << curr_sh->first << " -> " << *itVV << std::endl; - std::cout << "Children of " << curr_sh->first << " are "; - for (typename Dictionary::iterator itt = curr_sh->second.children()->members_.begin(); itt != curr_sh->second.children()->members_.end(); ++itt) - std::cout << itt->first << ","; - std::cout << std::endl; - curr_sh = curr_sh->second.children()->find(*itVV); - itVV++; + + void print_children(Dictionary map) + { + std::cout << "("; + if (!map.empty()) + { + std::cout << map.begin()->first; + if (has_children(map.begin())) + print_sc(map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + std::cout << "," << it->first; + if (has_children(it)) + print_sc(it->second.children()); + } + } + std::cout << ")"; } - if (itVV == suffix.end()) { - // the simplex is already in the tree - std::cout << "The simplex is there" << std::endl; + + template + bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) + { + //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + std::vector< VertexHandle > facet; + //VertexHandle curr_vh = curr_sh->first; + // CHECK ALL THE FACETS + for (int i = 0; i != k+1; ++i) + { + if (knn[witness_id][i] != inserted_vertex) + { + facet = {}; + for (int j = 0; j != k+1; ++j) + { + if (j != i) + { + facet.push_back(knn[witness_id][j]); + } + }//endfor + if (find(facet) == null_simplex()) + return false; + //std::cout << "++++ finished loop safely\n"; + }//endif + } //endfor return true; } - else if (itVV != suffix.end()) { - // the father of the simplex is not in the tree - std::cout << "The father is not there. Deleting witness." << std::endl; - return false; - } - else { - // CHECK ALL THE FACETS - curr_sh = sh_bup; - while (curr_sibl != root()) { - suffix.push_front(curr_vh); - curr_vh = curr_sibl->parent(); - curr_sibl = curr_sibl->oncles(); - curr_sh = curr_sibl->find(curr_vh); + + template + void print_vector(std::vector v) + { + std::cout << "["; + if (!v.empty()) + { + std::cout << *(v.begin()); + for (auto it = v.begin()+1; it != v.end(); ++it) + { + std::cout << ","; + std::cout << *it; + } } - suffix.push_front(curr_vh); - sh_bup = curr_sh; // the first vertex lexicographicly - for (typename std::list< VertexHandle >::iterator itExcl = suffix.begin(); itExcl != suffix.end(); ++itExcl) { - if (*itExcl != last) { - itVV = suffix.begin(); - while (itVV != itExcl) { - if (curr_sibl->find(*itVV) == null_simplex()) - return false; - curr_sh = curr_sibl->find(*itVV); - curr_sibl = self_siblings(curr_sh); - itVV++; - } - itVV++; - while (itVV != suffix.end()) { - if (curr_sibl->find(*itVV) == null_simplex()) - return false; - curr_sh = curr_sibl->find(*itVV); - curr_sibl = self_siblings(curr_sh); - itVV++; - } //endwhile - } //endif - } //endfor - return true; - } //end check all the facets - } - + std::cout << "]"; + } + + template + void print_vvector(std::vector< std::vector > vv) + { + std::cout << "["; + if (!vv.empty()) + { + print_vector(*(vv.begin())); + for (auto it = vv.begin()+1; it != vv.end(); ++it) + { + std::cout << ","; + print_vector(*it); + } + } + std::cout << "]\n"; + } + /** - * \brief Permutes the vector in such a way that the landmarks appear first + * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the + * current landmark set + * \arg W is the vector of points which will be the witnesses + * \arg nbP is the number of witnesses + * \arg nbL is the number of landmarks + * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) */ - void furthestPoints(Point_Vector &W, int nbP, std::string file_land, int dim, int nbL, Point_Vector &L) + template + void furthestPoints(Point_Vector &W, int nbP, int nbL, KNearestNeighbours &WL) + //void furthestPoints(Point_Vector &W, int nbP, int nbL, Point_Vector &L) { - std::cout << "Enter furthestPoints "<< std::endl; - //Point_Vector *L = new Point_Vector(); - double density = 5.; + //std::cout << "Enter furthestPoints "<< std::endl; + // What is density and why we need it. + // basically it is the stop indicator for "no more landmarks" + //std::cout << "W="; print_vvector(W); + //double density = 5.; + std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + std::vector< int > chosen_landmarks; // landmark list + + WL = KNearestNeighbours(nbP,std::vector()); //nbP copies of empty vectors int current_number_of_landmarks=0; - double curr_max_dist; + double curr_max_dist = 0; double curr_dist; - double mindist = 10005.; + double infty = std::numeric_limits::infinity(); + std::vector< double > dist_to_L(nbP,infty); + // double mindist = infty; int curr_max_w=0; - int curr_w=0; + int j; + int temp_swap_int; + double temp_swap_double; + + //CHOICE OF THE FIRST LANDMARK + //std::cout << "Enter the first landmark stage\n"; srand(354698); int rand_int = rand()% nbP; - //std::cout << rand_int << endl; - L.push_back(W[rand_int]);// first landmark is random - current_number_of_landmarks++; - while (1) { - curr_w = 0; - curr_max_dist = -1; - for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { - //compute distance from w and L - mindist = 100000.; - for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { - //curr_dist = distPoints(*itW,*itL); - curr_dist = euclidean_distance(*itW,*itL); - if(curr_dist < mindist) { - mindist = curr_dist; + curr_max_w = rand_int; + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + chosen_landmarks.push_back(curr_max_w); + curr_max_dist = 0; + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + for (auto v: WL) + v.push_back(current_number_of_landmarks); + for (int i = 0; i < nbP; ++i) + { + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + if (i != chosen_landmarks[current_number_of_landmarks]) + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + else + curr_dist = 0; + //std::cout << "The problem is not in distance function\n"; + wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + if (dist_to_L[i] > curr_max_dist) + { + curr_max_dist = curr_dist; + curr_max_w = i; + } + j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + } + //std::cout << "result WL="; print_vvector(WL); + //std::cout << "result WLD="; print_vvector(wit_land_dist); + //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; + //std::cout << "End loop\n"; } - } - if(mindist > curr_max_dist) { - curr_max_w = curr_w; //??? - curr_max_dist = mindist; - } - curr_w++; } - L.push_back(W[curr_max_w]); - current_number_of_landmarks++; - density = sqrt(curr_max_dist); - //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; - if(L.size() == nbL) break; - } //std::cout << endl; - return L; } }; //class Witness_complex -- cgit v1.2.3 From 7f864c8d1b8c019d4f239bc343e7a14e5853bf0d Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 31 Mar 2015 12:58:48 +0000 Subject: Wrote code for random landmark choice strategy git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@520 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 079b9ec46dcdd93416315ec101cd4e53b444154f --- .../include/gudhi/Witness_complex.h | 163 +++++-- .../include/gudhi/Witness_complex1.h | 470 --------------------- 2 files changed, 133 insertions(+), 500 deletions(-) delete mode 100644 src/Witness_complex/include/gudhi/Witness_complex1.h (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 57b89af8..d5a35801 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -32,9 +32,10 @@ #include "gudhi/Simplex_tree.h" #include #include +#include #include #include - +#include #include namespace Gudhi { @@ -92,6 +93,30 @@ namespace Gudhi { typedef int Witness_id; typedef int Landmark_id; typedef std::list< Vertex_handle > ActiveWitnessList; + + private: + /** Number of landmarks + */ + int nbL; + /** Desired density + */ + double density; + + public: + + /** \brief Set number of landmarks to nbL_ + */ + void setNbL(int nbL_) + { + nbL = nbL_; + } + + /** \brief Set density to density_ + */ + void setDensity(double density_) + { + density = density_; + } /** * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. @@ -106,8 +131,7 @@ namespace Gudhi { int k=2; /* current dimension in iterative construction */ //Construction of the active witness list int nbW = knn.size(); - int nbL = knn.at(0).size(); - //VertexHandle vh; + //int nbL = knn.at(0).size(); typeVectorVertex vv; typeSimplex simplex; typePairSimplexBool returnValue; @@ -184,15 +208,18 @@ namespace Gudhi { } k++; } - //print_sc(root()); std::cout << std::endl; + print_sc(root()); std::cout << std::endl; } /** \brief Construction of witness complex from points given explicitly + * nbL must be set to the right value of landmarks for strategies + * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and + * density must be set to the right value for DENSITY_STRATEGY */ - void witness_complex_from_file(Point_Vector point_vector, int nbL) + void witness_complex_from_points(Point_Vector point_vector) { std::vector > WL; - furthestPoints(point_vector, point_vector.size(), nbL, WL); + landmark_choice_by_random_points(point_vector, point_vector.size(), WL); witness_complex(WL); } @@ -226,7 +253,11 @@ private: } std::cout << ")"; } - + + /** \brief Check if the facets of the k-dimensional simplex witnessed + * by witness witness_id are already in the complex. + * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id + */ template bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) { @@ -296,53 +327,50 @@ private: */ template - void furthestPoints(Point_Vector &W, int nbP, int nbL, KNearestNeighbours &WL) - //void furthestPoints(Point_Vector &W, int nbP, int nbL, Point_Vector &L) + void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) { - //std::cout << "Enter furthestPoints "<< std::endl; - // What is density and why we need it. - // basically it is the stop indicator for "no more landmarks" + //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; //std::cout << "W="; print_vvector(W); //double density = 5.; - std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - std::vector< int > chosen_landmarks; // landmark list + Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + typeVectorVertex chosen_landmarks; // landmark list - WL = KNearestNeighbours(nbP,std::vector()); //nbP copies of empty vectors - int current_number_of_landmarks=0; - double curr_max_dist = 0; - double curr_dist; - double infty = std::numeric_limits::infinity(); - std::vector< double > dist_to_L(nbP,infty); + WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + double curr_max_dist = 0; // used for defining the furhest point from L + double curr_dist; // used to stock the distance from the current point to L + double infty = std::numeric_limits::infinity(); // infinity (see next entry) + std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points // double mindist = infty; - int curr_max_w=0; + int curr_max_w=0; // the point currently furthest from L int j; - int temp_swap_int; + int temp_swap_int; double temp_swap_double; //CHOICE OF THE FIRST LANDMARK - //std::cout << "Enter the first landmark stage\n"; + std::cout << "Enter the first landmark stage\n"; srand(354698); int rand_int = rand()% nbP; - curr_max_w = rand_int; + curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) { + //curr_max_w at this point is the next landmark chosen_landmarks.push_back(curr_max_w); curr_max_dist = 0; //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; //std::cout << "WL="; print_vvector(WL); //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; for (auto v: WL) v.push_back(current_number_of_landmarks); for (int i = 0; i < nbP; ++i) { + // iteration on points in W. update of distance vectors + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - if (i != chosen_landmarks[current_number_of_landmarks]) - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - else - curr_dist = 0; + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); //std::cout << "The problem is not in distance function\n"; wit_land_dist[i].push_back(curr_dist); WL[i].push_back(current_number_of_landmarks); @@ -358,6 +386,7 @@ private: //std::cout << "First half complete\n"; while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) { + // sort the closest landmark vector for every witness temp_swap_int = WL[i][j]; WL[i][j] = WL[i][j-1]; WL[i][j-1] = temp_swap_int; @@ -374,9 +403,83 @@ private: } //std::cout << endl; } - + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * + */ + + template + void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + { + //std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + //std::cout << "W="; print_vvector(W); + std::unordered_set< int > chosen_landmarks; // landmark set + + Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + + WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + + srand(24660); + int chosen_landmark = rand()%nbP; + double curr_dist; + + int j; + int temp_swap_int; + double temp_swap_double; + + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) + { + srand((int)clock()); + chosen_landmark = rand()% nbP; + //std::cout << chosen_landmark << "\n"; + } + chosen_landmarks.insert(chosen_landmark); + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + for (auto v: WL) + v.push_back(current_number_of_landmarks); + for (int i = 0; i < nbP; ++i) + { + // iteration on points in W. update of distance vectors + + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + //std::cout << "The problem is not in distance function\n"; + wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; + j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + // sort the closest landmark vector for every witness + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + } + //std::cout << "result WL="; print_vvector(WL); + //std::cout << "result WLD="; print_vvector(wit_land_dist); + //std::cout << "End loop\n"; + } + } + //std::cout << endl; + } + + }; //class Witness_complex + } // namespace Guhdi diff --git a/src/Witness_complex/include/gudhi/Witness_complex1.h b/src/Witness_complex/include/gudhi/Witness_complex1.h deleted file mode 100644 index f75c3e66..00000000 --- a/src/Witness_complex/include/gudhi/Witness_complex1.h +++ /dev/null @@ -1,470 +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): Siargey Kachanovich - * - * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef GUDHI_WITNESS_COMPLEX_H_ -#define GUDHI_WITNESS_COMPLEX_H_ - -#include -#include -#include -#include -#include "gudhi/reader_utils.h" -#include "gudhi/distance_functions.h" -#include "gudhi/Simplex_tree.h" -#include -#include -#include -#include - -#include - -namespace Gudhi { - - /* -template -class Simplex_tree; - */ - - /* - typedef int Witness_id; -typedef int Landmark_id; -typedef int Simplex_handle; //index in vector complex_ - */ - -template -class Witness_complex: public Simplex_tree<> { - //class Witness_complex: public Simplex_tree { - //class Witness_complex { -private: - - /* - template < typename Witness_id = int, - typename Landmark_id = int, - typename Simplex_handle = Simplex_handle > - struct Active_witness { - Witness_id witness_id; - Landmark_id landmark_id; - Simplex_handle simplex_handle; - }; - */ - -struct Active_witness { - int witness_id; - int landmark_id; - Simplex_handle simplex_handle; - - Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) - : witness_id(witness_id_), - landmark_id(landmark_id_), - simplex_handle(simplex_handle_) - {} -}; - - - - -public: - -//Simplex_tree<> st; - -// typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; -// typedef boost::iterator_range Boundary_simplex_range; - -// typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator; -// typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range; - -// typedef IndexingTag Indexing_tag; - /** \brief Type for the value of the filtration function. - * - * Must be comparable with <. */ -// typedef FiltrationValue Filtration_value; - /** \brief Key associated to each simplex. - * - * Must be a signed integer type. */ -// typedef SimplexKey Simplex_key; - - /** \brief Type for the vertex handle. - * - * Must be a signed integer type. It admits a total order <. */ - typedef VertexHandle Vertex_handle; - - /* Type of node in the simplex tree. */ - typedef Simplex_tree_node_explicit_storage Node; - /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ - typedef typename boost::container::flat_map Dictionary; - typedef typename Dictionary::iterator Simplex_handle; - -/* - friend class Simplex_tree_node_explicit_storage< Simplex_tree >; - friend class Simplex_tree_siblings< Simplex_tree, Dictionary>; - friend class Simplex_tree_simplex_vertex_iterator< Simplex_tree >; - friend class Simplex_tree_boundary_simplex_iterator< Simplex_tree >; - friend class Simplex_tree_complex_simplex_iterator< Simplex_tree >; - friend class Simplex_tree_skeleton_simplex_iterator< Simplex_tree >; -*/ - - /* \brief Set of nodes sharing a same parent in the simplex tree. */ - /* \brief Set of nodes sharing a same parent in the simplex tree. */ -// typedef Simplex_tree_siblings Siblings; - - - typedef std::vector< double > Point_t; - typedef std::vector< Point_t > Point_Vector; - - typedef std::vector< Vertex_handle > typeVectorVertex; - typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; - typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - - typedef int Witness_id; - typedef int Landmark_id; - typedef std::list< Vertex_handle > ActiveWitnessList; - -/** - * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. - * Landmarks are supposed to be in [0,nbL-1] - */ - - -template< typename KNearestNeighbours > -void witness_complex(KNearestNeighbours & knn) -//void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) -{ - std::cout << "**Start the procedure witness_complex" << std::endl; - int k=2; /* current dimension in iterative construction */ - //Construction of the active witness list - int nbW = knn.size(); - int nbL = knn.at(0).size(); - //VertexHandle vh; - typeVectorVertex vv; - typeSimplex simplex; - typePairSimplexBool returnValue; - int counter = 0; - /* The list of still useful witnesses - * it will diminuish in the course of iterations - */ - ActiveWitnessList active_w;// = new ActiveWitnessList(); - for (int i=0; i != nbL; ++i) { - // initial fill of 0-dimensional simplices - // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore - //vh = (Vertex_handle)i; - counter++; - vv = {i}; - /* TODO Filtration */ - //simplex = std::make_pair(vv, Filtration_value(0.0)); - //returnValue = this->insert_simplex(simplex.first, simplex.second); - returnValue = insert_simplex(vv, Filtration_value(0.0)); - /* TODO Error if not inserted : normally no need here though*/ - } - //vv = {0}; - //returnValue = insert_simplex(vv,Filtration_value(0.0)); - //std::cout << "Successfully added landmarks" << std::endl; - // PRINT2 - //print_sc(root()); std::cout << std::endl; - int u,v; // two extremities of an edge - if (nbL > 1) // if the supposed dimension of the complex is >0 - { - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - //Siblings * curr_sib = &root_; - //vh = (Vertex_handle)i; - vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - //print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; - } - //print_sc(root()); - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - if ( u > v) - { - u = v; - v = knn[i][0]; - knn[i][0] = knn[i][1]; - knn[i][1] = v; - } - Simplex_handle sh; - vv = {u,v}; - sh = (root()->find(u))->second.children()->find(v); - active_w.push_back(i); - } - } - //std::cout << "Successfully added edges" << std::endl; - while (!active_w.empty() && k < nbL ) - { - //std::cout << "Started the step k=" << k << std::endl; - typename ActiveWitnessList::iterator it = active_w.begin(); - while (it != active_w.end()) - { - typeVectorVertex simplex_vector; - /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ - // First sort the first k landmarks - VertexHandle inserted_vertex = knn[*it][k]; - bool ok = all_faces_in(knn, *it, k, inserted_vertex); - if (ok) - { - for (int i = 0; i != k+1; ++i) - simplex_vector.push_back(knn[*it][i]); - returnValue = insert_simplex(simplex_vector,0.0); - it++; - } - else - active_w.erase(it++); //First increase the iterator and then erase the previous element - } - k++; - } - print_sc(root()); std::cout << std::endl; -} - - void witness_complex_from_file(Point_Vector point_vector, int nbL) - { - //READ THE FILE INTO A POINT VECTOR - //std::vector< std::vector< double > > point_vector; - //read_points(file_name, point_vector); - std::vector > WL; - furthestPoints(point_vector, point_vector.size(), nbL, WL); - witness_complex(WL); - } - -private: - - void print_sc(Siblings * sibl) - { - if (sibl == NULL) - std::cout << "&"; - else - print_children(sibl->members_); - } - - void print_children(Dictionary map) - { - std::cout << "("; - if (!map.empty()) - { - std::cout << map.begin()->first; - /*if (map.begin()->second.children() == root()) - std::cout << "Sweet potato"; */ - if (has_children(map.begin())) - print_sc(map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - std::cout << "," << it->first; - /*if (map.begin()->second.children() == root()) - std::cout << "Sweet potato";*/ - if (has_children(it)) - print_sc(it->second.children()); - } - } - std::cout << ")"; - } - - template - bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) - { - //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; - std::vector< VertexHandle > facet; - //VertexHandle curr_vh = curr_sh->first; - // CHECK ALL THE FACETS - for (int i = 0; i != k+1; ++i) - { - if (knn[witness_id][i] != inserted_vertex) - { - facet = {}; - for (int j = 0; j != k+1; ++j) - { - if (j != i) - { - facet.push_back(knn[witness_id][j]); - } - }//endfor - if (find(facet) == null_simplex()) - return false; - //std::cout << "++++ finished loop safely\n"; - }//endif - } //endfor - return true; - } - - template - void print_vector(std::vector v) - { - std::cout << "["; - if (!v.empty()) - { - std::cout << *(v.begin()); - for (auto it = v.begin()+1; it != v.end(); ++it) - { - std::cout << ","; - std::cout << *it; - } - } - std::cout << "]"; - } - - template - void print_vvector(std::vector< std::vector > vv) - { - std::cout << "["; - if (!vv.empty()) - { - print_vector(*(vv.begin())); - for (auto it = vv.begin()+1; it != vv.end(); ++it) - { - std::cout << ","; - print_vector(*it); - } - } - std::cout << "]\n"; - } - -/** - * \brief Permutes the vector in such a way that the landmarks appear first - * \arg W is the vector of points which will be the witnesses - * \arg nbP is the number of witnesses - * \arg nbL is the number of landmarks - * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) - */ - - template - void furthestPoints(Point_Vector &W, int nbP, int nbL, KNearestNeighbours &WL) - //void furthestPoints(Point_Vector &W, int nbP, int nbL, Point_Vector &L) - { - std::cout << "Enter furthestPoints "<< std::endl; - // What is density and why we need it. - // basically it is the stop indicator for "no more landmarks" - //std::cout << "W="; print_vvector(W); - //double density = 5.; - std::vector< std::vector > wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - std::vector< int > chosen_landmarks; // landmark list - - WL = KNearestNeighbours(nbP,std::vector()); //nbP copies of empty vectors - int current_number_of_landmarks=0; - double curr_max_dist = 0; - double curr_dist; - double infty = std::numeric_limits::infinity(); - std::vector< double > dist_to_L(nbP,infty); - // double mindist = infty; - int curr_max_w=0; - int j; - int temp_swap_int; - double temp_swap_double; - - //CHOICE OF THE FIRST LANDMARK - //std::cout << "Enter the first landmark stage\n"; - srand(354698); - int rand_int = rand()% nbP; - curr_max_w = rand_int; - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - chosen_landmarks.push_back(curr_max_w); - curr_max_dist = 0; - std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - std::cout << "WL="; print_vvector(WL); - std::cout << "WLD="; print_vvector(wit_land_dist); - std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - for (auto v: WL) - v.push_back(current_number_of_landmarks); - for (int i = 0; i < nbP; ++i) - { - std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - if (i != chosen_landmarks[current_number_of_landmarks]) - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - else - curr_dist = 0; - //std::cout << "The problem is not in distance function\n"; - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; - if (curr_dist < dist_to_L[i]) - dist_to_L[i] = curr_dist; - if (dist_to_L[i] > curr_max_dist) - { - curr_max_dist = curr_dist; - curr_max_w = i; - } - j = current_number_of_landmarks; - //std::cout << "First half complete\n"; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } - std::cout << "result WL="; print_vvector(WL); - std::cout << "result WLD="; print_vvector(wit_land_dist); - - std::cout << "End loop\n"; - } - } - /* - while (1) { - curr_w = 0; - curr_max_dist = -1; - for(Point_Vector::iterator itW = W.begin(); itW != W.end(); itW++) { - //compute distance from w and L - mindist = infty; - for(Point_Vector::iterator itL = L.begin(); itL != L.end(); itL++) { - //curr_dist = distPoints(*itW,*itL); - curr_dist = euclidean_distance(*itW,*itL); - if(curr_dist < mindist) { - mindist = curr_dist; - } - } - if(mindist > curr_max_dist) { - curr_max_w = curr_w; //??? - curr_max_dist = mindist; - } - curr_w++; - } - L.push_back(W[curr_max_w]); - current_number_of_landmarks++; - //density = sqrt(curr_max_dist); - //std::cout << "[" << current_number_of_landmarks << ":" << density <<"] "; - if(L.size() == nbL) break; - } - */ - //std::cout << endl; - //return L; - } - -}; //class Witness_complex - - -} // namespace Guhdi - -#endif -- cgit v1.2.3 From 8df595a525b21fdd49816f312411814b3b894c21 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 31 Mar 2015 14:52:37 +0000 Subject: Fixed bug in landmark_choice_by_furthest_points. Stay tuned for one more bug git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@521 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e8f0a0b7122fd180b92fa3ba58e33dbec49f29ea --- src/Witness_complex/include/gudhi/Witness_complex.h | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index d5a35801..4b65e8a2 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -219,7 +219,7 @@ namespace Gudhi { void witness_complex_from_points(Point_Vector point_vector) { std::vector > WL; - landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); witness_complex(WL); } @@ -357,7 +357,6 @@ private: { //curr_max_w at this point is the next landmark chosen_landmarks.push_back(curr_max_w); - curr_max_dist = 0; //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; //std::cout << "WL="; print_vvector(WL); //std::cout << "WLD="; print_vvector(wit_land_dist); @@ -377,11 +376,6 @@ private: //std::cout << "Push't back\n"; if (curr_dist < dist_to_L[i]) dist_to_L[i] = curr_dist; - if (dist_to_L[i] > curr_max_dist) - { - curr_max_dist = curr_dist; - curr_max_w = i; - } j = current_number_of_landmarks; //std::cout << "First half complete\n"; while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) @@ -400,6 +394,17 @@ private: //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; //std::cout << "End loop\n"; } + std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; + curr_max_dist = 0; + for (int i = 0; i < nbP; ++i) { + if (dist_to_L[i] > curr_max_dist) + { + curr_max_dist = dist_to_L[i]; + curr_max_w = i; + std::cout << "hop curr_max_w is now " << curr_max_w << std::endl; + } + } + std::cout << "Chose " << curr_max_w << " as new landmark\n"; } //std::cout << endl; } -- cgit v1.2.3 From e6d3a9c57f80f65997183f4e08ecee31d4bcaae1 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 1 Apr 2015 08:21:06 +0000 Subject: Added landmark_strategy_by_random_points git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@525 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: dcf5d32465313860e4666a8e81128077e2cde1a5 --- src/Witness_complex/include/gudhi/Witness_complex.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 4b65e8a2..bcfe0f38 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -219,7 +219,7 @@ namespace Gudhi { void witness_complex_from_points(Point_Vector point_vector) { std::vector > WL; - landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + landmark_choice_by_random_points(point_vector, point_vector.size(), WL); witness_complex(WL); } @@ -360,7 +360,7 @@ private: //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; //std::cout << "WL="; print_vvector(WL); //std::cout << "WLD="; print_vvector(wit_land_dist); - std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; for (auto v: WL) v.push_back(current_number_of_landmarks); for (int i = 0; i < nbP; ++i) @@ -394,17 +394,16 @@ private: //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; //std::cout << "End loop\n"; } - std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; + //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; curr_max_dist = 0; for (int i = 0; i < nbP; ++i) { if (dist_to_L[i] > curr_max_dist) { curr_max_dist = dist_to_L[i]; curr_max_w = i; - std::cout << "hop curr_max_w is now " << curr_max_w << std::endl; } } - std::cout << "Chose " << curr_max_w << " as new landmark\n"; + //std::cout << "Chose " << curr_max_w << " as new landmark\n"; } //std::cout << endl; } -- cgit v1.2.3 From 42ef28d73a05b84ad02193e4f3bf76b416ba9a02 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 1 Apr 2015 14:50:43 +0000 Subject: Test commit: potentionally fix witness_complex_from_file.cpp file git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@530 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e5a3fd713024eb8a117ce58a1810f61af90490d0 --- src/Witness_complex/example/simple_witness_complex.cpp | 2 +- src/Witness_complex/example/witness_complex_from_file.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 7a46ffb3..43921c4e 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -23,7 +23,7 @@ #include #include //#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Witness_complex1.h" +#include "gudhi/Witness_complex.h" using namespace Gudhi; diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index a0e192f7..e2a80e92 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -2,9 +2,9 @@ * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author(s): Vincent Rouvreau + * Author(s): Siargey Kachanovich * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ #include #include //#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Witness_complex1.h" +#include "gudhi/Witness_complex.h" using namespace Gudhi; @@ -81,7 +81,8 @@ int main (int argc, char * const argv[]) start = clock(); Point_Vector point_vector; read_points_cust(file_name, point_vector); - witnessComplex.witness_complex_from_file(point_vector, nbL); + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex_from_points(point_vector); end = clock(); std::cout << "Howdy world! The process took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; -- cgit v1.2.3 From b76ee21ac17dbfc630bb16d66fec4b1c2ee4013a Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 2 Apr 2015 12:28:46 +0000 Subject: Added writing to file functions git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@538 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 429568c33608ad8f49508513379e33cd6a73b006 --- .../include/gudhi/Witness_complex.h | 40 +++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index bcfe0f38..1b50ca95 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -208,7 +208,7 @@ namespace Gudhi { } k++; } - print_sc(root()); std::cout << std::endl; + //print_sc(root()); std::cout << std::endl; } /** \brief Construction of witness complex from points given explicitly @@ -254,6 +254,44 @@ private: std::cout << ")"; } + public: + /** \brief Print functions + */ + + void st_to_file(std::ofstream& out_file) + { + sc_to_file(out_file, root()); + } + + private: + void sc_to_file(std::ofstream& out_file, Siblings * sibl) + { + if (sibl == NULL) + out_file << "&"; + else + children_to_file(out_file, sibl->members_); + } + + void children_to_file(std::ofstream& out_file, Dictionary map) + { + out_file << "("; + if (!map.empty()) + { + out_file << map.begin()->first; + if (has_children(map.begin())) + sc_to_file(out_file, map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + out_file << "," << it->first; + if (has_children(it)) + sc_to_file(out_file, it->second.children()); + } + } + out_file << ")"; + } + + /** \brief Check if the facets of the k-dimensional simplex witnessed * by witness witness_id are already in the complex. * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id -- cgit v1.2.3 From 35c75c5d30236dd29ad8e4d4f12de8223e73b58e Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 2 Apr 2015 12:38:30 +0000 Subject: Added also changes in the cpp file git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@539 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e32f574c7cf93f67de3d08b43f9c6de5a4a8396d --- src/Witness_complex/example/witness_complex_from_file.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index e2a80e92..cec1d1b8 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -23,6 +23,9 @@ #include #include #include + +//#include + //#include "gudhi/graph_simplicial_complex.h" #include "gudhi/Witness_complex.h" @@ -86,5 +89,13 @@ int main (int argc, char * const argv[]) end = clock(); std::cout << "Howdy world! The process took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - + char buffer[100]; + int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } } -- cgit v1.2.3 From cc8adaf7524cb56b6616bd6f6041af2e534ee211 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 2 Apr 2015 14:11:52 +0000 Subject: Added parallel file git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@540 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b56520af4bef97f99cae62924fc4860ce1e2f73e --- .../include/gudhi/Witness_complex-parallel.h | 553 +++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 src/Witness_complex/include/gudhi/Witness_complex-parallel.h (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex-parallel.h b/src/Witness_complex/include/gudhi/Witness_complex-parallel.h new file mode 100644 index 00000000..ac5c8dd5 --- /dev/null +++ b/src/Witness_complex/include/gudhi/Witness_complex-parallel.h @@ -0,0 +1,553 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_WITNESS_COMPLEX_H_ +#define GUDHI_WITNESS_COMPLEX_H_ + +#include +#include +#include +#include +#include "gudhi/reader_utils.h" +#include "gudhi/distance_functions.h" +#include "gudhi/Simplex_tree.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Gudhi { + + + /** \addtogroup simplex_tree + * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: + * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ + * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that + * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. + */ + template + class Witness_complex: public Simplex_tree<> { + + private: + + struct Active_witness { + int witness_id; + int landmark_id; + Simplex_handle simplex_handle; + + Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + : witness_id(witness_id_), + landmark_id(landmark_id_), + simplex_handle(simplex_handle_) + {} + }; + + + + + public: + + + /** \brief Type for the vertex handle. + * + * Must be a signed integer type. It admits a total order <. */ + typedef VertexHandle Vertex_handle; + + /* Type of node in the simplex tree. */ + typedef Simplex_tree_node_explicit_storage Node; + /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ + typedef typename boost::container::flat_map Dictionary; + typedef typename Dictionary::iterator Simplex_handle; + + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + + typedef std::vector< Vertex_handle > typeVectorVertex; + typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; + typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + typedef int Witness_id; + typedef int Landmark_id; + typedef std::list< Vertex_handle > ActiveWitnessList; + + private: + /** Number of landmarks + */ + int nbL; + /** Desired density + */ + double density; + + public: + + /** \brief Set number of landmarks to nbL_ + */ + void setNbL(int nbL_) + { + nbL = nbL_; + } + + /** \brief Set density to density_ + */ + void setDensity(double density_) + { + density = density_; + } + + /** + * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. + * Landmarks are supposed to be in [0,nbL-1] + */ + + template< typename KNearestNeighbours > + void witness_complex(KNearestNeighbours & knn) + //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) + { + std::cout << "**Start the procedure witness_complex" << std::endl; + int k=2; /* current dimension in iterative construction */ + //Construction of the active witness list + int nbW = knn.size(); + //int nbL = knn.at(0).size(); + typeVectorVertex vv; + typeSimplex simplex; + typePairSimplexBool returnValue; + int counter = 0; + /* The list of still useful witnesses + * it will diminuish in the course of iterations + */ + ActiveWitnessList active_w;// = new ActiveWitnessList(); + for (int i=0; i != nbL; ++i) { + // initial fill of 0-dimensional simplices + // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore + counter++; + vv = {i}; + /* TODO Filtration */ + returnValue = insert_simplex(vv, Filtration_value(0.0)); + /* TODO Error if not inserted : normally no need here though*/ + } + //std::cout << "Successfully added landmarks" << std::endl; + // PRINT2 + //print_sc(root()); std::cout << std::endl; + int u,v; // two extremities of an edge + if (nbL > 1) // if the supposed dimension of the complex is >0 + { + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + vv = {u,v}; + returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + //print_sc(root()); std::cout << std::endl; + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + if ( u > v) + { + u = v; + v = knn[i][0]; + knn[i][0] = knn[i][1]; + knn[i][1] = v; + } + Simplex_handle sh; + vv = {u,v}; + sh = (root()->find(u))->second.children()->find(v); + active_w.push_back(i); + } + } + //std::cout << "Successfully added edges" << std::endl; + while (!active_w.empty() && k < nbL ) + { + //std::cout << "Started the step k=" << k << std::endl; + typename ActiveWitnessList::iterator it = active_w.begin(); + while (it != active_w.end()) + { + typeVectorVertex simplex_vector; + /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ + // First sort the first k landmarks + VertexHandle inserted_vertex = knn[*it][k]; + bool ok = all_faces_in(knn, *it, k, inserted_vertex); + if (ok) + { + for (int i = 0; i != k+1; ++i) + simplex_vector.push_back(knn[*it][i]); + returnValue = insert_simplex(simplex_vector,0.0); + it++; + } + else + active_w.erase(it++); //First increase the iterator and then erase the previous element + } + k++; + } + //print_sc(root()); std::cout << std::endl; + } + + /** \brief Construction of witness complex from points given explicitly + * nbL must be set to the right value of landmarks for strategies + * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and + * density must be set to the right value for DENSITY_STRATEGY + */ + void witness_complex_from_points(Point_Vector point_vector) + { + std::vector > WL; + clock_t start,end; + start = clock(); + landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + end = clock(); + std::cout << "Landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; + start = clock(); + witness_complex(WL); + end = clock(); + std::cout << "Complex construction took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; + } + +private: + + /** \brief Print functions + */ + void print_sc(Siblings * sibl) + { + if (sibl == NULL) + std::cout << "&"; + else + print_children(sibl->members_); + } + + void print_children(Dictionary map) + { + std::cout << "("; + if (!map.empty()) + { + std::cout << map.begin()->first; + if (has_children(map.begin())) + print_sc(map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + std::cout << "," << it->first; + if (has_children(it)) + print_sc(it->second.children()); + } + } + std::cout << ")"; + } + + public: + /** \brief Print functions + */ + + void st_to_file(std::ofstream& out_file) + { + sc_to_file(out_file, root()); + } + + private: + void sc_to_file(std::ofstream& out_file, Siblings * sibl) + { + if (sibl == NULL) + out_file << "&"; + else + children_to_file(out_file, sibl->members_); + } + + void children_to_file(std::ofstream& out_file, Dictionary map) + { + out_file << "("; + if (!map.empty()) + { + out_file << map.begin()->first; + if (has_children(map.begin())) + sc_to_file(out_file, map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + out_file << "," << it->first; + if (has_children(it)) + sc_to_file(out_file, it->second.children()); + } + } + out_file << ")"; + } + + + /** \brief Check if the facets of the k-dimensional simplex witnessed + * by witness witness_id are already in the complex. + * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id + */ + template + bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) + { + //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + std::vector< VertexHandle > facet; + //VertexHandle curr_vh = curr_sh->first; + // CHECK ALL THE FACETS + for (int i = 0; i != k+1; ++i) + { + if (knn[witness_id][i] != inserted_vertex) + { + facet = {}; + for (int j = 0; j != k+1; ++j) + { + if (j != i) + { + facet.push_back(knn[witness_id][j]); + } + }//endfor + if (find(facet) == null_simplex()) + return false; + //std::cout << "++++ finished loop safely\n"; + }//endif + } //endfor + return true; + } + + template + void print_vector(std::vector v) + { + std::cout << "["; + if (!v.empty()) + { + std::cout << *(v.begin()); + for (auto it = v.begin()+1; it != v.end(); ++it) + { + std::cout << ","; + std::cout << *it; + } + } + std::cout << "]"; + } + + template + void print_vvector(std::vector< std::vector > vv) + { + std::cout << "["; + if (!vv.empty()) + { + print_vector(*(vv.begin())); + for (auto it = vv.begin()+1; it != vv.end(); ++it) + { + std::cout << ","; + print_vector(*it); + } + } + std::cout << "]\n"; + } + +/** + * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the + * current landmark set + * \arg W is the vector of points which will be the witnesses + * \arg nbP is the number of witnesses + * \arg nbL is the number of landmarks + * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) + */ + + template + void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + { + //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; + //std::cout << "W="; print_vvector(W); + //double density = 5.; + Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + typeVectorVertex chosen_landmarks; // landmark list + + WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + double curr_max_dist = 0; // used for defining the furhest point from L + double curr_dist; // used to stock the distance from the current point to L + double infty = std::numeric_limits::infinity(); // infinity (see next entry) + std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points + // double mindist = infty; + int curr_max_w=0; // the point currently furthest from L + int j; + int temp_swap_int; + double temp_swap_double; + + //CHOICE OF THE FIRST LANDMARK + std::cout << "Enter the first landmark stage\n"; + srand(354698); + int rand_int = rand()% nbP; + curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + //curr_max_w at this point is the next landmark + chosen_landmarks.push_back(curr_max_w); + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + for (auto v: WL) + v.push_back(current_number_of_landmarks); + //#pragma omp parallel for + for (int i = 0; i < nbP; ++i) + { + // iteration on points in W. update of distance vectors + + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + //std::cout << "The problem is not in distance function\n"; + wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + // sort the closest landmark vector for every witness + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + } + //std::cout << "result WL="; print_vvector(WL); + //std::cout << "result WLD="; print_vvector(wit_land_dist); + //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; + //std::cout << "End loop\n"; + } + //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; + curr_max_dist = 0; + //omp_set_variable() + #pragma omp parallel for + for (int i = 0; i < nbP; ++i) { + if (dist_to_L[i] > curr_max_dist) + { + //#pragma omp ordered + { + curr_max_dist = dist_to_L[i]; + curr_max_w = i; + } + } + } + /* + for (int i = 0; i < nbP; ++i) { + if (dist_to_L[i] > curr_max_dist) + { + { + curr_max_dist = dist_to_L[i]; + curr_max_w = i; + } + } + } + */ + //std::cout << "Chose " << curr_max_w << " as new landmark\n"; + } + //std::cout << endl; + } + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * + */ + + template + void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + { + //std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + //std::cout << "W="; print_vvector(W); + std::unordered_set< int > chosen_landmarks; // landmark set + + Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + + WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + + srand(24660); + int chosen_landmark = rand()%nbP; + double curr_dist; + + int j; + int temp_swap_int; + double temp_swap_double; + + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) + { + srand((int)clock()); + chosen_landmark = rand()% nbP; + //std::cout << chosen_landmark << "\n"; + } + chosen_landmarks.insert(chosen_landmark); + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + for (auto v: WL) + v.push_back(current_number_of_landmarks); + for (int i = 0; i < nbP; ++i) + { + // iteration on points in W. update of distance vectors + + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + //std::cout << "The problem is not in distance function\n"; + wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; + j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + // sort the closest landmark vector for every witness + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + } + //std::cout << "result WL="; print_vvector(WL); + //std::cout << "result WLD="; print_vvector(wit_land_dist); + //std::cout << "End loop\n"; + } + } + //std::cout << endl; + } + + +}; //class Witness_complex + + + +} // namespace Guhdi + +#endif -- cgit v1.2.3 From 30b0effaf86ff300c5519e0919b33f61fc4a14f8 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 7 Apr 2015 10:25:17 +0000 Subject: Deleted the parallel attempt file git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@544 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a853bc4b2afe5bfdaa8e95065f928c7c48988610 --- .../include/gudhi/Witness_complex-parallel.h | 553 --------------------- 1 file changed, 553 deletions(-) delete mode 100644 src/Witness_complex/include/gudhi/Witness_complex-parallel.h (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex-parallel.h b/src/Witness_complex/include/gudhi/Witness_complex-parallel.h deleted file mode 100644 index ac5c8dd5..00000000 --- a/src/Witness_complex/include/gudhi/Witness_complex-parallel.h +++ /dev/null @@ -1,553 +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): Siargey Kachanovich - * - * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef GUDHI_WITNESS_COMPLEX_H_ -#define GUDHI_WITNESS_COMPLEX_H_ - -#include -#include -#include -#include -#include "gudhi/reader_utils.h" -#include "gudhi/distance_functions.h" -#include "gudhi/Simplex_tree.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Gudhi { - - - /** \addtogroup simplex_tree - * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: - * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ - * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that - * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. - */ - template - class Witness_complex: public Simplex_tree<> { - - private: - - struct Active_witness { - int witness_id; - int landmark_id; - Simplex_handle simplex_handle; - - Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) - : witness_id(witness_id_), - landmark_id(landmark_id_), - simplex_handle(simplex_handle_) - {} - }; - - - - - public: - - - /** \brief Type for the vertex handle. - * - * Must be a signed integer type. It admits a total order <. */ - typedef VertexHandle Vertex_handle; - - /* Type of node in the simplex tree. */ - typedef Simplex_tree_node_explicit_storage Node; - /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ - typedef typename boost::container::flat_map Dictionary; - typedef typename Dictionary::iterator Simplex_handle; - - typedef std::vector< double > Point_t; - typedef std::vector< Point_t > Point_Vector; - - typedef std::vector< Vertex_handle > typeVectorVertex; - typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; - typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - - typedef int Witness_id; - typedef int Landmark_id; - typedef std::list< Vertex_handle > ActiveWitnessList; - - private: - /** Number of landmarks - */ - int nbL; - /** Desired density - */ - double density; - - public: - - /** \brief Set number of landmarks to nbL_ - */ - void setNbL(int nbL_) - { - nbL = nbL_; - } - - /** \brief Set density to density_ - */ - void setDensity(double density_) - { - density = density_; - } - - /** - * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. - * Landmarks are supposed to be in [0,nbL-1] - */ - - template< typename KNearestNeighbours > - void witness_complex(KNearestNeighbours & knn) - //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) - { - std::cout << "**Start the procedure witness_complex" << std::endl; - int k=2; /* current dimension in iterative construction */ - //Construction of the active witness list - int nbW = knn.size(); - //int nbL = knn.at(0).size(); - typeVectorVertex vv; - typeSimplex simplex; - typePairSimplexBool returnValue; - int counter = 0; - /* The list of still useful witnesses - * it will diminuish in the course of iterations - */ - ActiveWitnessList active_w;// = new ActiveWitnessList(); - for (int i=0; i != nbL; ++i) { - // initial fill of 0-dimensional simplices - // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore - counter++; - vv = {i}; - /* TODO Filtration */ - returnValue = insert_simplex(vv, Filtration_value(0.0)); - /* TODO Error if not inserted : normally no need here though*/ - } - //std::cout << "Successfully added landmarks" << std::endl; - // PRINT2 - //print_sc(root()); std::cout << std::endl; - int u,v; // two extremities of an edge - if (nbL > 1) // if the supposed dimension of the complex is >0 - { - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - //print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; - } - //print_sc(root()); - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - if ( u > v) - { - u = v; - v = knn[i][0]; - knn[i][0] = knn[i][1]; - knn[i][1] = v; - } - Simplex_handle sh; - vv = {u,v}; - sh = (root()->find(u))->second.children()->find(v); - active_w.push_back(i); - } - } - //std::cout << "Successfully added edges" << std::endl; - while (!active_w.empty() && k < nbL ) - { - //std::cout << "Started the step k=" << k << std::endl; - typename ActiveWitnessList::iterator it = active_w.begin(); - while (it != active_w.end()) - { - typeVectorVertex simplex_vector; - /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ - // First sort the first k landmarks - VertexHandle inserted_vertex = knn[*it][k]; - bool ok = all_faces_in(knn, *it, k, inserted_vertex); - if (ok) - { - for (int i = 0; i != k+1; ++i) - simplex_vector.push_back(knn[*it][i]); - returnValue = insert_simplex(simplex_vector,0.0); - it++; - } - else - active_w.erase(it++); //First increase the iterator and then erase the previous element - } - k++; - } - //print_sc(root()); std::cout << std::endl; - } - - /** \brief Construction of witness complex from points given explicitly - * nbL must be set to the right value of landmarks for strategies - * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and - * density must be set to the right value for DENSITY_STRATEGY - */ - void witness_complex_from_points(Point_Vector point_vector) - { - std::vector > WL; - clock_t start,end; - start = clock(); - landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - end = clock(); - std::cout << "Landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; - start = clock(); - witness_complex(WL); - end = clock(); - std::cout << "Complex construction took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; - } - -private: - - /** \brief Print functions - */ - void print_sc(Siblings * sibl) - { - if (sibl == NULL) - std::cout << "&"; - else - print_children(sibl->members_); - } - - void print_children(Dictionary map) - { - std::cout << "("; - if (!map.empty()) - { - std::cout << map.begin()->first; - if (has_children(map.begin())) - print_sc(map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - std::cout << "," << it->first; - if (has_children(it)) - print_sc(it->second.children()); - } - } - std::cout << ")"; - } - - public: - /** \brief Print functions - */ - - void st_to_file(std::ofstream& out_file) - { - sc_to_file(out_file, root()); - } - - private: - void sc_to_file(std::ofstream& out_file, Siblings * sibl) - { - if (sibl == NULL) - out_file << "&"; - else - children_to_file(out_file, sibl->members_); - } - - void children_to_file(std::ofstream& out_file, Dictionary map) - { - out_file << "("; - if (!map.empty()) - { - out_file << map.begin()->first; - if (has_children(map.begin())) - sc_to_file(out_file, map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - out_file << "," << it->first; - if (has_children(it)) - sc_to_file(out_file, it->second.children()); - } - } - out_file << ")"; - } - - - /** \brief Check if the facets of the k-dimensional simplex witnessed - * by witness witness_id are already in the complex. - * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id - */ - template - bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) - { - //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; - std::vector< VertexHandle > facet; - //VertexHandle curr_vh = curr_sh->first; - // CHECK ALL THE FACETS - for (int i = 0; i != k+1; ++i) - { - if (knn[witness_id][i] != inserted_vertex) - { - facet = {}; - for (int j = 0; j != k+1; ++j) - { - if (j != i) - { - facet.push_back(knn[witness_id][j]); - } - }//endfor - if (find(facet) == null_simplex()) - return false; - //std::cout << "++++ finished loop safely\n"; - }//endif - } //endfor - return true; - } - - template - void print_vector(std::vector v) - { - std::cout << "["; - if (!v.empty()) - { - std::cout << *(v.begin()); - for (auto it = v.begin()+1; it != v.end(); ++it) - { - std::cout << ","; - std::cout << *it; - } - } - std::cout << "]"; - } - - template - void print_vvector(std::vector< std::vector > vv) - { - std::cout << "["; - if (!vv.empty()) - { - print_vector(*(vv.begin())); - for (auto it = vv.begin()+1; it != vv.end(); ++it) - { - std::cout << ","; - print_vector(*it); - } - } - std::cout << "]\n"; - } - -/** - * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the - * current landmark set - * \arg W is the vector of points which will be the witnesses - * \arg nbP is the number of witnesses - * \arg nbL is the number of landmarks - * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) - */ - - template - void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - { - //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - //double density = 5.; - Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - typeVectorVertex chosen_landmarks; // landmark list - - WL = KNearestNeighbours(nbP,std::vector()); - int current_number_of_landmarks=0; // counter for landmarks - double curr_max_dist = 0; // used for defining the furhest point from L - double curr_dist; // used to stock the distance from the current point to L - double infty = std::numeric_limits::infinity(); // infinity (see next entry) - std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points - // double mindist = infty; - int curr_max_w=0; // the point currently furthest from L - int j; - int temp_swap_int; - double temp_swap_double; - - //CHOICE OF THE FIRST LANDMARK - std::cout << "Enter the first landmark stage\n"; - srand(354698); - int rand_int = rand()% nbP; - curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - //curr_max_w at this point is the next landmark - chosen_landmarks.push_back(curr_max_w); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - for (auto v: WL) - v.push_back(current_number_of_landmarks); - //#pragma omp parallel for - for (int i = 0; i < nbP; ++i) - { - // iteration on points in W. update of distance vectors - - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - //std::cout << "The problem is not in distance function\n"; - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; - if (curr_dist < dist_to_L[i]) - dist_to_L[i] = curr_dist; - j = current_number_of_landmarks; - //std::cout << "First half complete\n"; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - // sort the closest landmark vector for every witness - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } - //std::cout << "result WL="; print_vvector(WL); - //std::cout << "result WLD="; print_vvector(wit_land_dist); - //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; - //std::cout << "End loop\n"; - } - //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; - curr_max_dist = 0; - //omp_set_variable() - #pragma omp parallel for - for (int i = 0; i < nbP; ++i) { - if (dist_to_L[i] > curr_max_dist) - { - //#pragma omp ordered - { - curr_max_dist = dist_to_L[i]; - curr_max_w = i; - } - } - } - /* - for (int i = 0; i < nbP; ++i) { - if (dist_to_L[i] > curr_max_dist) - { - { - curr_max_dist = dist_to_L[i]; - curr_max_w = i; - } - } - } - */ - //std::cout << "Chose " << curr_max_w << " as new landmark\n"; - } - //std::cout << endl; - } - - /** \brief Landmark choice strategy by taking random vertices for landmarks. - * - */ - - template - void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - { - //std::cout << "Enter landmark_choice_by_random_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - std::unordered_set< int > chosen_landmarks; // landmark set - - Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - - WL = KNearestNeighbours(nbP,std::vector()); - int current_number_of_landmarks=0; // counter for landmarks - - srand(24660); - int chosen_landmark = rand()%nbP; - double curr_dist; - - int j; - int temp_swap_int; - double temp_swap_double; - - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) - { - srand((int)clock()); - chosen_landmark = rand()% nbP; - //std::cout << chosen_landmark << "\n"; - } - chosen_landmarks.insert(chosen_landmark); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - for (auto v: WL) - v.push_back(current_number_of_landmarks); - for (int i = 0; i < nbP; ++i) - { - // iteration on points in W. update of distance vectors - - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - //std::cout << "The problem is not in distance function\n"; - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; - j = current_number_of_landmarks; - //std::cout << "First half complete\n"; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - // sort the closest landmark vector for every witness - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } - //std::cout << "result WL="; print_vvector(WL); - //std::cout << "result WLD="; print_vvector(wit_land_dist); - //std::cout << "End loop\n"; - } - } - //std::cout << endl; - } - - -}; //class Witness_complex - - - -} // namespace Guhdi - -#endif -- cgit v1.2.3 From 244d9ce5a5cb9050255cf519def9bdb273646f81 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 8 Apr 2015 14:50:03 +0000 Subject: Added rock-age style off reader git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@553 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 74462161c45893cfbfcc1875569b93b365445e35 --- CMakeLists.txt | 12 +++--- .../example/witness_complex_from_file.cpp | 43 +++++++++++++++++++++- .../include/gudhi/Witness_complex.h | 4 +- 3 files changed, 50 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index fabba412..0684b18e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ if(MSVC) # Turn off some VC++ warnings SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -std=c++11 -Wall -Wpedantic -Wsign-compare") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -std=c++11 -Wall -Wsign-compare") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") endif() @@ -24,12 +24,12 @@ set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) find_package(Boost) -find_package(GMP) -if(GMP_FOUND) - find_package(GMPXX) -endif() +#find_package(GMP) +#if(GMP_FOUND) + #find_package(GMPXX) +#endif() -find_package(CGAL) +#find_package(CGAL) # Required programs for unitary tests purpose FIND_PROGRAM( LCOV_PATH lcov ) diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index cec1d1b8..b1d7575a 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -28,7 +28,7 @@ //#include "gudhi/graph_simplicial_complex.h" #include "gudhi/Witness_complex.h" - +#include "gudhi/reader_utils.h" using namespace Gudhi; @@ -65,6 +65,44 @@ read_points_cust ( std::string file_name , std::vector< std::vector< double > > in_file.close(); } +/** + * \brief Rock age method of reading off file + * + */ +inline void +off_reader_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + // Line OFF. No need in it + if (!getline(in_file, line)) + { + std::cerr << "No line OFF\n"; + return; + } + // Line with 3 numbers. No need + if (!getline(in_file, line)) + { + std::cerr << "No line with 3 numbers\n"; + return; + } + // Reading points + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + points.push_back(point); + } + in_file.close(); +} + int main (int argc, char * const argv[]) { if (argc != 3) @@ -83,7 +121,8 @@ int main (int argc, char * const argv[]) std::cout << "Let the carnage begin!\n"; start = clock(); Point_Vector point_vector; - read_points_cust(file_name, point_vector); + off_reader_cust(file_name, point_vector); + std::cout << "Successfully read the points\n"; witnessComplex.setNbL(nbL); witnessComplex.witness_complex_from_points(point_vector); end = clock(); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 1b50ca95..f4b1d62c 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -184,6 +184,7 @@ namespace Gudhi { active_w.push_back(i); } } + std::cout << "k=1, active witnesses: " << active_w.size() << std::endl; //std::cout << "Successfully added edges" << std::endl; while (!active_w.empty() && k < nbL ) { @@ -206,6 +207,7 @@ namespace Gudhi { else active_w.erase(it++); //First increase the iterator and then erase the previous element } + std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; k++; } //print_sc(root()); std::cout << std::endl; @@ -453,7 +455,7 @@ private: template void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) { - //std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + std::cout << "Enter landmark_choice_by_random_points "<< std::endl; //std::cout << "W="; print_vvector(W); std::unordered_set< int > chosen_landmarks; // landmark set -- cgit v1.2.3 From 3f659091c2e941714cc3de101d8525c5ea28b2de Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 8 Apr 2015 14:56:13 +0000 Subject: Added witness_complex_from_off git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@554 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 36536d49be6f49f9f388d3e8e61bcf09ed7e1424 --- .../example/witness_complex_from_file.cpp | 40 +----- .../example/witness_complex_from_off.cpp | 140 +++++++++++++++++++++ 2 files changed, 141 insertions(+), 39 deletions(-) create mode 100644 src/Witness_complex/example/witness_complex_from_off.cpp (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index b1d7575a..7460652f 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -65,44 +65,6 @@ read_points_cust ( std::string file_name , std::vector< std::vector< double > > in_file.close(); } -/** - * \brief Rock age method of reading off file - * - */ -inline void -off_reader_cust ( std::string file_name , std::vector< std::vector< double > > & points) -{ - std::ifstream in_file (file_name.c_str(),std::ios::in); - if(!in_file.is_open()) - { - std::cerr << "Unable to open file " << file_name << std::endl; - return; - } - std::string line; - double x; - // Line OFF. No need in it - if (!getline(in_file, line)) - { - std::cerr << "No line OFF\n"; - return; - } - // Line with 3 numbers. No need - if (!getline(in_file, line)) - { - std::cerr << "No line with 3 numbers\n"; - return; - } - // Reading points - while( getline ( in_file , line ) ) - { - std::vector< double > point; - std::istringstream iss( line ); - while(iss >> x) { point.push_back(x); } - points.push_back(point); - } - in_file.close(); -} - int main (int argc, char * const argv[]) { if (argc != 3) @@ -121,7 +83,7 @@ int main (int argc, char * const argv[]) std::cout << "Let the carnage begin!\n"; start = clock(); Point_Vector point_vector; - off_reader_cust(file_name, point_vector); + read_points_cust(file_name, point_vector); std::cout << "Successfully read the points\n"; witnessComplex.setNbL(nbL); witnessComplex.witness_complex_from_points(point_vector); diff --git a/src/Witness_complex/example/witness_complex_from_off.cpp b/src/Witness_complex/example/witness_complex_from_off.cpp new file mode 100644 index 00000000..b1d7575a --- /dev/null +++ b/src/Witness_complex/example/witness_complex_from_off.cpp @@ -0,0 +1,140 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" + +using namespace Gudhi; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::vector< std::vector > Point_Vector; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + if (point.size() != 1) + points.push_back(point); + } + in_file.close(); +} + +/** + * \brief Rock age method of reading off file + * + */ +inline void +off_reader_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + // Line OFF. No need in it + if (!getline(in_file, line)) + { + std::cerr << "No line OFF\n"; + return; + } + // Line with 3 numbers. No need + if (!getline(in_file, line)) + { + std::cerr << "No line with 3 numbers\n"; + return; + } + // Reading points + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + points.push_back(point); + } + in_file.close(); +} + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + + clock_t start, end; + //Construct the Simplex Tree + Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + start = clock(); + Point_Vector point_vector; + off_reader_cust(file_name, point_vector); + std::cout << "Successfully read the points\n"; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex_from_points(point_vector); + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + char buffer[100]; + int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } +} -- cgit v1.2.3 From 7e1913f458abc7f526459c775f4b6e0c4a6d9ac0 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 8 Apr 2015 16:46:42 +0000 Subject: witness_from_points now creates an output directory+WL matrix output git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@555 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b5f1886dcc06e606d21e5e20cb5f394cf3920ea4 --- .../example/witness_complex_from_file.cpp | 57 +++++++++++++++++++--- .../include/gudhi/Witness_complex.h | 3 +- 2 files changed, 52 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 7460652f..be4869ea 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -24,13 +24,17 @@ #include #include +#include +#include //#include //#include "gudhi/graph_simplicial_complex.h" #include "gudhi/Witness_complex.h" #include "gudhi/reader_utils.h" +//#include using namespace Gudhi; +//using namespace boost::filesystem; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::vector< std::vector > Point_Vector; @@ -65,14 +69,32 @@ read_points_cust ( std::string file_name , std::vector< std::vector< double > > in_file.close(); } +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + int main (int argc, char * const argv[]) { - if (argc != 3) - { - std::cerr << "Usage: " << argv[0] - << " path_to_point_file nbL \n"; - return 0; - } + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + /* + boost::filesystem::path p; + + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ std::string file_name = argv[1]; int nbL = atoi(argv[2]); @@ -86,10 +108,24 @@ int main (int argc, char * const argv[]) read_points_cust(file_name, point_vector); std::cout << "Successfully read the points\n"; witnessComplex.setNbL(nbL); - witnessComplex.witness_complex_from_points(point_vector); + // witnessComplex.witness_complex_from_points(point_vector); + std::vector > WL; + witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + // Write the WL matrix in a file + mkdir("output", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; + write_wl(out_file,WL); + witnessComplex.witness_complex(WL); + // end = clock(); std::cout << "Howdy world! The process took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + /* char buffer[100]; int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); if (i >= 0) @@ -99,4 +135,11 @@ int main (int argc, char * const argv[]) witnessComplex.st_to_file(ofs); ofs.close(); } + */ + + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index f4b1d62c..89abeb1f 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -356,7 +356,8 @@ private: } std::cout << "]\n"; } - + + public: /** * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the * current landmark set -- cgit v1.2.3 From f3d75e50187c04d7be3f55fe9fbb77fb3ed90888 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 8 Apr 2015 16:51:33 +0000 Subject: added separate time for landmarks and complex construction git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@556 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 11f86285979963b9dd0cd65fcc1229bb8f5323b6 --- src/Witness_complex/example/witness_complex_from_file.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index be4869ea..35c00003 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -103,14 +103,17 @@ int main (int argc, char * const argv[]) Witness_complex<> witnessComplex; std::cout << "Let the carnage begin!\n"; - start = clock(); Point_Vector point_vector; read_points_cust(file_name, point_vector); - std::cout << "Successfully read the points\n"; + //std::cout << "Successfully read the points\n"; witnessComplex.setNbL(nbL); // witnessComplex.witness_complex_from_points(point_vector); std::vector > WL; + start = clock(); witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + end = clock(); + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; // Write the WL matrix in a file mkdir("output", S_IRWXU); const size_t last_slash_idx = file_name.find_last_of("/"); @@ -120,6 +123,7 @@ int main (int argc, char * const argv[]) } std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; write_wl(out_file,WL); + start = clock(); witnessComplex.witness_complex(WL); // end = clock(); -- cgit v1.2.3 From f6bd8bf87d5033a6f9c4ce726bfb040ccb6b452f Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 9 Apr 2015 07:36:16 +0000 Subject: Added witness complex from wl matrix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@557 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 61865da9db4f3a4a42b1d4e9e60a33b7671e5df2 --- src/Witness_complex/example/CMakeLists.txt | 4 + .../example/witness_complex_from_wl_matrix.cpp | 160 +++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/Witness_complex/example/witness_complex_from_wl_matrix.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 74007c65..51f7976b 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -7,6 +7,10 @@ add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_compl add_executable( witness_complex_from_file witness_complex_from_file.cpp ) add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 ) +add_executable( witness_complex_from_off witness_complex_from_off.cpp ) + +add_executable( witness_complex_from_wl_matrix witness_complex_from_wl_matrix.cpp ) + # An example with Simplex-tree using CGAL alpha_shapes_3 #if(GMP_FOUND AND CGAL_FOUND) # message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") diff --git a/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp b/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp new file mode 100644 index 00000000..2fec499c --- /dev/null +++ b/src/Witness_complex/example/witness_complex_from_wl_matrix.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): Siargey Kachanovich + * + * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::vector< std::vector > Point_Vector; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + if (point.size() != 1) + points.push_back(point); + } + in_file.close(); +} + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + +void read_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + int x; + while( getline ( in_file , line ) ) + { + std::vector< int > witness; + std::istringstream iss( line ); + while(iss >> x) { witness.push_back(x); } + WL.push_back(witness); + } + in_file.close(); + +} + +int main (int argc, char * const argv[]) +{ + if (argc != 2) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file \n"; + return 0; + } + /* + boost::filesystem::path p; + + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + std::string file_name = argv[1]; + //int nbL = atoi(argv[2]); + + clock_t start, end; + //Construct the Simplex Tree + Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + read_points_cust(file_name, point_vector); + //std::cout << "Successfully read the points\n"; + // witnessComplex.witness_complex_from_points(point_vector); + std::vector > WL; + read_wl(file_name,WL); + witnessComplex.setNbL(WL[0].size()); + // Write the WL matrix in a file + std::string out_file; + write_wl(out_file,WL); + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + /* + char buffer[100]; + int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + */ + + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + +} -- cgit v1.2.3 From ec1bdf0a6eae6708e9071c9f332c6c4782c2884c Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 9 Apr 2015 16:05:11 +0000 Subject: Added is_pseudomanifold & Co functions. It compiles. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@558 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e4569f2ef6e36cca22b4a3856b3631c324c506c8 --- .../example/witness_complex_from_wl_matrix.cpp | 12 -- .../include/gudhi/Witness_complex.h | 137 ++++++++++++++++++++- 2 files changed, 136 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp b/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp index 2fec499c..614bb945 100644 --- a/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp +++ b/src/Witness_complex/example/witness_complex_from_wl_matrix.cpp @@ -140,18 +140,6 @@ int main (int argc, char * const argv[]) end = clock(); std::cout << "Howdy world! The process took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - /* - char buffer[100]; - int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); - if (i >= 0) - { - std::string out_file = (std::string)buffer; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - } - */ - out_file = "output/"+file_name+"_"+argv[2]+".stree"; std::ofstream ofs (out_file, std::ofstream::out); witnessComplex.st_to_file(ofs); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 89abeb1f..ef470589 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -38,6 +38,10 @@ #include #include +#include +#include +#include + namespace Gudhi { @@ -93,7 +97,7 @@ namespace Gudhi { typedef int Witness_id; typedef int Landmark_id; typedef std::list< Vertex_handle > ActiveWitnessList; - + private: /** Number of landmarks */ @@ -521,7 +525,138 @@ private: //std::cout << endl; } + void write_bad_links(std::ofstream& out_file) + { + out_file << "Bad links list\n"; + for (auto v: complex_vertex_range()) + { + std::vector< Vertex_handle > link_vertices; + // Fill link_vertices + for (auto u: complex_vertex_range()) + if (u != v && find({u,v}) != null_simplex()) + link_vertices.push_back(u); + // Find the dimension + int d = link_dim(link_vertices, link_vertices.begin(),root(),0); + //Siblings* curr_sibl = root(); + bool b = link_is_pseudomanifold(link_vertices,d); + } + } + + private: + int link_dim(std::vector< Vertex_handle >& link_vertices, + typename std::vector< Vertex_handle >::iterator& curr_v, + Siblings* curr_sibl, int curr_d) + { + Simplex_handle sh; + int final_d = curr_d; + typename std::vector< Vertex_handle >::iterator it; + for (it = curr_v; it != link_vertices.end(); ++it) + { + sh = curr_sibl->find(*it); + if (sh != null_simplex()) + { + int d = link_dim(link_vertices, it+1, self_siblings(sh), curr_d+1); + if (d > final_d) + final_d = d; + } + } + return final_d; + } + + // color is false is a (d-1)-dim face, true is a d-dim face + //typedef bool Color; + // graph is an adjacency list + typedef typename boost::adjacency_list Adj_graph; + // map that gives to a certain simplex its node in graph and its dimension + //typedef std::pair Reference; + typedef boost::container::flat_map Graph_map; + typedef boost::graph_traits::vertex_descriptor Vertex_t; + typedef boost::graph_traits::edge_descriptor Edge_t; + /* \brief Verifies if the simplices formed by vertices given by link_vertices + * form a pseudomanifold. + * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional + * faces and edges represent adjacency between them. + */ + bool link_is_pseudomanifold(std::vector< Vertex_handle >& link_vertices, + int dimension) + { + Adj_graph adj_graph; + Graph_map d_map, f_map; // d_map = map for d-dimensional simplices, + // f_map = map for its facets + add_vertices_edges(link_vertices, + link_vertices.begin(), + adj_graph, + d_map, + f_map, + root(), + 0, dimension); + for (auto f_map_it : f_map) + if (boost::out_degree(f_map_it->second, adj_graph) != 2) + return false; + // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices + // What is left is to check the connexity + std::vector components(boost::num_vertices(adj_graph)); + return (boost::connected_components(adj_graph, &components[0]) == 1); + } + + void add_vertices_edges(typeVectorVertex& link_vertices, + typename typeVectorVertex::iterator curr_v, + Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map, + Siblings* curr_sibl, + int curr_d, + int dimension) + { + Simplex_handle sh; + Vertex_t vert; + typename typeVectorVertex::iterator it; + //Add vertices + for (it = curr_v; it != link_vertices.end(); ++it) + { + sh = curr_sibl->find(*it); + if (sh != null_simplex()) + { + if (curr_d == dimension) + { + vert = boost::add_vertex(adj_graph); + f_map.insert(sh,vert); + } + else + { + if (curr_d == dimension-1) + { + vert = boost::add_vertex(adj_graph); + d_map.insert(sh,vert); + } + add_vertices_edges(link_vertices, + it+1, + adj_graph, + d_map, + f_map, + self_siblings(sh), + curr_d+1, dimension); + } + } + } + // Add edges + typename Graph_map::iterator map_it; + for (auto d_map_it : d_map) + { + sh = d_map_it->first; + Vertex_t d_vert = d_map_it->second; + for (auto facet_sh : boundary_simplex_range(sh)) + //for (auto f_map_it : f_map) + { + map_it = f_map.find(facet_sh); + //We must have all the facets in the graph at this point + assert(map_it != f_map.end()); + Vertex_t f_vert = map_it->second; + boost::add_edge(d_vert,f_vert,adj_graph); + } + } + } }; //class Witness_complex -- cgit v1.2.3 From 33149cf3d76704d90526484f82c4d537a91ecd91 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 9 Apr 2015 16:59:17 +0000 Subject: write_bad_links compiles. 信じんない 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/witness@559 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fbd82029f52cf2ed2a8d7379f8b55777f0758a25 --- .../example/witness_complex_from_file.cpp | 6 ++++- .../include/gudhi/Witness_complex.h | 29 ++++++++++++++-------- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 35c00003..3e853f67 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -122,7 +122,7 @@ int main (int argc, char * const argv[]) file_name.erase(0, last_slash_idx + 1); } std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; - write_wl(out_file,WL); + //write_wl(out_file,WL); start = clock(); witnessComplex.witness_complex(WL); // @@ -146,4 +146,8 @@ int main (int argc, char * const argv[]) witnessComplex.st_to_file(ofs); ofs.close(); + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index ef470589..174af950 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -533,18 +533,22 @@ private: std::vector< Vertex_handle > link_vertices; // Fill link_vertices for (auto u: complex_vertex_range()) - if (u != v && find({u,v}) != null_simplex()) - link_vertices.push_back(u); + { + typeVectorVertex edge = {u,v}; + if (u != v && find(edge) != null_simplex()) + link_vertices.push_back(u); + } // Find the dimension int d = link_dim(link_vertices, link_vertices.begin(),root(),0); //Siblings* curr_sibl = root(); - bool b = link_is_pseudomanifold(link_vertices,d); + if (! link_is_pseudomanifold(link_vertices,d)) + out_file << "Bad link at " << v << "\n"; } } private: int link_dim(std::vector< Vertex_handle >& link_vertices, - typename std::vector< Vertex_handle >::iterator& curr_v, + typename std::vector< Vertex_handle >::iterator curr_v, Siblings* curr_sibl, int curr_d) { Simplex_handle sh; @@ -569,9 +573,10 @@ private: typedef typename boost::adjacency_list Adj_graph; // map that gives to a certain simplex its node in graph and its dimension //typedef std::pair Reference; - typedef boost::container::flat_map Graph_map; typedef boost::graph_traits::vertex_descriptor Vertex_t; typedef boost::graph_traits::edge_descriptor Edge_t; + + typedef boost::container::flat_map Graph_map; /* \brief Verifies if the simplices formed by vertices given by link_vertices * form a pseudomanifold. @@ -592,7 +597,7 @@ private: root(), 0, dimension); for (auto f_map_it : f_map) - if (boost::out_degree(f_map_it->second, adj_graph) != 2) + if (boost::out_degree(f_map_it.second, adj_graph) != 2) return false; // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices // What is left is to check the connexity @@ -612,6 +617,8 @@ private: Simplex_handle sh; Vertex_t vert; typename typeVectorVertex::iterator it; + std::pair resPair; + //typename Graph_map::iterator resPair; //Add vertices for (it = curr_v; it != link_vertices.end(); ++it) { @@ -621,14 +628,14 @@ private: if (curr_d == dimension) { vert = boost::add_vertex(adj_graph); - f_map.insert(sh,vert); + resPair = f_map.emplace(sh,vert); } else { if (curr_d == dimension-1) { vert = boost::add_vertex(adj_graph); - d_map.insert(sh,vert); + resPair = d_map.emplace(sh,vert); } add_vertices_edges(link_vertices, it+1, @@ -642,10 +649,10 @@ private: } // Add edges typename Graph_map::iterator map_it; - for (auto d_map_it : d_map) + for (auto d_map_pair : d_map) { - sh = d_map_it->first; - Vertex_t d_vert = d_map_it->second; + sh = d_map_pair.first; + Vertex_t d_vert = d_map_pair.second; for (auto facet_sh : boundary_simplex_range(sh)) //for (auto f_map_it : f_map) { -- cgit v1.2.3 From 001cb626d2ce452e6c258eb326f60544be7c1b3c Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 10 Apr 2015 15:58:47 +0000 Subject: write_bad_links works git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@562 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 70e8ec8512f15f990437b257beb3c67d55e1cb78 --- .../example/witness_complex_from_file.cpp | 2 +- .../include/gudhi/Witness_complex.h | 139 ++++++++++++++++----- 2 files changed, 108 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 3e853f67..c0e062fd 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -110,7 +110,7 @@ int main (int argc, char * const argv[]) // witnessComplex.witness_complex_from_points(point_vector); std::vector > WL; start = clock(); - witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); end = clock(); std::cout << "Landmark choice took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 174af950..c0199d92 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -528,8 +528,31 @@ private: void write_bad_links(std::ofstream& out_file) { out_file << "Bad links list\n"; + std::cout << "Entered write_bad_links\n"; + //typeVectorVertex testv = {9,15,17}; + /* + Mein lieber Gott! + Simplex_handle d1 = root()->members().find(9); + if (d1 != root()->members().end()) + { + Simplex_handle d2 = d1->second.children()->members().find(15); + if (d2 != d1->second.children()->members().end()) + { + Simplex_handle d3 = d2->second.children()->members().find(17); + if (d3 != d2->second.children()->members().end()) + std::cout << "{9,15,17} is there\n"; + else + std::cout << "Everything is jak maje być\n"; + } + else + std::cout << "{9,15} is not there\n"; + } + else + std::cout << "{9} is not there\n"; + */ for (auto v: complex_vertex_range()) { + //std::cout << "Vertex " << v << ":\n"; std::vector< Vertex_handle > link_vertices; // Fill link_vertices for (auto u: complex_vertex_range()) @@ -538,8 +561,14 @@ private: if (u != v && find(edge) != null_simplex()) link_vertices.push_back(u); } + /* + print_vector(link_vertices); + std::cout << "\n"; + */ // Find the dimension - int d = link_dim(link_vertices, link_vertices.begin(),root(),0); + typeVectorVertex empty_simplex = {}; + int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); + //std::cout << " dim " << d << "\n"; //Siblings* curr_sibl = root(); if (! link_is_pseudomanifold(link_vertices,d)) out_file << "Bad link at " << v << "\n"; @@ -547,22 +576,37 @@ private: } private: + int link_dim(std::vector< Vertex_handle >& link_vertices, typename std::vector< Vertex_handle >::iterator curr_v, - Siblings* curr_sibl, int curr_d) + int curr_d, + typeVectorVertex& curr_simplex) { + //std::cout << "Entered link_dim for " << *(curr_v-1) << "\n"; Simplex_handle sh; int final_d = curr_d; typename std::vector< Vertex_handle >::iterator it; for (it = curr_v; it != link_vertices.end(); ++it) { - sh = curr_sibl->find(*it); + curr_simplex.push_back(*it); + /* + std::cout << "Searching for "; + print_vector(curr_simplex); + std::cout << " curr_dim " << curr_d << " final_dim " << final_d; + */ + sh = find(curr_simplex); if (sh != null_simplex()) { - int d = link_dim(link_vertices, it+1, self_siblings(sh), curr_d+1); + //std::cout << " -> " << *it << "\n"; + int d = link_dim(link_vertices, it+1, curr_d+1, curr_simplex); if (d > final_d) final_d = d; } + /* + else + std::cout << "\n"; + */ + curr_simplex.pop_back(); } return final_d; } @@ -587,32 +631,39 @@ private: int dimension) { Adj_graph adj_graph; - Graph_map d_map, f_map; // d_map = map for d-dimensional simplices, + Graph_map d_map, f_map; // d_map = map for d-dimensional simplices // f_map = map for its facets - add_vertices_edges(link_vertices, - link_vertices.begin(), - adj_graph, - d_map, - f_map, - root(), - 0, dimension); + typeVectorVertex empty_vector = {}; + add_vertices(link_vertices, + link_vertices.begin(), + adj_graph, + d_map, + f_map, + empty_vector, + 0, dimension); + //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; + //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; + add_edges(adj_graph, d_map, f_map); for (auto f_map_it : f_map) - if (boost::out_degree(f_map_it.second, adj_graph) != 2) - return false; + { + //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; + if (boost::out_degree(f_map_it.second, adj_graph) != 2) + return false; + } // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices // What is left is to check the connexity std::vector components(boost::num_vertices(adj_graph)); return (boost::connected_components(adj_graph, &components[0]) == 1); } - void add_vertices_edges(typeVectorVertex& link_vertices, - typename typeVectorVertex::iterator curr_v, - Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map, - Siblings* curr_sibl, - int curr_d, - int dimension) + void add_vertices(typeVectorVertex& link_vertices, + typename typeVectorVertex::iterator curr_v, + Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map, + typeVectorVertex& curr_simplex, + int curr_d, + int dimension) { Simplex_handle sh; Vertex_t vert; @@ -620,46 +671,70 @@ private: std::pair resPair; //typename Graph_map::iterator resPair; //Add vertices + //std::cout << "Entered add vertices\n"; for (it = curr_v; it != link_vertices.end(); ++it) { - sh = curr_sibl->find(*it); + curr_simplex.push_back(*it); + /* + std::cout << "Searching for "; + print_vector(curr_simplex); + std::cout << " curr_dim " << curr_d << " d " << dimension << ""; + */ + sh = find(curr_simplex); if (sh != null_simplex()) { + //std::cout << " added\n"; if (curr_d == dimension) { vert = boost::add_vertex(adj_graph); - resPair = f_map.emplace(sh,vert); + resPair = d_map.emplace(sh,vert); } else { if (curr_d == dimension-1) { vert = boost::add_vertex(adj_graph); - resPair = d_map.emplace(sh,vert); + resPair = f_map.emplace(sh,vert); } - add_vertices_edges(link_vertices, - it+1, - adj_graph, - d_map, - f_map, - self_siblings(sh), - curr_d+1, dimension); + add_vertices(link_vertices, + it+1, + adj_graph, + d_map, + f_map, + curr_simplex, + curr_d+1, dimension); } } + /* + else + std::cout << "\n"; + */ + curr_simplex.pop_back(); } + } + + void add_edges(Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map) + { + Simplex_handle sh; // Add edges + //std::cout << "Entered add edges:\n"; typename Graph_map::iterator map_it; for (auto d_map_pair : d_map) { + //std::cout << "*"; sh = d_map_pair.first; Vertex_t d_vert = d_map_pair.second; for (auto facet_sh : boundary_simplex_range(sh)) //for (auto f_map_it : f_map) { + //std::cout << "'"; map_it = f_map.find(facet_sh); //We must have all the facets in the graph at this point assert(map_it != f_map.end()); Vertex_t f_vert = map_it->second; + //std::cout << "Added edge " << sh->first << "-" << map_it->first->first << "\n"; boost::add_edge(d_vert,f_vert,adj_graph); } } -- cgit v1.2.3 From 2d0c9ac7759dde1b0d2e41a147ac1a82bbc0081d Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 14 Apr 2015 16:33:51 +0000 Subject: Ready for testing! git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@565 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4cce2055368e8d9ade18d522d16daeea32acb893 --- .../example/witness_complex_from_file.cpp | 3 +- .../example/witness_complex_from_off.cpp | 44 +++++++++++++++++++++- .../include/gudhi/Witness_complex.h | 26 +++---------- 3 files changed, 50 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index c0e062fd..cf09899b 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -110,7 +110,8 @@ int main (int argc, char * const argv[]) // witnessComplex.witness_complex_from_points(point_vector); std::vector > WL; start = clock(); - witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); end = clock(); std::cout << "Landmark choice took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_from_off.cpp b/src/Witness_complex/example/witness_complex_from_off.cpp index b1d7575a..04d4e601 100644 --- a/src/Witness_complex/example/witness_complex_from_off.cpp +++ b/src/Witness_complex/example/witness_complex_from_off.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include //#include @@ -117,7 +119,8 @@ int main (int argc, char * const argv[]) clock_t start, end; //Construct the Simplex Tree Witness_complex<> witnessComplex; - + + /* std::cout << "Let the carnage begin!\n"; start = clock(); Point_Vector point_vector; @@ -137,4 +140,43 @@ int main (int argc, char * const argv[]) witnessComplex.st_to_file(ofs); ofs.close(); } + */ + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + off_reader_cust(file_name, point_vector); + //std::cout << "Successfully read the points\n"; + witnessComplex.setNbL(nbL); + // witnessComplex.witness_complex_from_points(point_vector); + std::vector > WL; + start = clock(); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + end = clock(); + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + // Write the WL matrix in a file + mkdir("output", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; + //write_wl(out_file,WL); + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index c0199d92..f831ef44 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -530,26 +530,7 @@ private: out_file << "Bad links list\n"; std::cout << "Entered write_bad_links\n"; //typeVectorVertex testv = {9,15,17}; - /* - Mein lieber Gott! - Simplex_handle d1 = root()->members().find(9); - if (d1 != root()->members().end()) - { - Simplex_handle d2 = d1->second.children()->members().find(15); - if (d2 != d1->second.children()->members().end()) - { - Simplex_handle d3 = d2->second.children()->members().find(17); - if (d3 != d2->second.children()->members().end()) - std::cout << "{9,15,17} is there\n"; - else - std::cout << "Everything is jak maje być\n"; - } - else - std::cout << "{9,15} is not there\n"; - } - else - std::cout << "{9} is not there\n"; - */ + int count = 0; for (auto v: complex_vertex_range()) { //std::cout << "Vertex " << v << ":\n"; @@ -571,8 +552,11 @@ private: //std::cout << " dim " << d << "\n"; //Siblings* curr_sibl = root(); if (! link_is_pseudomanifold(link_vertices,d)) - out_file << "Bad link at " << v << "\n"; + count++; + //out_file << "Bad link at " << v << "\n"; } + out_file << "Number of bad links: " << count << "/" << root()->size(); + std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; } private: -- cgit v1.2.3 From 5a60fe7321538379d0910166620c1b8c3655f53a Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 15 Apr 2015 13:22:25 +0000 Subject: Added more detailed output on bad links git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@566 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1c4a4b692f9ce68221ac3f104b10509ccb307231 --- .../include/gudhi/Witness_complex.h | 39 ++++++++++++++++++---- 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index f831ef44..e2dcdf79 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -190,8 +190,12 @@ namespace Gudhi { } std::cout << "k=1, active witnesses: " << active_w.size() << std::endl; //std::cout << "Successfully added edges" << std::endl; + count_good = {0,0}; + count_bad = {0,0}; while (!active_w.empty() && k < nbL ) { + count_good.push_back(0); + count_bad.push_back(0); //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) @@ -530,7 +534,7 @@ private: out_file << "Bad links list\n"; std::cout << "Entered write_bad_links\n"; //typeVectorVertex testv = {9,15,17}; - int count = 0; + //int count = 0; for (auto v: complex_vertex_range()) { //std::cout << "Vertex " << v << ":\n"; @@ -551,16 +555,36 @@ private: int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); //std::cout << " dim " << d << "\n"; //Siblings* curr_sibl = root(); - if (! link_is_pseudomanifold(link_vertices,d)) - count++; + if (link_is_pseudomanifold(link_vertices,d)) + count_good[d]++; //out_file << "Bad link at " << v << "\n"; } - out_file << "Number of bad links: " << count << "/" << root()->size(); - std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; + //out_file << "Number of bad links: " << count << "/" << root()->size(); + //std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; + nc = nbL; + for (int i = 0; i != count_good.size(); i++) + { + out_file << "count_good[" << i << "] = " << count_good[i] << std::endl; + nc -= count_good[i]; + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + } + for (int i = 0; i != count_bad.size(); i++) + { + out_file << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + nc -= count_bad[i]; + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + } + std::cout << "not_connected = " << nc << std::endl; } private: + std::vector count_good; + std::vector count_bad; + int nc; + int link_dim(std::vector< Vertex_handle >& link_vertices, typename std::vector< Vertex_handle >::iterator curr_v, int curr_d, @@ -632,7 +656,10 @@ private: { //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; if (boost::out_degree(f_map_it.second, adj_graph) != 2) - return false; + { + count_bad[dimension]++; + return false; + } } // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices // What is left is to check the connexity -- cgit v1.2.3 From d3cef9245dcff1ea585142ef0b711bb35b6f9338 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 15 Apr 2015 13:48:51 +0000 Subject: Landmark selection: now it's faster git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@567 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 24292a17b98074b7aff4693630829b636ba3d67a --- .../include/gudhi/Witness_complex.h | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index e2dcdf79..c633691b 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -510,22 +510,25 @@ private: //std::cout << "Push't back\n"; j = current_number_of_landmarks; //std::cout << "First half complete\n"; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - // sort the closest landmark vector for every witness - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } //std::cout << "result WL="; print_vvector(WL); //std::cout << "result WLD="; print_vvector(wit_land_dist); //std::cout << "End loop\n"; } } + for (int i = 0; i < nbP; i++) + { + // sort the closest landmark vector for every witness + sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + /* + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + */ + } //std::cout << endl; } -- cgit v1.2.3 From eaedaf52122a397f35fb75df93f83ae9ffdceb7c Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 27 Apr 2015 10:24:05 +0000 Subject: Struggled with CMake... git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@579 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 38b558196806b226cba5e1ef30abb927619bbe33 --- CMakeLists.txt | 2 +- src/Witness_complex/example/CMakeLists.txt | 48 +++++++++++++++------- .../include/gudhi/Witness_complex.h | 42 +++++++++++-------- 3 files changed, 60 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 0684b18e..57cb14d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ find_package(Boost) #find_package(GMPXX) #endif() -#find_package(CGAL) +find_package(CGAL) # Required programs for unitary tests purpose FIND_PROGRAM( LCOV_PATH lcov ) diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 51f7976b..14d23551 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -1,23 +1,41 @@ cmake_minimum_required(VERSION 2.6) project(GUDHIWitnessComplex) +#cmake -DCGAL_DIR=~/GitDrive/CGAL/ ../../.. -add_executable ( simple_witness_complex simple_witness_complex.cpp ) -add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) +#if (CGAL_FOUND) + #message(STATUS "CGAL version: ${CGAL_VERSION}.") + #include( ${CGAL_USE_FILE} ) -add_executable( witness_complex_from_file witness_complex_from_file.cpp ) -add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 ) + #find_package(Eigen3 3.1.0) + #include( ${EIGEN3_USE_FILE} ) -add_executable( witness_complex_from_off witness_complex_from_off.cpp ) + #INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR}) + #INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) + add_executable ( simple_witness_complex simple_witness_complex.cpp ) + add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) -add_executable( witness_complex_from_wl_matrix witness_complex_from_wl_matrix.cpp ) + #add_executable( witness_complex_from_file witness_complex_from_file.cpp ) + #target_link_libraries(witness_complex_from_file ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) + #add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + + add_executable( witness_complex_from_off witness_complex_from_off.cpp ) + + add_executable( witness_complex_from_wl_matrix witness_complex_from_wl_matrix.cpp ) +#endif() # An example with Simplex-tree using CGAL alpha_shapes_3 -#if(GMP_FOUND AND CGAL_FOUND) -# message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") -# message("GMP_LIBRARIES = ${GMP_LIBRARIES}") -# INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) -# INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) -# add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) -# target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY}) -# add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) -#endif() + +include( ${CGAL_USE_FILE} ) +find_package(Eigen3 3.1.0) +if(GMP_FOUND AND CGAL_FOUND) + message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") + message("GMP_LIBRARIES = ${GMP_LIBRARIES}") + message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") + #message("EIGEN3_LIBRARIES = ${EIGEN3_LIBRARIES}") + INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) + INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) + add_executable (witness_complex_from_file witness_complex_from_file.cpp ) + target_link_libraries(witness_complex_from_file ${GMP_LIBRARIES} ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) + add_test(witness_complex_from_file ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) +endif() diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index c633691b..3c030c45 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -38,6 +38,13 @@ #include #include +// Needed for nearest neighbours +//#include +#include +#include +#include + +// Needed for the adjacency graph in bad link search #include #include #include @@ -477,9 +484,9 @@ private: int chosen_landmark = rand()%nbP; double curr_dist; - int j; - int temp_swap_int; - double temp_swap_double; + //int j; + //int temp_swap_int; + //double temp_swap_double; for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) @@ -508,7 +515,7 @@ private: wit_land_dist[i].push_back(curr_dist); WL[i].push_back(current_number_of_landmarks); //std::cout << "Push't back\n"; - j = current_number_of_landmarks; + //j = current_number_of_landmarks; //std::cout << "First half complete\n"; //std::cout << "result WL="; print_vvector(WL); //std::cout << "result WLD="; print_vvector(wit_land_dist); @@ -517,21 +524,24 @@ private: } for (int i = 0; i < nbP; i++) { - // sort the closest landmark vector for every witness sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); - /* - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - */ } //std::cout << endl; } + /** \brief Construct the matrix |W|x(D+1) of D+1 closest landmarks + * where W is the set of witnesses and D is the ambient dimension + */ + template + void nearest_landmarks(Point_Vector &W, std::unordered_set &L, KNearestNeighbours &WL) + { + int D = W[0].size(); + + } + + /** \brief Search and output links around vertices that are not pseudomanifolds + * + */ void write_bad_links(std::ofstream& out_file) { out_file << "Bad links list\n"; @@ -565,14 +575,14 @@ private: //out_file << "Number of bad links: " << count << "/" << root()->size(); //std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; nc = nbL; - for (int i = 0; i != count_good.size(); i++) + for (unsigned int i = 0; i != count_good.size(); i++) { out_file << "count_good[" << i << "] = " << count_good[i] << std::endl; nc -= count_good[i]; if (count_good[i] != 0) std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; } - for (int i = 0; i != count_bad.size(); i++) + for (unsigned int i = 0; i != count_bad.size(); i++) { out_file << "count_bad[" << i << "] = " << count_bad[i] << std::endl; nc -= count_bad[i]; -- cgit v1.2.3 From a99d289c4f37766bc262baa980284fa1a9816d42 Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 27 Apr 2015 16:23:54 +0000 Subject: Added the file for knn landmarks (no CGAL include yet). New algorithm for landmark selection: now 10 times faster! git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@580 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9de270bd67ac33fd1079de7692dd8974441db606 --- src/Witness_complex/example/CMakeLists.txt | 10 +- .../example/witness_complex_from_file.cpp | 4 +- .../example/witness_complex_from_off.cpp | 4 +- .../example/witness_complex_knn_landmarks.cpp | 161 +++++++++++++++++++ .../include/gudhi/Witness_complex.h | 176 +++++++++++++++------ 5 files changed, 303 insertions(+), 52 deletions(-) create mode 100644 src/Witness_complex/example/witness_complex_knn_landmarks.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 14d23551..fa594de7 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -14,9 +14,9 @@ project(GUDHIWitnessComplex) add_executable ( simple_witness_complex simple_witness_complex.cpp ) add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) - #add_executable( witness_complex_from_file witness_complex_from_file.cpp ) + add_executable( witness_complex_from_file witness_complex_from_file.cpp ) #target_link_libraries(witness_complex_from_file ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) - #add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) add_executable( witness_complex_from_off witness_complex_from_off.cpp ) @@ -35,7 +35,7 @@ if(GMP_FOUND AND CGAL_FOUND) INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) - add_executable (witness_complex_from_file witness_complex_from_file.cpp ) - target_link_libraries(witness_complex_from_file ${GMP_LIBRARIES} ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) - add_test(witness_complex_from_file ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable (witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) + target_link_libraries(witness_complex_knn_landmarks ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) + add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) endif() diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index cf09899b..b842574b 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -109,9 +109,11 @@ int main (int argc, char * const argv[]) witnessComplex.setNbL(nbL); // witnessComplex.witness_complex_from_points(point_vector); std::vector > WL; + std::set L; start = clock(); //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), L); + witnessComplex.nearest_landmarks(point_vector,L,WL); end = clock(); std::cout << "Landmark choice took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_from_off.cpp b/src/Witness_complex/example/witness_complex_from_off.cpp index 04d4e601..948f09a8 100644 --- a/src/Witness_complex/example/witness_complex_from_off.cpp +++ b/src/Witness_complex/example/witness_complex_from_off.cpp @@ -148,9 +148,11 @@ int main (int argc, char * const argv[]) witnessComplex.setNbL(nbL); // witnessComplex.witness_complex_from_points(point_vector); std::vector > WL; + std::set L; start = clock(); //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), L); + witnessComplex.nearest_landmarks(point_vector,L,WL); end = clock(); std::cout << "Landmark choice took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp new file mode 100644 index 00000000..2003f218 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp @@ -0,0 +1,161 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +//#include +//#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef std::vector< std::vector > Point_Vector; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + if (point.size() != 1) + points.push_back(point); + } + in_file.close(); +} + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + /* + boost::filesystem::path p; + + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + + clock_t start, end; + //Construct the Simplex Tree + Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + read_points_cust(file_name, point_vector); + //std::cout << "Successfully read the points\n"; + witnessComplex.setNbL(nbL); + // witnessComplex.witness_complex_from_points(point_vector); + std::vector > WL; + std::set L; + int nbP = point_vector.size(); + start = clock(); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + witnessComplex.landmark_choice_by_random_points(point_vector, nbP, L); + witnessComplex.nearest_landmarks(point_vector,L,WL); + end = clock(); + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + // Write the WL matrix in a file + mkdir("output", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; + //write_wl(out_file,WL); + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + /* + char buffer[100]; + int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + */ + + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); +} diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 3c030c45..2ccaa416 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -32,7 +32,8 @@ #include "gudhi/Simplex_tree.h" #include #include -#include +#include +#include #include #include #include @@ -40,9 +41,9 @@ // Needed for nearest neighbours //#include -#include -#include -#include +//#include +//#include +//#include // Needed for the adjacency graph in bad link search #include @@ -233,12 +234,12 @@ namespace Gudhi { * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and * density must be set to the right value for DENSITY_STRATEGY */ - void witness_complex_from_points(Point_Vector point_vector) - { - std::vector > WL; - landmark_choice_by_random_points(point_vector, point_vector.size(), WL); - witness_complex(WL); - } + // void witness_complex_from_points(Point_Vector point_vector) + // { + // std::vector > WL; + // landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + // witness_complex(WL); + // } private: @@ -468,75 +469,160 @@ private: * */ - template - void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + // template + // void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + // { + // std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + // //std::cout << "W="; print_vvector(W); + // std::unordered_set< int > chosen_landmarks; // landmark set + + // Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + + // WL = KNearestNeighbours(nbP,std::vector()); + // int current_number_of_landmarks=0; // counter for landmarks + + // srand(24660); + // int chosen_landmark = rand()%nbP; + // double curr_dist; + + // //int j; + // //int temp_swap_int; + // //double temp_swap_double; + + + // for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + // { + // while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) + // { + // srand((int)clock()); + // chosen_landmark = rand()% nbP; + // //std::cout << chosen_landmark << "\n"; + // } + // chosen_landmarks.insert(chosen_landmark); + // //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + // //std::cout << "WL="; print_vvector(WL); + // //std::cout << "WLD="; print_vvector(wit_land_dist); + // //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + // for (auto v: WL) + // v.push_back(current_number_of_landmarks); + // for (int i = 0; i < nbP; ++i) + // { + // // iteration on points in W. update of distance vectors + + // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + // //std::cout << "The problem is not in distance function\n"; + // wit_land_dist[i].push_back(curr_dist); + // WL[i].push_back(current_number_of_landmarks); + // //std::cout << "Push't back\n"; + // //j = current_number_of_landmarks; + // //std::cout << "First half complete\n"; + // //std::cout << "result WL="; print_vvector(WL); + // //std::cout << "result WLD="; print_vvector(wit_land_dist); + // //std::cout << "End loop\n"; + // } + // } + // for (int i = 0; i < nbP; i++) + // { + // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + // } + // //std::cout << endl; + // } + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * + */ + + // template + void landmark_choice_by_random_points(Point_Vector &W, int nbP, std::set &L) { std::cout << "Enter landmark_choice_by_random_points "<< std::endl; //std::cout << "W="; print_vvector(W); - std::unordered_set< int > chosen_landmarks; // landmark set + //std::unordered_set< int > chosen_landmarks; // landmark set Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - WL = KNearestNeighbours(nbP,std::vector()); + //WL = KNearestNeighbours(nbP,std::vector()); int current_number_of_landmarks=0; // counter for landmarks srand(24660); int chosen_landmark = rand()%nbP; - double curr_dist; - + //double curr_dist; //int j; //int temp_swap_int; - //double temp_swap_double; - - + //double temp_swap_double; for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) { - while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) + while (L.find(chosen_landmark) != L.end()) { srand((int)clock()); chosen_landmark = rand()% nbP; //std::cout << chosen_landmark << "\n"; } - chosen_landmarks.insert(chosen_landmark); + L.insert(chosen_landmark); //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; //std::cout << "WL="; print_vvector(WL); //std::cout << "WLD="; print_vvector(wit_land_dist); //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - for (auto v: WL) - v.push_back(current_number_of_landmarks); - for (int i = 0; i < nbP; ++i) - { - // iteration on points in W. update of distance vectors + // for (auto v: WL) + // v.push_back(current_number_of_landmarks); + // for (int i = 0; i < nbP; ++i) + // { + // // iteration on points in W. update of distance vectors - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - //std::cout << "The problem is not in distance function\n"; - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; - //j = current_number_of_landmarks; - //std::cout << "First half complete\n"; - //std::cout << "result WL="; print_vvector(WL); - //std::cout << "result WLD="; print_vvector(wit_land_dist); - //std::cout << "End loop\n"; - } - } - for (int i = 0; i < nbP; i++) - { - sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + // //std::cout << "The problem is not in distance function\n"; + // wit_land_dist[i].push_back(curr_dist); + // WL[i].push_back(current_number_of_landmarks); + // //std::cout << "Push't back\n"; + // //j = current_number_of_landmarks; + // //std::cout << "First half complete\n"; + // //std::cout << "result WL="; print_vvector(WL); + // //std::cout << "result WLD="; print_vvector(wit_land_dist); + // //std::cout << "End loop\n"; + // } } + // for (int i = 0; i < nbP; i++) + // { + // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + // } //std::cout << endl; } + /** \brief Construct the matrix |W|x(D+1) of D+1 closest landmarks * where W is the set of witnesses and D is the ambient dimension */ template - void nearest_landmarks(Point_Vector &W, std::unordered_set &L, KNearestNeighbours &WL) + void nearest_landmarks(Point_Vector &W, std::set &L, KNearestNeighbours &WL) { int D = W[0].size(); - + int nbP = W.size(); + WL = KNearestNeighbours(nbP,std::vector()); + typedef std::pair dist_i; + typedef bool (*comp)(dist_i,dist_i); + for (int W_i = 0; W_i < nbP; W_i++) + { + //std::cout << "<<<<<<<<<<<<<<" << W_i <<"\n"; + std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); + std::set::iterator L_it; + int L_i; + for (L_it = L.begin(), L_i=0; L_it != L.end(); L_it++, L_i++) + { + dist_i dist = std::make_pair(euclidean_distance(W[W_i],W[*L_it]), L_i); + l_heap.push(dist); + } + for (int i = 0; i < D+1; i++) + { + dist_i dist = l_heap.top(); + WL[W_i].push_back(dist.second); + //std::cout << dist.first << " " << dist.second << std::endl; + l_heap.pop(); + } + } } /** \brief Search and output links around vertices that are not pseudomanifolds -- cgit v1.2.3 From 42be4074aa20b30c343867de156f3c6d7f96cf81 Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 27 Apr 2015 16:56:40 +0000 Subject: Added a CGAL include git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@581 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4f747215a4a6ac6bb0ca6f86b140f0bd8c4f0c14 --- src/Witness_complex/example/witness_complex_from_file.cpp | 2 +- src/Witness_complex/example/witness_complex_knn_landmarks.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index b842574b..01172fbe 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -115,7 +115,7 @@ int main (int argc, char * const argv[]) witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), L); witnessComplex.nearest_landmarks(point_vector,L,WL); end = clock(); - std::cout << "Landmark choice took " + std::cout << "Landmark choice for " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; // Write the WL matrix in a file mkdir("output", S_IRWXU); diff --git a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp index 2003f218..5580c0eb 100644 --- a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp +++ b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp @@ -34,7 +34,7 @@ //#include //#include -//#include +#include #include using namespace Gudhi; -- cgit v1.2.3 From e1caa847d6c0de60812a5246437e7702605cb7e8 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 28 Apr 2015 07:21:41 +0000 Subject: compile fixed git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@582 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: fb750b7fb681685a59ddad6c3bbb66970379de3d --- src/Witness_complex/example/CMakeLists.txt | 52 ++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index fa594de7..315ffc36 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -25,17 +25,43 @@ project(GUDHIWitnessComplex) # An example with Simplex-tree using CGAL alpha_shapes_3 -include( ${CGAL_USE_FILE} ) -find_package(Eigen3 3.1.0) -if(GMP_FOUND AND CGAL_FOUND) - message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") - message("GMP_LIBRARIES = ${GMP_LIBRARIES}") - message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") - #message("EIGEN3_LIBRARIES = ${EIGEN3_LIBRARIES}") - INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) - INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) - INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) - add_executable (witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) - target_link_libraries(witness_complex_knn_landmarks ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) - add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) +#find_package(Eigen3 3.1.0) +#if(GMP_FOUND AND CGAL_FOUND) +# message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") +# message("GMP_LIBRARIES = ${GMP_LIBRARIES}") +# message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") +# #message("EIGEN3_LIBRARIES = ${EIGEN3_LIBRARIES}") +# INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) +# INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) +# INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) +# add_executable (witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) +# target_link_libraries(witness_complex_knn_landmarks ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) +# add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) +#endif() + +# need CGAL 4.6 +# cmake -DCGAL_DIR=~/workspace/CGAL-4.6-beta1 ../../.. +if(CGAL_FOUND) + if (NOT CGAL_VERSION VERSION_LESS 4.6.0) + message(STATUS "CGAL version: ${CGAL_VERSION}.") + + include( ${CGAL_USE_FILE} ) + + find_package(Eigen3 3.1.0) + if (EIGEN3_FOUND) + message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") + include( ${EIGEN3_USE_FILE} ) + include_directories (BEFORE "../../include") + + add_executable ( witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) + target_link_libraries(witness_complex_knn_landmarks ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + + else() + message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") + endif() + else() + message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") + endif () endif() + -- cgit v1.2.3 From d8984eab8b054dbdaa2d2ada040f6b1927594bef Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 6 May 2015 13:51:36 +0000 Subject: Kd tree landmark choice worked git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@586 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 59d672bab0c8d8bad0a39774a58a50c87d573604 --- .../example/witness_complex_from_file.cpp | 2 +- .../example/witness_complex_knn_landmarks.cpp | 132 +++++++++++++++++++-- .../include/gudhi/Witness_complex.h | 21 ++-- 3 files changed, 134 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 01172fbe..70c81528 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -125,7 +125,7 @@ int main (int argc, char * const argv[]) file_name.erase(0, last_slash_idx + 1); } std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; - //write_wl(out_file,WL); + write_wl(out_file,WL); start = clock(); witnessComplex.witness_complex(WL); // diff --git a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp index 5580c0eb..e4a1c324 100644 --- a/src/Witness_complex/example/witness_complex_knn_landmarks.cpp +++ b/src/Witness_complex/example/witness_complex_knn_landmarks.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -34,25 +35,51 @@ //#include //#include +#include +#include +#include +#include #include -#include +#include + +#include +#include +#include +#include using namespace Gudhi; //using namespace boost::filesystem; typedef std::vector< Vertex_handle > typeVectorVertex; -typedef std::vector< std::vector > Point_Vector; + //typedef std::pair typeSimplex; //typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef std::vector Point_Vector; /** * \brief Customized version of read_points * which takes into account a possible nbP first line * */ inline void -read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +read_points_cust ( std::string file_name , Point_Vector & points) { std::ifstream in_file (file_name.c_str(),std::ios::in); if(!in_file.is_open()) @@ -67,11 +94,96 @@ read_points_cust ( std::string file_name , std::vector< std::vector< double > > std::vector< double > point; std::istringstream iss( line ); while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); if (point.size() != 1) - points.push_back(point); + points.push_back(p); + } + in_file.close(); +} + +/* +void read_points_to_tree (std::string file_name, Tree& tree) +{ + //I assume here that tree is empty + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector coords; + std::istringstream iss( line ); + while(iss >> x) { coords.push_back(x); } + if (coords.size() != 1) + { + Point_d point(coords.begin(), coords.end()); + tree.insert(point); + } } in_file.close(); } +*/ + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice_to_tree(Point_Vector &W, int nbP, Point_etiquette_map &L_i, int nbL, std::vector< std::vector > &WL) +{ + std::cout << "Enter landmark choice to kd tree\n"; + std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + srand(24660); + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + chosen_landmark = rand()%nbP; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits((Point_d*)&(landmarks[0]))); + /*} + + +void d_nearest_landmarks(Point_Vector &W, Tree &L, Point_etiquette_map &L_i, std::vector< std::vector > &WL) +{*/ + std::cout << "Enter (D+1) nearest landmarks\n"; + std::cout << "Size of the tree is " << L.size() << std::endl; +//int nbP = W.size(); + int D = W[0].size(); + for (int i = 0; i < nbP; i++) + { + //std::cout << "Entered witness number " << i << std::endl; + Point_d& w = W[i]; + //std::cout << "Safely constructed a point\n"; + //Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter>((Point_d*)&(landmarks[0])) ); + //std::cout << "Safely found nearest landmarks\n"; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + //Point_etiquette_map::iterator itm = L_i.find(it->first); + //assert(itm != L_i.end()); + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + WL[i].push_back(it->first); + //std::cout << i << " " << it->first << ": " << it->second << std::endl; + } + } +} + void write_wl( std::string file_name, std::vector< std::vector > & WL) { @@ -112,13 +224,15 @@ int main (int argc, char * const argv[]) //std::cout << "Successfully read the points\n"; witnessComplex.setNbL(nbL); // witnessComplex.witness_complex_from_points(point_vector); - std::vector > WL; - std::set L; int nbP = point_vector.size(); + std::vector > WL(nbP); + //std::set L; + Tree L; + Point_etiquette_map L_i; start = clock(); //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - witnessComplex.landmark_choice_by_random_points(point_vector, nbP, L); - witnessComplex.nearest_landmarks(point_vector,L,WL); + landmark_choice_to_tree(point_vector, nbP, L_i, nbL, WL); + //d_nearest_landmarks(point_vector, L, L_i, WL); end = clock(); std::cout << "Landmark choice took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; @@ -130,7 +244,7 @@ int main (int argc, char * const argv[]) file_name.erase(0, last_slash_idx + 1); } std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; - //write_wl(out_file,WL); + write_wl(out_file,WL); start = clock(); witnessComplex.witness_complex(WL); // diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 2ccaa416..69521e6a 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -284,29 +284,27 @@ private: private: void sc_to_file(std::ofstream& out_file, Siblings * sibl) { - if (sibl == NULL) - out_file << "&"; - else - children_to_file(out_file, sibl->members_); + assert(sibl); + children_to_file(out_file, sibl->members_); } - void children_to_file(std::ofstream& out_file, Dictionary map) + void children_to_file(std::ofstream& out_file, Dictionary& map) { - out_file << "("; + out_file << "(" << std::flush; if (!map.empty()) { - out_file << map.begin()->first; + out_file << map.begin()->first << std::flush; if (has_children(map.begin())) sc_to_file(out_file, map.begin()->second.children()); typename Dictionary::iterator it; for (it = map.begin()+1; it != map.end(); ++it) { - out_file << "," << it->first; + out_file << "," << it->first << std::flush; if (has_children(it)) sc_to_file(out_file, it->second.children()); } } - out_file << ")"; + out_file << ")" << std::flush; } @@ -541,7 +539,7 @@ private: //std::cout << "W="; print_vvector(W); //std::unordered_set< int > chosen_landmarks; // landmark set - Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + //Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks //WL = KNearestNeighbours(nbP,std::vector()); int current_number_of_landmarks=0; // counter for landmarks @@ -618,7 +616,8 @@ private: for (int i = 0; i < D+1; i++) { dist_i dist = l_heap.top(); - WL[W_i].push_back(dist.second); + WL[W_i].push_back(dist.second); + //WL[W_i].insert(WL[W_i].begin(),dist.second); //std::cout << dist.first << " " << dist.second << std::endl; l_heap.pop(); } -- cgit v1.2.3 From bc9d9bdaec5e4ca1604cca2a5251031f25c64b0f Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 20 May 2015 15:16:13 +0000 Subject: Added perturbation witness complex construction git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@590 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5c478d127e0fefa8696be5ca72ab89efa2e2dfc6 --- src/Witness_complex/example/CMakeLists.txt | 29 +- .../example/witness_complex_perturbations.cpp | 377 +++++++++++++++++++++ .../include/gudhi/Witness_complex.h | 28 +- 3 files changed, 431 insertions(+), 3 deletions(-) create mode 100644 src/Witness_complex/example/witness_complex_perturbations.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 315ffc36..a3e7b3f5 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -56,12 +56,37 @@ if(CGAL_FOUND) add_executable ( witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) target_link_libraries(witness_complex_knn_landmarks ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - + #add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) + #target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + #add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() - message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") + message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() else() message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") endif () endif() +if(CGAL_FOUND) + if (NOT CGAL_VERSION VERSION_LESS 4.6.0) + message(STATUS "CGAL version: ${CGAL_VERSION}.") + include( ${CGAL_USE_FILE} ) + + find_package(Eigen3 3.1.0) + if (EIGEN3_FOUND) + message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") + include( ${EIGEN3_USE_FILE} ) + include_directories (BEFORE "../../include") + add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) + target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( range_queries range_queries.cpp ) + target_link_libraries(range_queries ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(range_queries ${CMAKE_CURRENT_BINARY_DIR}/range_queries ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + else() + message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") + endif() + else() + message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") + endif () +endif() diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp new file mode 100644 index 00000000..afb42807 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -0,0 +1,377 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +typedef CGAL::Euclidean_distance Euclidean_distance; +//typedef K::Equal_d Equal_d; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +/* +void read_points_to_tree (std::string file_name, Tree& tree) +{ + //I assume here that tree is empty + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector coords; + std::istringstream iss( line ); + while(iss >> x) { coords.push_back(x); } + if (coords.size() != 1) + { + Point_d point(coords.begin(), coords.end()); + tree.insert(point); + } + } + in_file.close(); +} +*/ + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + srand(24660); + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + chosen_landmark = rand()%nbP; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + + +int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Constructing a WL matrix + int nbP = W.size(); + int nbL = landmarks.size(); + //Point_Vector landmarks_ = landmarks; + Euclidean_distance ed; + //Equal_d ed; + FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); + //FT lambda = 0.1;//Euclidean_distance(); + std::vector< std::vector > WL(nbP); + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits(&(landmarks[0]))); + /*Tree2 L2(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits(&(landmarks[0]))); + */ + std::cout << "Enter (D+1) nearest landmarks\n"; + //std::cout << "Size of the tree is " << L.size() << std::endl; + int D = W[0].size(); + for (int i = 0; i < nbP; i++) + { + //std::cout << "Entered witness number " << i << std::endl; + Point_d& w = W[i]; + //std::cout << "Safely constructed a point\n"; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter>(&(landmarks[0])) ); + //std::cout << "Safely found nearest landmarks\n"; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + //Point_etiquette_map::iterator itm = L_i.find(it->first); + //assert(itm != L_i.end()); + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + WL[i].push_back(it->first); + //std::cout << "ITFIRST " << it->first << std::endl; + //std::cout << i << " " << it->first << ": " << it->second << std::endl; + } + if (i == landmarks_ind[WL[i][0]]) + { + //std::cout << "'"; + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + //std::cout << "\n"; + /* + std::string out_file = "wl_result"; + write_wl(out_file,WL); + */ + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + std::cout << "Bad links around "; + for (auto u: witnessComplex.complex_vertex_range()) + if (!witnessComplex.has_good_link(u)) + { + //std::cout << "Landmark " << u << " start!" << std::endl; + //perturbL.insert(u); + count_badlinks++; + std::cout << u << " "; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*2, 0, STraits(&(landmarks[0]))); + L.search(std::insert_iterator>(perturbL,perturbL.begin()),fs); + //L.search(std::inserter(perturbL,perturbL.begin()),fs); + //L.search(std::ostream_iterator(std::cout,"\n"),fs); + //std::cout << "PerturbL size is " << perturbL.size() << std::endl; + } + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; + //*********************** Perturb bad link landmarks + + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/2); + //std::cout << landmarks[u] << std::endl; + + std::vector point; + for (int i = 0; i < D; i++) + { + point.push_back(W[landmarks_ind[u]][i] + (*rp)[i]); + } + landmarks[u] = Point_d(point); + //std::cout << landmarks[u] << std::endl; + } + + //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl; + std::cout << "lambda=" << lambda << std::endl; + // Write the WL matrix in a file + /* + mkdir("output", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + */ + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + /* + boost::filesystem::path p; + + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + + //clock_t start, end; + //Construct the Simplex Tree + //Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + read_points_cust(file_name, point_vector); + //std::cout << "Successfully read the points\n"; + //witnessComplex.setNbL(nbL); + // witnessComplex.witness_complex_from_points(point_vector); + int nbP = point_vector.size(); + //std::vector > WL(nbP); + //std::set L; + Point_Vector L; + std::vector chosen_landmarks; + //Point_etiquette_map L_i; + //start = clock(); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + int bl = 1; + for (int i = 0; bl != 0; i++) + { + std::cout << "========== Start iteration " << i << " ========\n"; + bl = landmark_perturbation(point_vector, L, chosen_landmarks); + } + //end = clock(); + + /* + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + */ + + /* + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); + */ +} diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 69521e6a..bb553347 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -192,6 +192,7 @@ namespace Gudhi { } Simplex_handle sh; vv = {u,v}; + //if (u==v) std::cout << "Bazzinga!\n"; sh = (root()->find(u))->second.children()->find(v); active_w.push_back(i); } @@ -200,7 +201,8 @@ namespace Gudhi { //std::cout << "Successfully added edges" << std::endl; count_good = {0,0}; count_bad = {0,0}; - while (!active_w.empty() && k < nbL ) + int D = knn[0].size(); + while (!active_w.empty() && k < D ) { count_good.push_back(0); count_bad.push_back(0); @@ -623,6 +625,30 @@ private: } } } + + /** \brief Returns true if the link is good + */ + bool has_good_link(Vertex_handle v) + { + std::vector< Vertex_handle > link_vertices; + // Fill link_vertices + for (auto u: complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u != v && find(edge) != null_simplex()) + link_vertices.push_back(u); + } + /* + print_vector(link_vertices); + std::cout << "\n"; + */ + // Find the dimension + typeVectorVertex empty_simplex = {}; + int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); + //std::cout << " dim " << d << "\n"; + //Siblings* curr_sibl = root(); + return (link_is_pseudomanifold(link_vertices,d)); + } /** \brief Search and output links around vertices that are not pseudomanifolds * -- cgit v1.2.3 From c0795bfcb30428f57ce51e939ec7d9f345a39f1b Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 20 May 2015 15:24:42 +0000 Subject: Removed range_queries from cmakelists git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@591 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e2c78757c05ccc827e53f377449ae247edc79649 --- src/Witness_complex/example/CMakeLists.txt | 6 +- .../example/witness_complex_flat_torus.cpp | 377 +++++++++++++++++++++ 2 files changed, 380 insertions(+), 3 deletions(-) create mode 100644 src/Witness_complex/example/witness_complex_flat_torus.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index a3e7b3f5..49c8c0bb 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -80,9 +80,9 @@ if(CGAL_FOUND) add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( range_queries range_queries.cpp ) - target_link_libraries(range_queries ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(range_queries ${CMAKE_CURRENT_BINARY_DIR}/range_queries ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + #add_executable ( range_queries range_queries.cpp ) + #target_link_libraries(range_queries ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + #add_test(range_queries ${CMAKE_CURRENT_BINARY_DIR}/range_queries ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp new file mode 100644 index 00000000..afb42807 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -0,0 +1,377 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +typedef CGAL::Euclidean_distance Euclidean_distance; +//typedef K::Equal_d Equal_d; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +/* +void read_points_to_tree (std::string file_name, Tree& tree) +{ + //I assume here that tree is empty + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector coords; + std::istringstream iss( line ); + while(iss >> x) { coords.push_back(x); } + if (coords.size() != 1) + { + Point_d point(coords.begin(), coords.end()); + tree.insert(point); + } + } + in_file.close(); +} +*/ + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + srand(24660); + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + chosen_landmark = rand()%nbP; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + + +int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Constructing a WL matrix + int nbP = W.size(); + int nbL = landmarks.size(); + //Point_Vector landmarks_ = landmarks; + Euclidean_distance ed; + //Equal_d ed; + FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); + //FT lambda = 0.1;//Euclidean_distance(); + std::vector< std::vector > WL(nbP); + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits(&(landmarks[0]))); + /*Tree2 L2(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits(&(landmarks[0]))); + */ + std::cout << "Enter (D+1) nearest landmarks\n"; + //std::cout << "Size of the tree is " << L.size() << std::endl; + int D = W[0].size(); + for (int i = 0; i < nbP; i++) + { + //std::cout << "Entered witness number " << i << std::endl; + Point_d& w = W[i]; + //std::cout << "Safely constructed a point\n"; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter>(&(landmarks[0])) ); + //std::cout << "Safely found nearest landmarks\n"; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + //Point_etiquette_map::iterator itm = L_i.find(it->first); + //assert(itm != L_i.end()); + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + WL[i].push_back(it->first); + //std::cout << "ITFIRST " << it->first << std::endl; + //std::cout << i << " " << it->first << ": " << it->second << std::endl; + } + if (i == landmarks_ind[WL[i][0]]) + { + //std::cout << "'"; + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + //std::cout << "\n"; + /* + std::string out_file = "wl_result"; + write_wl(out_file,WL); + */ + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + std::cout << "Bad links around "; + for (auto u: witnessComplex.complex_vertex_range()) + if (!witnessComplex.has_good_link(u)) + { + //std::cout << "Landmark " << u << " start!" << std::endl; + //perturbL.insert(u); + count_badlinks++; + std::cout << u << " "; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*2, 0, STraits(&(landmarks[0]))); + L.search(std::insert_iterator>(perturbL,perturbL.begin()),fs); + //L.search(std::inserter(perturbL,perturbL.begin()),fs); + //L.search(std::ostream_iterator(std::cout,"\n"),fs); + //std::cout << "PerturbL size is " << perturbL.size() << std::endl; + } + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; + //*********************** Perturb bad link landmarks + + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/2); + //std::cout << landmarks[u] << std::endl; + + std::vector point; + for (int i = 0; i < D; i++) + { + point.push_back(W[landmarks_ind[u]][i] + (*rp)[i]); + } + landmarks[u] = Point_d(point); + //std::cout << landmarks[u] << std::endl; + } + + //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl; + std::cout << "lambda=" << lambda << std::endl; + // Write the WL matrix in a file + /* + mkdir("output", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + */ + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + /* + boost::filesystem::path p; + + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + + //clock_t start, end; + //Construct the Simplex Tree + //Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + read_points_cust(file_name, point_vector); + //std::cout << "Successfully read the points\n"; + //witnessComplex.setNbL(nbL); + // witnessComplex.witness_complex_from_points(point_vector); + int nbP = point_vector.size(); + //std::vector > WL(nbP); + //std::set L; + Point_Vector L; + std::vector chosen_landmarks; + //Point_etiquette_map L_i; + //start = clock(); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + int bl = 1; + for (int i = 0; bl != 0; i++) + { + std::cout << "========== Start iteration " << i << " ========\n"; + bl = landmark_perturbation(point_vector, L, chosen_landmarks); + } + //end = clock(); + + /* + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + */ + + /* + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); + */ +} -- cgit v1.2.3 From da5114d23e2a42e45805773f60520059c7f8cf22 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 26 May 2015 08:51:43 +0000 Subject: witness complex in a torus git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@594 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: af4ef3a1233aec08d21f635bb3606cfc5d19c4d7 --- src/Witness_complex/example/CMakeLists.txt | 6 +- .../example/witness_complex_flat_torus.cpp | 303 ++++++++++++++++++--- .../example/witness_complex_perturbations.cpp | 4 +- 3 files changed, 270 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 49c8c0bb..e3768138 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -80,9 +80,9 @@ if(CGAL_FOUND) add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - #add_executable ( range_queries range_queries.cpp ) - #target_link_libraries(range_queries ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - #add_test(range_queries ${CMAKE_CURRENT_BINARY_DIR}/range_queries ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_flat_torus witness_complex_flat_torus.cpp ) + target_link_libraries(witness_complex_flat_torus ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_flat_torus ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_flat_torus ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index afb42807..c1fb5082 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,8 @@ #include #include #include -#include +#include + #include #include @@ -60,11 +62,6 @@ using namespace Gudhi; //using namespace boost::filesystem; -typedef std::vector< Vertex_handle > typeVectorVertex; - -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - typedef CGAL::Epick_d K; typedef K::FT FT; typedef K::Point_d Point_d; @@ -72,10 +69,197 @@ typedef CGAL::Search_traits< FT, Point_d, typename K::Cartesian_const_iterator_d, typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + +/** + * \brief Class of distance in a flat torus in dimaension D + * + */ +class Torus_distance : public Euclidean_distance { + +public: + typedef FT FT; + typedef Point_d Point_d; + typedef Point_d Query_item; + typedef typename CGAL::Dynamic_dimension_tag D; + + FT transformed_distance(Query_item q, Point_d p) const + { + FT distance = FT(0); + FT coord = FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1), pit = construct_it(p); + for(; qit != qe; qit++, pit++) + { + coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit))); + if (coord*coord <= (1-coord)*(1-coord)) + distance += coord*coord; + else + distance += (1-coord)*(1-coord); + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (1 - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (1 - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (1 - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + } + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (1 - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + } + } + }; + return distance; + } + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (FT(1) <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-FT(1))/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + else + if ((FT(1)-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + return distance; + } + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (FT(1) <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-FT(1))/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = r.max_coord(i)-(*qit); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + } + else + { + dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i))); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + else + if ((FT(1)-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit))); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + + } + else + { + dists[i] = (*qit)-r.min_coord(i); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + } + return distance; + } + + inline FT transformed_distance(FT d) const { + return d*d; + } + + inline FT inverse_of_transformed_distance(FT d) const { + return sqrt(d); + } + +}; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + typedef CGAL::Search_traits_adapter< std::ptrdiff_t, Point_d*, Traits_base> STraits; //typedef K TreeTraits; -typedef CGAL::Orthogonal_k_neighbor_search K_neighbor_search; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; typedef K_neighbor_search::Tree Tree; typedef K_neighbor_search::Distance Distance; typedef K_neighbor_search::iterator KNS_iterator; @@ -87,9 +271,12 @@ typedef CGAL::Fuzzy_sphere Fuzzy_sphere; typedef std::vector Point_Vector; -typedef CGAL::Euclidean_distance Euclidean_distance; //typedef K::Equal_d Equal_d; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; typedef CGAL::Random_points_in_ball_d Random_point_iterator; + + + /** * \brief Customized version of read_points * which takes into account a possible nbP first line @@ -118,6 +305,20 @@ read_points_cust ( std::string file_name , Point_Vector & points) in_file.close(); } +void generate_points_grid(Point_Vector& W, int width, int D) +{ + +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + /* void read_points_to_tree (std::string file_name, Tree& tree) { @@ -169,12 +370,14 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, int chosen_landmark; //std::pair res = std::make_pair(L_i.begin(),false); Point_d* p; - srand(24660); + CGAL::Random rand; for (int i = 0; i < nbL; i++) { // while (!res.second) // { - chosen_landmark = rand()%nbP; + chosen_landmark = rand.get_int(0,nbP); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; //L_i.emplace(chosen_landmark,i); // } @@ -191,9 +394,11 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< int nbP = W.size(); int nbL = landmarks.size(); //Point_Vector landmarks_ = landmarks; - Euclidean_distance ed; + Torus_distance ed; //Equal_d ed; + //Point_d p1(std::vector({0.8,0.8})), p2(std::vector({0.1,0.1})); FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); + //std::cout << "Lambda=" << lambda << std::endl; //FT lambda = 0.1;//Euclidean_distance(); std::vector< std::vector > WL(nbP); Tree L(boost::counting_iterator(0), @@ -215,7 +420,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //std::cout << "Safely constructed a point\n"; ////Search D+1 nearest neighbours from the tree of landmarks L K_neighbor_search search(L, w, D+1, FT(0), true, - CGAL::Distance_adapter>(&(landmarks[0])) ); + //CGAL::Distance_adapter(&(landmarks[0])) ); + CGAL::Distance_adapter(&(landmarks[0])) ); //std::cout << "Safely found nearest landmarks\n"; for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) { @@ -236,10 +442,10 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< } } //std::cout << "\n"; - /* + std::string out_file = "wl_result"; write_wl(out_file,WL); - */ + //******************** Constructng a witness complex std::cout << "Entered witness complex construction\n"; Witness_complex<> witnessComplex; @@ -249,16 +455,16 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::cout << "Entered bad links\n"; std::set< int > perturbL; int count_badlinks = 0; - std::cout << "Bad links around "; + //std::cout << "Bad links around "; for (auto u: witnessComplex.complex_vertex_range()) if (!witnessComplex.has_good_link(u)) { //std::cout << "Landmark " << u << " start!" << std::endl; //perturbL.insert(u); count_badlinks++; - std::cout << u << " "; + //std::cout << u << " "; Point_d& l = landmarks[u]; - Fuzzy_sphere fs(l, sqrt(lambda)*2, 0, STraits(&(landmarks[0]))); + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, STraits(&(landmarks[0]))); L.search(std::insert_iterator>(perturbL,perturbL.begin()),fs); //L.search(std::inserter(perturbL,perturbL.begin()),fs); //L.search(std::ostream_iterator(std::cout,"\n"),fs); @@ -270,13 +476,20 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< for (auto u: perturbL) { - Random_point_iterator rp(D,sqrt(lambda)/2); + Random_point_iterator rp(D,sqrt(lambda)/16); //std::cout << landmarks[u] << std::endl; std::vector point; for (int i = 0; i < D; i++) { - point.push_back(W[landmarks_ind[u]][i] + (*rp)[i]); + //FT coord = W[landmarks_ind[u]][i] + (*rp)[i]; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); } landmarks[u] = Point_d(point); //std::cout << landmarks[u] << std::endl; @@ -284,14 +497,13 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl; std::cout << "lambda=" << lambda << std::endl; - // Write the WL matrix in a file + + //std::cout << "WL size" << WL.size() << std::endl; /* - mkdir("output", S_IRWXU); - const size_t last_slash_idx = file_name.find_last_of("/"); - if (std::string::npos != last_slash_idx) - { - file_name.erase(0, last_slash_idx + 1); - } + std::cout << "L:" << std::endl; + for (int i = 0; i < landmarks.size(); i++) + std::cout << landmarks[i] << std::endl; + */ char buffer[100]; int i = sprintf(buffer,"stree_result.txt"); @@ -303,39 +515,47 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< witnessComplex.st_to_file(ofs); ofs.close(); } - */ + return count_badlinks; } int main (int argc, char * const argv[]) { - if (argc != 3) + + if (argc != 4) { std::cerr << "Usage: " << argv[0] - << " path_to_point_file nbL \n"; + << " nbP nbL dim\n"; return 0; } /* boost::filesystem::path p; - for (; argc > 2; --argc, ++argv) p /= argv[1]; */ - std::string file_name = argv[1]; - int nbL = atoi(argv[2]); + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); //clock_t start, end; //Construct the Simplex Tree //Witness_complex<> witnessComplex; std::cout << "Let the carnage begin!\n"; Point_Vector point_vector; - read_points_cust(file_name, point_vector); + //read_points_cust(file_name, point_vector); + generate_points_random_box(point_vector, nbP, dim); + /* + for (auto &p: point_vector) + { + assert(std::count(point_vector.begin(),point_vector.end(),p) == 1); + } + */ //std::cout << "Successfully read the points\n"; //witnessComplex.setNbL(nbL); // witnessComplex.witness_complex_from_points(point_vector); - int nbP = point_vector.size(); + //int nbP = point_vector.size(); //std::vector > WL(nbP); //std::set L; Point_Vector L; @@ -344,11 +564,18 @@ int main (int argc, char * const argv[]) //start = clock(); //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); - int bl = 1; - for (int i = 0; bl != 0; i++) + for (auto i: chosen_landmarks) + { + assert(std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + } + int bl = nbL, curr_min = bl; + + for (int i = 0; bl > 0; i++) { - std::cout << "========== Start iteration " << i << " ========\n"; - bl = landmark_perturbation(point_vector, L, chosen_landmarks); + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; } //end = clock(); diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index afb42807..514b115b 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -236,10 +236,10 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< } } //std::cout << "\n"; - /* + std::string out_file = "wl_result"; write_wl(out_file,WL); - */ + //******************** Constructng a witness complex std::cout << "Entered witness complex construction\n"; Witness_complex<> witnessComplex; -- cgit v1.2.3 From 9d49bd8d3fe2421016c02bf40cf4ac8e87e75cbe Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 26 May 2015 10:39:03 +0000 Subject: witness complex in a torus 2 git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@595 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f43a636b79ccbc926e1a5c77dc0876ba689038c5 --- .../example/witness_complex_flat_torus.cpp | 25 +++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index c1fb5082..c3b2f910 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -390,6 +390,12 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) { + //********************Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i point; for (int i = 0; i < D; i++) { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; //FT coord = W[landmarks_ind[u]][i] + (*rp)[i]; FT coord = landmarks[u][i] + (*rp)[i]; if (coord > 1) @@ -563,10 +570,18 @@ int main (int argc, char * const argv[]) //Point_etiquette_map L_i; //start = clock(); //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); - for (auto i: chosen_landmarks) + bool ok=false; + while (!ok) { - assert(std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + ok = true; + L = {}; + chosen_landmarks = {}; + landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + for (auto i: chosen_landmarks) + { + ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + if (!ok) break; + } } int bl = nbL, curr_min = bl; -- cgit v1.2.3 From 0844edcc9dcd8d507da462d84d120d4ad4724c83 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 26 May 2015 11:00:08 +0000 Subject: Fixed random point choice in flat torus git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@596 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ae114c4dc58c3f7dd8a761c6407c2ad4ff8ef61e --- src/Witness_complex/example/witness_complex_flat_torus.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index c3b2f910..1ce17fde 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -375,7 +375,8 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, { // while (!res.second) // { - chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) + chosen_landmark = rand.get_int(0,nbP); //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; -- cgit v1.2.3 From 380c105e640335deb148feb80b81bbc6fdd39ff3 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 29 May 2015 09:18:41 +0000 Subject: witness: Tweaking for the tests git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@597 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f357efa7f0967c337be027f37c236f3ad2864204 --- src/Witness_complex/example/CMakeLists.txt | 3 + .../example/witness_complex_flat_torus.cpp | 223 ++++++++++++++++++--- .../example/witness_complex_perturbations.cpp | 83 +++++++- .../include/gudhi/Witness_complex.h | 36 +++- 4 files changed, 294 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index e3768138..09167cbe 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -83,6 +83,9 @@ if(CGAL_FOUND) add_executable ( witness_complex_flat_torus witness_complex_flat_torus.cpp ) target_link_libraries(witness_complex_flat_torus ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_flat_torus ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_flat_torus ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_sphere witness_complex_sphere.cpp ) + target_link_libraries(witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index 1ce17fde..ff995a4f 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -75,28 +75,33 @@ typedef CGAL::Euclidean_distance Euclidean_distance; * \brief Class of distance in a flat torus in dimaension D * */ -class Torus_distance : public Euclidean_distance { +//class Torus_distance : public Euclidean_distance { +/* + class Torus_distance { public: - typedef FT FT; - typedef Point_d Point_d; - typedef Point_d Query_item; - typedef typename CGAL::Dynamic_dimension_tag D; + typedef K::FT FT; + typedef K::Point_d Point_d; + typedef Point_d Query_item; + typedef typename CGAL::Dynamic_dimension_tag D; + + double box_length = 2; FT transformed_distance(Query_item q, Point_d p) const { FT distance = FT(0); FT coord = FT(0); + //std::cout << "Hello skitty!\n"; typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); typename K::Cartesian_const_iterator_d qit = construct_it(q), qe = construct_it(q,1), pit = construct_it(p); for(; qit != qe; qit++, pit++) { coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit))); - if (coord*coord <= (1-coord)*(1-coord)) + if (coord*coord <= (box_length-coord)*(box_length-coord)) distance += coord*coord; else - distance += (1-coord)*(1-coord); + distance += (box_length-coord)*(box_length-coord); } return distance; } @@ -113,7 +118,7 @@ public: if((*qit) < r.min_coord(i)) { dist1 = (r.min_coord(i)-(*qit)); - dist2 = (1 - r.max_coord(i)+(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); if (dist1 < dist2) distance += dist1*dist1; else @@ -121,7 +126,7 @@ public: } else if ((*qit) > r.max_coord(i)) { - dist1 = (1 - (*qit)+r.min_coord(i)); + dist1 = (box_length - (*qit)+r.min_coord(i)); dist2 = ((*qit) - r.max_coord(i)); if (dist1 < dist2) distance += dist1*dist1; @@ -140,12 +145,13 @@ public: typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); typename K::Cartesian_const_iterator_d qit = construct_it(q), qe = construct_it(q,1); + //std::cout << r.max_coord(0) << std::endl; for(unsigned int i = 0;qit != qe; i++, qit++) { if((*qit) < r.min_coord(i)) { dist1 = (r.min_coord(i)-(*qit)); - dist2 = (1 - r.max_coord(i)+(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); if (dist1 < dist2) { dists[i] = dist1; @@ -155,16 +161,18 @@ public: { dists[i] = dist2; distance += dist2*dist2; + //std::cout << "Good stuff1\n"; } } else if ((*qit) > r.max_coord(i)) { - dist1 = (1 - (*qit)+r.min_coord(i)); + dist1 = (box_length - (*qit)+r.min_coord(i)); dist2 = ((*qit) - r.max_coord(i)); if (dist1 < dist2) { dists[i] = dist1; distance += dist1*dist1; + //std::cout << "Good stuff2\n"; } else { @@ -175,7 +183,7 @@ public: }; return distance; } - + FT max_distance_to_rectangle(const Query_item& q, const CGAL::Kd_tree_rectangle& r) const { FT distance=FT(0); @@ -184,14 +192,14 @@ public: qe = construct_it(q,1); for(unsigned int i = 0;qit != qe; i++, qit++) { - if (FT(1) <= (r.min_coord(i)+r.max_coord(i))) - if ((r.max_coord(i)+r.min_coord(i)-FT(1))/FT(2.0) <= (*qit) && + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); else distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); else - if ((FT(1)-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); else @@ -200,6 +208,7 @@ public: return distance; } + FT max_distance_to_rectangle(const Query_item& q, const CGAL::Kd_tree_rectangle& r, std::vector& dists) const { @@ -209,8 +218,8 @@ public: qe = construct_it(q,1); for(unsigned int i = 0;qit != qe; i++, qit++) { - if (FT(1) <= (r.min_coord(i)+r.max_coord(i))) - if ((r.max_coord(i)+r.min_coord(i)-FT(1))/FT(2.0) <= (*qit) && + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) { dists[i] = r.max_coord(i)-(*qit); @@ -222,7 +231,7 @@ public: distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); } else - if ((FT(1)-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) { dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit))); @@ -237,7 +246,14 @@ public: } return distance; } - + + inline FT new_distance(FT dist, FT old_off, FT new_off, + int ) const { + + FT new_dist = dist + (new_off*new_off - old_off*old_off); + return new_dist; + } + inline FT transformed_distance(FT d) const { return d*d; } @@ -247,7 +263,7 @@ public: } }; - +*/ typedef std::vector< Vertex_handle > typeVectorVertex; @@ -259,7 +275,7 @@ typedef CGAL::Search_traits_adapter< //typedef K TreeTraits; //typedef CGAL::Distance_adapter Euclidean_adapter; //typedef CGAL::Kd_tree Kd_tree; -typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; typedef K_neighbor_search::Tree Tree; typedef K_neighbor_search::Distance Distance; typedef K_neighbor_search::iterator KNS_iterator; @@ -275,7 +291,7 @@ typedef std::vector Point_Vector; typedef CGAL::Random_points_in_cube_d Random_cube_iterator; typedef CGAL::Random_points_in_ball_d Random_point_iterator; - +bool toric=true; /** * \brief Customized version of read_points @@ -319,6 +335,14 @@ void generate_points_random_box(Point_Vector& W, int nbP, int dim) } } +/* NOT TORUS RELATED + */ +void generate_points_sphere(Point_Vector& W, int nbP, int dim) +{ + CGAL::Random_points_on_sphere_d rp(dim,1); + for (int i = 0; i < nbP; i++) + W.push_back(*rp++); +} /* void read_points_to_tree (std::string file_name, Tree& tree) { @@ -359,6 +383,97 @@ void write_wl( std::string file_name, std::vector< std::vector > & WL) } +std::vector convert_to_torus(std::vector< Point_d>& points) +{ + std::vector< Point_d > points_torus; + for (auto p: points) + { + FT theta = M_PI*p[0]; + FT phi = M_PI*p[1]; + std::vector p_torus; + p_torus.push_back((1+0.2*cos(theta))*cos(phi)); + p_torus.push_back((1+0.2*cos(theta))*sin(phi)); + p_torus.push_back(0.2*sin(theta)); + points_torus.push_back(Point_d(p_torus)); + } + return points_torus; +} + +void write_points_torus( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + std::vector points_torus = convert_to_torus(points); + for (auto w : points_torus) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + if (toric) write_points_torus(file_name, points); + else + { + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); + } +} + + +void write_edges_torus(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + Point_Vector l_torus = convert_to_torus(landmarks); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = l_torus[u].cartesian_begin(); it != l_torus[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = l_torus[v].cartesian_begin(); it != l_torus[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + if (toric) write_edges_torus(file_name, witness_complex, landmarks); + else + { + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); + } +} + /** Function that chooses landmarks from W and place it in the kd-tree L. * Note: nbL hould be removed if the code moves to Witness_complex @@ -397,21 +512,41 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< for (int i=0; i({0.8,0.8})), p2(std::vector({0.1,0.1})); FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); //std::cout << "Lambda=" << lambda << std::endl; //FT lambda = 0.1;//Euclidean_distance(); + std::vector landmarks_ext; + int nb_cells = 1; + for (int i = 0; i < D; ++i) + nb_cells *= 3; + for (int i = 0; i < nb_cells; ++i) + for (int k = 0; k < nbL; ++k) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1)); + cell_i /= 3; + } + landmarks_ext.push_back(point); + } + write_points("landmarks/initial_landmarks",landmarks_ext); + STraits traits(&(landmarks_ext[0])); std::vector< std::vector > WL(nbP); Tree L(boost::counting_iterator(0), - boost::counting_iterator(nbL), + boost::counting_iterator(nb_cells*nbL), typename Tree::Splitter(), - STraits(&(landmarks[0]))); + traits); /*Tree2 L2(boost::counting_iterator(0), boost::counting_iterator(nbL), typename Tree::Splitter(), @@ -424,10 +559,14 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //std::cout << "Entered witness number " << i << std::endl; Point_d& w = W[i]; //std::cout << "Safely constructed a point\n"; - ////Search D+1 nearest neighbours from the tree of landmarks L + ////Search D+1 nearest neighbours from the tree of landmarks L + /* + if (w[0]>0.95) + std::cout << i << std::endl; + */ K_neighbor_search search(L, w, D+1, FT(0), true, //CGAL::Distance_adapter(&(landmarks[0])) ); - CGAL::Distance_adapter(&(landmarks[0])) ); + CGAL::Distance_adapter(&(landmarks_ext[0])) ); //std::cout << "Safely found nearest landmarks\n"; for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) { @@ -435,7 +574,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //Point_etiquette_map::iterator itm = L_i.find(it->first); //assert(itm != L_i.end()); //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; - WL[i].push_back(it->first); + WL[i].push_back((it->first)%nbL); //std::cout << "ITFIRST " << it->first << std::endl; //std::cout << i << " " << it->first << ": " << it->second << std::endl; } @@ -463,6 +602,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< int count_badlinks = 0; //std::cout << "Bad links around "; for (auto u: witnessComplex.complex_vertex_range()) + { + std::cout << "Vertex " << u << " "; if (!witnessComplex.has_good_link(u)) { //std::cout << "Landmark " << u << " start!" << std::endl; @@ -470,12 +611,16 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< count_badlinks++; //std::cout << u << " "; Point_d& l = landmarks[u]; - Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, STraits(&(landmarks[0]))); - L.search(std::insert_iterator>(perturbL,perturbL.begin()),fs); + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); //L.search(std::inserter(perturbL,perturbL.begin()),fs); //L.search(std::ostream_iterator(std::cout,"\n"),fs); //std::cout << "PerturbL size is " << perturbL.size() << std::endl; } + } std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; //*********************** Perturb bad link landmarks @@ -523,7 +668,18 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< witnessComplex.st_to_file(ofs); ofs.close(); } - + /* + i = sprintf(buffer,"badlinks.txt"); + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs); + ofs.close(); + } + */ + write_edges("landmarks/edges", witnessComplex, landmarks); + //std::cout << Distance().transformed_distance(Point_d(std::vector({0.1,0.1})), Point_d(std::vector({1.9,1.9}))) << std::endl; return count_badlinks; } @@ -585,13 +741,16 @@ int main (int argc, char * const argv[]) } } int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_landmarks",L); - for (int i = 0; bl > 0; i++) + for (int i = 0; i < 1; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); if (bl < curr_min) curr_min=bl; + write_points("landmarks/landmarks0",L); } //end = clock(); diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index 514b115b..07b1eb8d 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -157,11 +157,44 @@ void write_wl( std::string file_name, std::vector< std::vector > & WL) ofs.close(); } +void write_points( std::string file_name, std::vector< Point_d > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_edges_gnuplot(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + /** Function that chooses landmarks from W and place it in the kd-tree L. * Note: nbL hould be removed if the code moves to Witness_complex */ + void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) { std::cout << "Enter landmark choice to kd tree\n"; @@ -183,7 +216,32 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, //std::cout << "Added landmark " << chosen_landmark << std::endl; } } - +/* +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) + chosen_landmark = rand.get_int(0,nbP); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } +*/ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) { @@ -285,13 +343,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl; std::cout << "lambda=" << lambda << std::endl; // Write the WL matrix in a file - /* - mkdir("output", S_IRWXU); - const size_t last_slash_idx = file_name.find_last_of("/"); - if (std::string::npos != last_slash_idx) - { - file_name.erase(0, last_slash_idx + 1); - } + char buffer[100]; int i = sprintf(buffer,"stree_result.txt"); @@ -303,7 +355,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< witnessComplex.st_to_file(ofs); ofs.close(); } - */ + //witnessComplex.write_badlinks("badlinks"); + write_edges_gnuplot("landmarks/edges", witnessComplex, landmarks); return count_badlinks; } @@ -345,10 +398,22 @@ int main (int argc, char * const argv[]) //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); int bl = 1; + + mkdir("landmarks", S_IRWXU); + const size_t last_slash_idx = file_name.find_last_of("/"); + if (std::string::npos != last_slash_idx) + { + file_name.erase(0, last_slash_idx + 1); + } + write_points("landmarks/initial_pointset",point_vector); + write_points("landmarks/initial_landmarks",L); for (int i = 0; bl != 0; i++) { std::cout << "========== Start iteration " << i << " ========\n"; bl = landmark_perturbation(point_vector, L, chosen_landmarks); + std::ostringstream os(std::ostringstream::ate);; + os << "landmarks/landmarks0"; + write_points(os.str(),L); } //end = clock(); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index bb553347..c8eaa3ef 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -642,14 +642,16 @@ private: print_vector(link_vertices); std::cout << "\n"; */ + print_vector(link_vertices); std::cout << "\n"; // Find the dimension typeVectorVertex empty_simplex = {}; int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); //std::cout << " dim " << d << "\n"; //Siblings* curr_sibl = root(); + //std::cout << "Currently at vertex " return (link_is_pseudomanifold(link_vertices,d)); } - + /** \brief Search and output links around vertices that are not pseudomanifolds * */ @@ -661,7 +663,7 @@ private: //int count = 0; for (auto v: complex_vertex_range()) { - //std::cout << "Vertex " << v << ":\n"; + std::cout << "Vertex " << v << ": "; std::vector< Vertex_handle > link_vertices; // Fill link_vertices for (auto u: complex_vertex_range()) @@ -670,10 +672,10 @@ private: if (u != v && find(edge) != null_simplex()) link_vertices.push_back(u); } - /* - print_vector(link_vertices); - std::cout << "\n"; - */ + + print_vector(link_vertices); + std::cout << "\n"; + // Find the dimension typeVectorVertex empty_simplex = {}; int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); @@ -718,6 +720,7 @@ private: Simplex_handle sh; int final_d = curr_d; typename std::vector< Vertex_handle >::iterator it; + //std::cout << "Current vertex is " << for (it = curr_v; it != link_vertices.end(); ++it) { curr_simplex.push_back(*it); @@ -731,8 +734,13 @@ private: { //std::cout << " -> " << *it << "\n"; int d = link_dim(link_vertices, it+1, curr_d+1, curr_simplex); - if (d > final_d) - final_d = d; + if (d >= final_d) + { + final_d = d; + std::cout << d << " "; + print_vector(curr_simplex); + std::cout << std::endl; + } } /* else @@ -781,14 +789,22 @@ private: //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; if (boost::out_degree(f_map_it.second, adj_graph) != 2) { + if (boost::out_degree(f_map_it.second, adj_graph) == 3) + { + std::cout << "This simplex has 3 cofaces: "; + for(auto v : simplex_vertex_range(f_map_it.first)) + std::cout << v << " "; + std::cout << std::endl; + } count_bad[dimension]++; return false; } } // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices // What is left is to check the connexity - std::vector components(boost::num_vertices(adj_graph)); - return (boost::connected_components(adj_graph, &components[0]) == 1); + //std::vector components(boost::num_vertices(adj_graph)); + return true; //Forget the connexity + //return (boost::connected_components(adj_graph, &components[0]) == 1); } void add_vertices(typeVectorVertex& link_vertices, -- cgit v1.2.3 From 5cae0e771c7d4603d25ccf06c782fe383f91e74a Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 29 May 2015 09:22:36 +0000 Subject: Added the test with spheres git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@598 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f35dd2d082e318b912f581ee86e1407fd39109eb --- .../example/witness_complex_sphere.cpp | 748 +++++++++++++++++++++ 1 file changed, 748 insertions(+) create mode 100644 src/Witness_complex/example/witness_complex_sphere.cpp (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp new file mode 100644 index 00000000..c9a9119a --- /dev/null +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -0,0 +1,748 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + +/** + * \brief Class of distance in a flat torus in dimaension D + * + */ +//class Torus_distance : public Euclidean_distance { + class Torus_distance { + +public: + typedef K::FT FT; + typedef K::Point_d Point_d; + typedef Point_d Query_item; + typedef typename CGAL::Dynamic_dimension_tag D; + + double box_length = 2; + + FT transformed_distance(Query_item q, Point_d p) const + { + FT distance = FT(0); + FT coord = FT(0); + //std::cout << "Hello skitty!\n"; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1), pit = construct_it(p); + for(; qit != qe; qit++, pit++) + { + coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit))); + if (coord*coord <= (box_length-coord)*(box_length-coord)) + distance += coord*coord; + else + distance += (box_length-coord)*(box_length-coord); + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (box_length - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + //std::cout << r.max_coord(0) << std::endl; + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + //std::cout << "Good stuff1\n"; + } + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (box_length - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + //std::cout << "Good stuff2\n"; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + } + } + }; + return distance; + } + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + else + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + return distance; + } + + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = r.max_coord(i)-(*qit); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + } + else + { + dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i))); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + else + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit))); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + + } + else + { + dists[i] = (*qit)-r.min_coord(i); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + } + return distance; + } + + inline FT new_distance(FT dist, FT old_off, FT new_off, + int /* cutting_dimension */) const { + + FT new_dist = dist + (new_off*new_off - old_off*old_off); + return new_dist; + } + + inline FT transformed_distance(FT d) const { + return d*d; + } + + inline FT inverse_of_transformed_distance(FT d) const { + return sqrt(d); + } + +}; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +bool toric=false; + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +void generate_points_grid(Point_Vector& W, int width, int D) +{ + +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + +/* NOT TORUS RELATED + */ +void generate_points_sphere(Point_Vector& W, int nbP, int dim) +{ + CGAL::Random_points_on_sphere_d rp(dim,1); + for (int i = 0; i < nbP; i++) + W.push_back(*rp++); +} +/* +void read_points_to_tree (std::string file_name, Tree& tree) +{ + //I assume here that tree is empty + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector coords; + std::istringstream iss( line ); + while(iss >> x) { coords.push_back(x); } + if (coords.size() != 1) + { + Point_d point(coords.begin(), coords.end()); + tree.insert(point); + } + } + in_file.close(); +} +*/ + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + +std::vector convert_to_torus(std::vector< Point_d>& points) +{ + std::vector< Point_d > points_torus; + for (auto p: points) + { + FT theta = M_PI*p[0]; + FT phi = M_PI*p[1]; + std::vector p_torus; + p_torus.push_back((1+0.2*cos(theta))*cos(phi)); + p_torus.push_back((1+0.2*cos(theta))*sin(phi)); + p_torus.push_back(0.2*sin(theta)); + points_torus.push_back(Point_d(p_torus)); + } + return points_torus; +} + +void write_points_torus( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + std::vector points_torus = convert_to_torus(points); + for (auto w : points_torus) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + if (toric) write_points_torus(file_name, points); + else + { + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); + } +} + + +void write_edges_torus(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + Point_Vector l_torus = convert_to_torus(landmarks); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = l_torus[u].cartesian_begin(); it != l_torus[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = l_torus[v].cartesian_begin(); it != l_torus[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + if (toric) write_edges_torus(file_name, witness_complex, landmarks); + else + { + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); + } +} + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) + chosen_landmark = rand.get_int(0,nbP); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + + +int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //********************Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i({0.8,0.8})), p2(std::vector({0.1,0.1})); + FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); + //std::cout << "Lambda=" << lambda << std::endl; + //FT lambda = 0.1;//Euclidean_distance(); + STraits traits(&(landmarks[0])); + std::vector< std::vector > WL(nbP); + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + traits); + /*Tree2 L2(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + STraits(&(landmarks[0]))); + */ + std::cout << "Enter (D+1) nearest landmarks\n"; + //std::cout << "Size of the tree is " << L.size() << std::endl; + for (int i = 0; i < nbP; i++) + { + //std::cout << "Entered witness number " << i << std::endl; + Point_d& w = W[i]; + //std::cout << "Safely constructed a point\n"; + ////Search D+1 nearest neighbours from the tree of landmarks L + /* + if (w[0]>0.95) + std::cout << i << std::endl; + */ + K_neighbor_search search(L, w, D+1, FT(0), true, + //CGAL::Distance_adapter(&(landmarks[0])) ); + CGAL::Distance_adapter(&(landmarks[0])) ); + //std::cout << "Safely found nearest landmarks\n"; + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + //Point_etiquette_map::iterator itm = L_i.find(it->first); + //assert(itm != L_i.end()); + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + WL[i].push_back(it->first); + //std::cout << "ITFIRST " << it->first << std::endl; + //std::cout << i << " " << it->first << ": " << it->second << std::endl; + } + if (i == landmarks_ind[WL[i][0]]) + { + //std::cout << "'"; + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + //std::cout << "\n"; + + std::string out_file = "wl_result"; + write_wl(out_file,WL); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + //std::cout << "Bad links around "; + for (auto u: witnessComplex.complex_vertex_range()) + if (!witnessComplex.has_good_link(u)) + { + //std::cout << "Landmark " << u << " start!" << std::endl; + //perturbL.insert(u); + count_badlinks++; + //std::cout << u << " "; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); + //L.search(std::inserter(perturbL,perturbL.begin()),fs); + //L.search(std::ostream_iterator(std::cout,"\n"),fs); + //std::cout << "PerturbL size is " << perturbL.size() << std::endl; + } + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; + //*********************** Perturb bad link landmarks + + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/8); + //std::cout << landmarks[u] << std::endl; + + std::vector point; + for (int i = 0; i < D; i++) + { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; + //FT coord = W[landmarks_ind[u]][i] + (*rp)[i]; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); + } + landmarks[u] = Point_d(point); + //std::cout << landmarks[u] << std::endl; + } + + //std::cout << "landmark[0][0] after" << landmarks[0][0] << std::endl; + std::cout << "lambda=" << lambda << std::endl; + + //std::cout << "WL size" << WL.size() << std::endl; + /* + std::cout << "L:" << std::endl; + for (int i = 0; i < landmarks.size(); i++) + std::cout << landmarks[i] << std::endl; + */ + + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + std::cout << Distance().transformed_distance(Point_d(std::vector({0.1,0.1})), Point_d(std::vector({1.9,1.9}))) << std::endl; + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + + if (argc != 4) + { + std::cerr << "Usage: " << argv[0] + << " nbP nbL dim\n"; + return 0; + } + /* + boost::filesystem::path p; + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); + //clock_t start, end; + //Construct the Simplex Tree + //Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + //read_points_cust(file_name, point_vector); + generate_points_sphere(point_vector, nbP, dim); + /* + for (auto &p: point_vector) + { + assert(std::count(point_vector.begin(),point_vector.end(),p) == 1); + } + */ + //std::cout << "Successfully read the points\n"; + //witnessComplex.setNbL(nbL); + // witnessComplex.witness_complex_from_points(point_vector); + //int nbP = point_vector.size(); + //std::vector > WL(nbP); + //std::set L; + Point_Vector L; + std::vector chosen_landmarks; + //Point_etiquette_map L_i; + //start = clock(); + //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); + bool ok=false; + while (!ok) + { + ok = true; + L = {}; + chosen_landmarks = {}; + landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + for (auto i: chosen_landmarks) + { + ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + if (!ok) break; + } + } + int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + write_points("landmarks/initial_landmarks",L); + + for (int i = 0; bl > 0; i++) + { + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; + write_points("landmarks/landmarks0",L); + } + //end = clock(); + + /* + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + */ + + /* + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); + */ +} -- cgit v1.2.3 From 3efbb8c26aecc9f88dae4ec69d3149a4f5f1bd40 Mon Sep 17 00:00:00 2001 From: skachano Date: Sat, 30 May 2015 15:36:35 +0000 Subject: witness: Testing continues git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@600 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 57d8d66a90e9839887289e4efd7fbddabe009d94 --- .../example/witness_complex_perturbations.cpp | 2 +- .../example/witness_complex_sphere.cpp | 15 ++++++++-- .../include/gudhi/Witness_complex.h | 32 ++++++++++++++++------ 3 files changed, 37 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index 07b1eb8d..9d39906b 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -328,7 +328,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< for (auto u: perturbL) { - Random_point_iterator rp(D,sqrt(lambda)/2); + Random_point_iterator rp(D,sqrt(lambda)/4); //std::cout << landmarks[u] << std::endl; std::vector point; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index c9a9119a..7ba1dd61 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -489,8 +489,9 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, { // while (!res.second) // { - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) + do chosen_landmark = rand.get_int(0,nbP); + while (std::find(landmarks_ind.begin(), landmarks_ind.end(), chosen_landmark) != landmarks_ind.end()); //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; @@ -546,7 +547,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< if (w[0]>0.95) std::cout << i << std::endl; */ - K_neighbor_search search(L, w, D+1, FT(0), true, + K_neighbor_search search(L, w, D, FT(0), true, //CGAL::Distance_adapter(&(landmarks[0])) ); CGAL::Distance_adapter(&(landmarks[0])) ); //std::cout << "Safely found nearest landmarks\n"; @@ -583,8 +584,10 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::set< int > perturbL; int count_badlinks = 0; //std::cout << "Bad links around "; + std::vector< int > count_bad(D+3); + std::vector< int > count_good(D+3); for (auto u: witnessComplex.complex_vertex_range()) - if (!witnessComplex.has_good_link(u)) + if (!witnessComplex.has_good_link(u, count_bad, count_good)) { //std::cout << "Landmark " << u << " start!" << std::endl; //perturbL.insert(u); @@ -600,6 +603,12 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //L.search(std::ostream_iterator(std::cout,"\n"),fs); //std::cout << "PerturbL size is " << perturbL.size() << std::endl; } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; //*********************** Perturb bad link landmarks diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index c8eaa3ef..c45d144d 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -628,7 +628,7 @@ private: /** \brief Returns true if the link is good */ - bool has_good_link(Vertex_handle v) + bool has_good_link(Vertex_handle v, std::vector< int >& bad_count, std::vector< int >& good_count) { std::vector< Vertex_handle > link_vertices; // Fill link_vertices @@ -642,14 +642,28 @@ private: print_vector(link_vertices); std::cout << "\n"; */ - print_vector(link_vertices); std::cout << "\n"; + //print_vector(link_vertices); std::cout << "\n"; // Find the dimension typeVectorVertex empty_simplex = {}; int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); + /* + if (d >= good_count.size()) + { + std::cout << "d=" << d << std::endl; + std::cout << "gc.size=" << good_count.size() << std::endl; + print_vector(link_vertices); + std::cout << std::endl; + } + */ + //assert(d < good_count.size()); + if (d == -1) bad_count[0]++; //std::cout << " dim " << d << "\n"; //Siblings* curr_sibl = root(); //std::cout << "Currently at vertex " - return (link_is_pseudomanifold(link_vertices,d)); + bool b= (link_is_pseudomanifold(link_vertices,d)); + if (d != -1) {if (b) good_count[d]++; else bad_count[d]++;} + return b; + } /** \brief Search and output links around vertices that are not pseudomanifolds @@ -737,9 +751,9 @@ private: if (d >= final_d) { final_d = d; - std::cout << d << " "; - print_vector(curr_simplex); - std::cout << std::endl; + //std::cout << d << " "; + //print_vector(curr_simplex); + // std::cout << std::endl; } } /* @@ -789,13 +803,15 @@ private: //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; if (boost::out_degree(f_map_it.second, adj_graph) != 2) { + /* if (boost::out_degree(f_map_it.second, adj_graph) == 3) - { + { std::cout << "This simplex has 3 cofaces: "; for(auto v : simplex_vertex_range(f_map_it.first)) std::cout << v << " "; std::cout << std::endl; - } + + }*/ count_bad[dimension]++; return false; } -- cgit v1.2.3 From 9e99b02fa2d91aced59c5fded3f1a2e07afe30aa Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 1 Jun 2015 09:00:41 +0000 Subject: Corrected bad-good links git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@601 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 004b949f2d74b803483535b126e76b84b27f4a7e --- .../example/witness_complex_flat_torus.cpp | 14 ++- .../example/witness_complex_sphere.cpp | 9 +- .../include/gudhi/Witness_complex.h | 110 ++++++++++----------- 3 files changed, 71 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index ff995a4f..14d6426d 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -601,10 +601,12 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::set< int > perturbL; int count_badlinks = 0; //std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); for (auto u: witnessComplex.complex_vertex_range()) { - std::cout << "Vertex " << u << " "; - if (!witnessComplex.has_good_link(u)) + //std::cout << "Vertex " << u << " "; + if (!witnessComplex.has_good_link(u, count_bad, count_good)) { //std::cout << "Landmark " << u << " start!" << std::endl; //perturbL.insert(u); @@ -621,6 +623,12 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //std::cout << "PerturbL size is " << perturbL.size() << std::endl; } } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; //*********************** Perturb bad link landmarks @@ -744,7 +752,7 @@ int main (int argc, char * const argv[]) write_points("landmarks/initial_pointset",point_vector); //write_points("landmarks/initial_landmarks",L); - for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 7ba1dd61..f6345411 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -584,8 +584,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::set< int > perturbL; int count_badlinks = 0; //std::cout << "Bad links around "; - std::vector< int > count_bad(D+3); - std::vector< int > count_good(D+3); + std::vector< int > count_bad(D); + std::vector< int > count_good(D); for (auto u: witnessComplex.complex_vertex_range()) if (!witnessComplex.has_good_link(u, count_bad, count_good)) { @@ -623,8 +623,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< { while (K().squared_distance_d_object()(*rp,origin) < lambda/256) rp++; - //FT coord = W[landmarks_ind[u]][i] + (*rp)[i]; - FT coord = landmarks[u][i] + (*rp)[i]; + FT coord = W[landmarks_ind[u]][i] + (*rp)[i]; + //FT coord = landmarks[u][i] + (*rp)[i]; if (coord > 1) point.push_back(coord-1); else if (coord < -1) @@ -723,6 +723,7 @@ int main (int argc, char * const argv[]) write_points("landmarks/initial_landmarks",L); for (int i = 0; bl > 0; i++) + //for (int i = 0; i < 1; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index c45d144d..0888c086 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -630,51 +630,41 @@ private: */ bool has_good_link(Vertex_handle v, std::vector< int >& bad_count, std::vector< int >& good_count) { - std::vector< Vertex_handle > link_vertices; - // Fill link_vertices + std::vector< Vertex_handle > star_vertices; + // Fill star_vertices + star_vertices.push_back(v); for (auto u: complex_vertex_range()) { typeVectorVertex edge = {u,v}; if (u != v && find(edge) != null_simplex()) - link_vertices.push_back(u); + star_vertices.push_back(u); } - /* - print_vector(link_vertices); - std::cout << "\n"; - */ - //print_vector(link_vertices); std::cout << "\n"; // Find the dimension - typeVectorVertex empty_simplex = {}; - int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); + typeVectorVertex init_simplex = {star_vertices[0]}; + int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex) - 1; //link_dim = star_dim - 1 + assert(init_simplex.size() == 1); /* - if (d >= good_count.size()) - { - std::cout << "d=" << d << std::endl; - std::cout << "gc.size=" << good_count.size() << std::endl; - print_vector(link_vertices); - std::cout << std::endl; - } - */ - //assert(d < good_count.size()); + if (d == count_good.size()) + { + std::cout << "Found a star of dimension " << (d+1) << " around " << v << "\nThe star is "; + print_vector(star_vertices); std::cout << std::endl; + } + */ if (d == -1) bad_count[0]++; - //std::cout << " dim " << d << "\n"; - //Siblings* curr_sibl = root(); - //std::cout << "Currently at vertex " - bool b= (link_is_pseudomanifold(link_vertices,d)); + bool b= (link_is_pseudomanifold(star_vertices,d)); if (d != -1) {if (b) good_count[d]++; else bad_count[d]++;} - return b; + return (d != -1 && b); } /** \brief Search and output links around vertices that are not pseudomanifolds * */ + /* void write_bad_links(std::ofstream& out_file) { out_file << "Bad links list\n"; std::cout << "Entered write_bad_links\n"; - //typeVectorVertex testv = {9,15,17}; - //int count = 0; for (auto v: complex_vertex_range()) { std::cout << "Vertex " << v << ": "; @@ -693,14 +683,9 @@ private: // Find the dimension typeVectorVertex empty_simplex = {}; int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); - //std::cout << " dim " << d << "\n"; - //Siblings* curr_sibl = root(); if (link_is_pseudomanifold(link_vertices,d)) count_good[d]++; - //out_file << "Bad link at " << v << "\n"; } - //out_file << "Number of bad links: " << count << "/" << root()->size(); - //std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; nc = nbL; for (unsigned int i = 0; i != count_good.size(); i++) { @@ -718,42 +703,43 @@ private: } std::cout << "not_connected = " << nc << std::endl; } - + */ private: std::vector count_good; std::vector count_bad; int nc; - int link_dim(std::vector< Vertex_handle >& link_vertices, + int star_dim(std::vector< Vertex_handle >& star_vertices, typename std::vector< Vertex_handle >::iterator curr_v, int curr_d, typeVectorVertex& curr_simplex) { - //std::cout << "Entered link_dim for " << *(curr_v-1) << "\n"; + //std::cout << "Entered star_dim for " << *(curr_v-1) << "\n"; Simplex_handle sh; int final_d = curr_d; typename std::vector< Vertex_handle >::iterator it; //std::cout << "Current vertex is " << - for (it = curr_v; it != link_vertices.end(); ++it) + for (it = curr_v; it != star_vertices.end(); ++it) { curr_simplex.push_back(*it); + typeVectorVertex curr_simplex_copy(curr_simplex); /* std::cout << "Searching for "; print_vector(curr_simplex); std::cout << " curr_dim " << curr_d << " final_dim " << final_d; */ - sh = find(curr_simplex); + sh = find(curr_simplex_copy); //Need a copy because find sorts the vector and I want star center to be the first if (sh != null_simplex()) { //std::cout << " -> " << *it << "\n"; - int d = link_dim(link_vertices, it+1, curr_d+1, curr_simplex); + int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex); if (d >= final_d) { final_d = d; //std::cout << d << " "; //print_vector(curr_simplex); - // std::cout << std::endl; + //std::cout << std::endl; } } /* @@ -781,19 +767,19 @@ private: * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional * faces and edges represent adjacency between them. */ - bool link_is_pseudomanifold(std::vector< Vertex_handle >& link_vertices, + bool link_is_pseudomanifold(std::vector< Vertex_handle >& star_vertices, int dimension) { Adj_graph adj_graph; Graph_map d_map, f_map; // d_map = map for d-dimensional simplices // f_map = map for its facets - typeVectorVertex empty_vector = {}; - add_vertices(link_vertices, - link_vertices.begin(), + typeVectorVertex init_vector = {}; + add_vertices(star_vertices, + star_vertices.begin()+1, adj_graph, d_map, f_map, - empty_vector, + init_vector, 0, dimension); //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; @@ -823,60 +809,74 @@ private: //return (boost::connected_components(adj_graph, &components[0]) == 1); } - void add_vertices(typeVectorVertex& link_vertices, + void add_vertices(typeVectorVertex& star_vertices, typename typeVectorVertex::iterator curr_v, Adj_graph& adj_graph, Graph_map& d_map, Graph_map& f_map, typeVectorVertex& curr_simplex, int curr_d, - int dimension) + int link_dimension) { Simplex_handle sh; Vertex_t vert; typename typeVectorVertex::iterator it; - std::pair resPair; + //std::pair resPair; //typename Graph_map::iterator resPair; //Add vertices //std::cout << "Entered add vertices\n"; - for (it = curr_v; it != link_vertices.end(); ++it) + for (it = curr_v; it != star_vertices.end(); ++it) { - curr_simplex.push_back(*it); + curr_simplex.push_back(*it); //push next vertex in question + curr_simplex.push_back(star_vertices[0]); //push the center of the star /* std::cout << "Searching for "; print_vector(curr_simplex); std::cout << " curr_dim " << curr_d << " d " << dimension << ""; */ - sh = find(curr_simplex); + typeVectorVertex curr_simplex_copy(curr_simplex); + sh = find(curr_simplex_copy); //a simplex of the star + curr_simplex.pop_back(); //pop the center of the star + curr_simplex_copy = typeVectorVertex(curr_simplex); if (sh != null_simplex()) { //std::cout << " added\n"; - if (curr_d == dimension) + if (curr_d == link_dimension) { + sh = find(curr_simplex_copy); //a simplex of the link + assert(sh != null_simplex()); //ASSERT! vert = boost::add_vertex(adj_graph); - resPair = d_map.emplace(sh,vert); + d_map.emplace(sh,vert); + for (Simplex_handle sh_b: boundary_simplex_range(sh)) + { + vert = boost::add_vertex(adj_graph); + f_map.emplace(sh_b,vert); + } } else { - if (curr_d == dimension-1) + /* + if (curr_d == link_dimension-1) { vert = boost::add_vertex(adj_graph); resPair = f_map.emplace(sh,vert); } - add_vertices(link_vertices, + */ + //delete (&curr_simplex_copy); //Just so it doesn't stack + add_vertices(star_vertices, it+1, adj_graph, d_map, f_map, curr_simplex, - curr_d+1, dimension); + curr_d+1, link_dimension); } } /* else std::cout << "\n"; */ - curr_simplex.pop_back(); + curr_simplex.pop_back(); //pop the vertex in question } } -- cgit v1.2.3 From 5f049ec0dbf0f756d8ecc5e55b00d2bd748cb927 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 3 Jun 2015 08:40:22 +0000 Subject: witness: Added good-bad link count to witness_complex_perturbations git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@602 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b4dbfbf4f8c59399b174574216b577075f08ede8 --- .../example/witness_complex_perturbations.cpp | 20 +++++++++++++++----- src/Witness_complex/include/gudhi/Witness_complex.h | 14 ++++++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index 9d39906b..ec7a5abe 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -292,6 +292,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< if (dist < lambda) lambda = dist; } + //std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + } //std::cout << "\n"; @@ -307,14 +309,16 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::cout << "Entered bad links\n"; std::set< int > perturbL; int count_badlinks = 0; - std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); + //std::cout << "Bad links around "; for (auto u: witnessComplex.complex_vertex_range()) - if (!witnessComplex.has_good_link(u)) + if (!witnessComplex.has_good_link(u, count_bad, count_good)) { //std::cout << "Landmark " << u << " start!" << std::endl; //perturbL.insert(u); count_badlinks++; - std::cout << u << " "; + //std::cout << u << " "; Point_d& l = landmarks[u]; Fuzzy_sphere fs(l, sqrt(lambda)*2, 0, STraits(&(landmarks[0]))); L.search(std::insert_iterator>(perturbL,perturbL.begin()),fs); @@ -322,7 +326,13 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //L.search(std::ostream_iterator(std::cout,"\n"),fs); //std::cout << "PerturbL size is " << perturbL.size() << std::endl; } - std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + std::cout << "Bad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; //std::cout << "landmark[0][0] before" << landmarks[0][0] << std::endl; //*********************** Perturb bad link landmarks @@ -405,7 +415,7 @@ int main (int argc, char * const argv[]) { file_name.erase(0, last_slash_idx + 1); } - write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_pointset",point_vector); write_points("landmarks/initial_landmarks",L); for (int i = 0; bl != 0; i++) { diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 0888c086..222e379c 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -641,8 +641,11 @@ private: } // Find the dimension typeVectorVertex init_simplex = {star_vertices[0]}; - int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex) - 1; //link_dim = star_dim - 1 + bool is_pure = true; + int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex, is_pure) - 1; //link_dim = star_dim - 1 assert(init_simplex.size() == 1); + if (!is_pure) + std::cout << "Found an impure star around " << v << "\n"; /* if (d == count_good.size()) { @@ -651,7 +654,7 @@ private: } */ if (d == -1) bad_count[0]++; - bool b= (link_is_pseudomanifold(star_vertices,d)); + bool b= (is_pure && link_is_pseudomanifold(star_vertices,d)); if (d != -1) {if (b) good_count[d]++; else bad_count[d]++;} return (d != -1 && b); @@ -713,7 +716,8 @@ private: int star_dim(std::vector< Vertex_handle >& star_vertices, typename std::vector< Vertex_handle >::iterator curr_v, int curr_d, - typeVectorVertex& curr_simplex) + typeVectorVertex& curr_simplex, + bool& is_pure) { //std::cout << "Entered star_dim for " << *(curr_v-1) << "\n"; Simplex_handle sh; @@ -733,7 +737,9 @@ private: if (sh != null_simplex()) { //std::cout << " -> " << *it << "\n"; - int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex); + int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex, is_pure); + if (it != curr_v && d != final_d) //If the dimension is known and differs from the one computed previously + is_pure = false; //the simplex is not pure if (d >= final_d) { final_d = d; -- cgit v1.2.3 From 2bfa55d843580497f00376ede3dddf5c106dc12f Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 3 Jun 2015 12:37:11 +0000 Subject: Fixed purity and landmark choice git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@604 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 42e8bc2c939605e73ceb554ecf68e1807d3efb85 --- .../include/gudhi/Witness_complex.h | 73 ++++++++++++---------- 1 file changed, 39 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 222e379c..8b87ae89 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -642,10 +642,13 @@ private: // Find the dimension typeVectorVertex init_simplex = {star_vertices[0]}; bool is_pure = true; - int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex, is_pure) - 1; //link_dim = star_dim - 1 + std::vector dim_coface(star_vertices.size(), 1); + int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex, dim_coface.begin()+1) - 1; //link_dim = star_dim - 1 assert(init_simplex.size() == 1); if (!is_pure) std::cout << "Found an impure star around " << v << "\n"; + for (int dc: dim_coface) + is_pure = (dc == dim_coface[0]); /* if (d == count_good.size()) { @@ -653,10 +656,11 @@ private: print_vector(star_vertices); std::cout << std::endl; } */ - if (d == -1) bad_count[0]++; + //if (d == -1) bad_count[0]++; bool b= (is_pure && link_is_pseudomanifold(star_vertices,d)); if (d != -1) {if (b) good_count[d]++; else bad_count[d]++;} - return (d != -1 && b); + if (!is_pure) bad_count[0]++; + return (d != -1 && b && is_pure); } @@ -717,14 +721,15 @@ private: typename std::vector< Vertex_handle >::iterator curr_v, int curr_d, typeVectorVertex& curr_simplex, - bool& is_pure) + typename std::vector< int >::iterator curr_dc) { //std::cout << "Entered star_dim for " << *(curr_v-1) << "\n"; Simplex_handle sh; int final_d = curr_d; typename std::vector< Vertex_handle >::iterator it; + typename std::vector< Vertex_handle >::iterator dc_it; //std::cout << "Current vertex is " << - for (it = curr_v; it != star_vertices.end(); ++it) + for (it = curr_v, dc_it = curr_dc; it != star_vertices.end(); ++it, ++dc_it) { curr_simplex.push_back(*it); typeVectorVertex curr_simplex_copy(curr_simplex); @@ -737,9 +742,7 @@ private: if (sh != null_simplex()) { //std::cout << " -> " << *it << "\n"; - int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex, is_pure); - if (it != curr_v && d != final_d) //If the dimension is known and differs from the one computed previously - is_pure = false; //the simplex is not pure + int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex, dc_it); if (d >= final_d) { final_d = d; @@ -747,6 +750,8 @@ private: //print_vector(curr_simplex); //std::cout << std::endl; } + if (d >= *dc_it) + *dc_it = d; } /* else @@ -780,16 +785,16 @@ private: Graph_map d_map, f_map; // d_map = map for d-dimensional simplices // f_map = map for its facets typeVectorVertex init_vector = {}; - add_vertices(star_vertices, - star_vertices.begin()+1, - adj_graph, - d_map, - f_map, - init_vector, - 0, dimension); + add_vertices_to_link_graph(star_vertices, + star_vertices.begin()+1, + adj_graph, + d_map, + f_map, + init_vector, + 0, dimension); //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; - add_edges(adj_graph, d_map, f_map); + add_edges_to_link_graph(adj_graph, d_map, f_map); for (auto f_map_it : f_map) { //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; @@ -815,14 +820,14 @@ private: //return (boost::connected_components(adj_graph, &components[0]) == 1); } - void add_vertices(typeVectorVertex& star_vertices, - typename typeVectorVertex::iterator curr_v, - Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map, - typeVectorVertex& curr_simplex, - int curr_d, - int link_dimension) + void add_vertices_to_link_graph(typeVectorVertex& star_vertices, + typename typeVectorVertex::iterator curr_v, + Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map, + typeVectorVertex& curr_simplex, + int curr_d, + int link_dimension) { Simplex_handle sh; Vertex_t vert; @@ -869,13 +874,13 @@ private: } */ //delete (&curr_simplex_copy); //Just so it doesn't stack - add_vertices(star_vertices, - it+1, - adj_graph, - d_map, - f_map, - curr_simplex, - curr_d+1, link_dimension); + add_vertices_to_link_graph(star_vertices, + it+1, + adj_graph, + d_map, + f_map, + curr_simplex, + curr_d+1, link_dimension); } } /* @@ -886,9 +891,9 @@ private: } } - void add_edges(Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map) + void add_edges_to_link_graph(Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map) { Simplex_handle sh; // Add edges -- cgit v1.2.3 From 81d222a2222bb7a4e6304ed1ce708598a8e29dc6 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 12 Jun 2015 09:44:31 +0000 Subject: Added grid witnesses for flat torus git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@610 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 34d0bfe869ee04bd0dfa832e0e36b245f33b062f --- src/Witness_complex/example/CMakeLists.txt | 3 + .../example/relaxed_witness_complex_sphere.cpp | 460 +++++++++++++++++++++ .../example/witness_complex_flat_torus.cpp | 23 +- .../example/witness_complex_perturbations.cpp | 18 +- .../example/witness_complex_sphere.cpp | 3 +- 5 files changed, 493 insertions(+), 14 deletions(-) create mode 100644 src/Witness_complex/example/relaxed_witness_complex_sphere.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 09167cbe..77f95c79 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -86,6 +86,9 @@ if(CGAL_FOUND) add_executable ( witness_complex_sphere witness_complex_sphere.cpp ) target_link_libraries(witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( relaxed_witness_complex_sphere relaxed_witness_complex_sphere.cpp ) + target_link_libraries(relaxed_witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(relaxed_witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/relaxed_witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() diff --git a/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp b/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp new file mode 100644 index 00000000..53380124 --- /dev/null +++ b/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp @@ -0,0 +1,460 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Relaxed_witness_complex.h" +#include "gudhi/reader_utils.h" +//#include + +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_incremental_neighbor_search> Neighbor_search; +typedef Neighbor_search::Tree Tree; +typedef Neighbor_search::Distance Distance; +typedef Neighbor_search::iterator KNS_iterator; +typedef Neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +bool toric=false; + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + + +void generate_points_sphere(Point_Vector& W, int nbP, int dim) +{ + CGAL::Random_points_on_sphere_d rp(dim,1); + for (int i = 0; i < nbP; i++) + W.push_back(*rp++); +} + + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_rl( std::string file_name, std::vector< std::vector ::iterator> > & rl) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : rl) + { + for (auto l: w) + ofs << *l << " "; + ofs << "\n"; + } + ofs.close(); +} + +std::vector convert_to_torus(std::vector< Point_d>& points) +{ + std::vector< Point_d > points_torus; + for (auto p: points) + { + FT theta = M_PI*p[0]; + FT phi = M_PI*p[1]; + std::vector p_torus; + p_torus.push_back((1+0.2*cos(theta))*cos(phi)); + p_torus.push_back((1+0.2*cos(theta))*sin(phi)); + p_torus.push_back(0.2*sin(theta)); + points_torus.push_back(Point_d(p_torus)); + } + return points_torus; +} + + +void write_points_torus( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + std::vector points_torus = convert_to_torus(points); + for (auto w : points_torus) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + if (toric) write_points_torus(file_name, points); + else + { + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); + } +} + + +void write_edges_torus(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + Point_Vector l_torus = convert_to_torus(landmarks); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = l_torus[u].cartesian_begin(); it != l_torus[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = l_torus[v].cartesian_begin(); it != l_torus[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + if (toric) write_edges_torus(file_name, witness_complex, landmarks); + else + { + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); + } +} + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //std::vector landmarks; + int chosen_landmark; + //std::pair res = std::make_pair(L_i.begin(),false); + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + do chosen_landmark = rand.get_int(0,nbP); + while (std::find(landmarks_ind.begin(), landmarks_ind.end(), chosen_landmark) != landmarks_ind.end()); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + + +void landmarks_to_witness_complex(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind, FT alpha) +{ + //********************Preface: origin point + unsigned D = W[0].size(); + std::vector orig_vector; + for (unsigned i = 0; i < D; i++) + orig_vector.push_back(0); + Point_d origin(orig_vector); + //Distance dist; + //dist.transformed_distance(0,1); + //******************** Constructing a WL matrix + int nbP = W.size(); + int nbL = landmarks.size(); + STraits traits(&(landmarks[0])); + Euclidean_distance ed; + std::vector< std::vector > WL(nbP); + std::vector< std::vector< typename std::vector::iterator > > ope_limits(nbP); + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nbL), + typename Tree::Splitter(), + traits); + + std::cout << "Enter (D+1) nearest landmarks\n"; + //std::cout << "Size of the tree is " << L.size() << std::endl; + for (int i = 0; i < nbP; i++) + { + //std::cout << "Entered witness number " << i << std::endl; + Point_d& w = W[i]; + std::queue< typename std::vector::iterator > ope_queue; // queue of points at (1+epsilon) distance to current landmark + Neighbor_search search(L, w, FT(0), true, CGAL::Distance_adapter(&(landmarks[0]))); + Neighbor_search::iterator search_it = search.begin(); + + //Incremental search and filling WL + while (WL[i].size() < D) + WL[i].push_back((search_it++)->first); + FT dtow = ed.transformed_distance(w, landmarks[WL[i][D-1]]); + while (search_it->second < dtow + alpha) + WL[i].push_back((search_it++)->first); + + //Filling the (1+epsilon)-limits table + for (std::vector::iterator wl_it = WL[i].begin(); wl_it != WL[i].end(); ++wl_it) + { + ope_queue.push(wl_it); + FT d_to_curr_l = ed.transformed_distance(w, landmarks[*wl_it]); + //std::cout << "d_to_curr_l=" << d_to_curr_l << std::endl; + //std::cout << "d_to_front+alpha=" << d_to_curr_l << std::endl; + while (d_to_curr_l > alpha + ed.transformed_distance(w, landmarks[*(ope_queue.front())])) + { + ope_limits[i].push_back(wl_it); + ope_queue.pop(); + } + } + while (ope_queue.size() > 0) + { + ope_limits[i].push_back(WL[i].end()); + ope_queue.pop(); + } + //std::cout << "Safely constructed a point\n"; + ////Search D+1 nearest neighbours from the tree of landmarks L + /* + if (w[0]>0.95) + std::cout << i << std::endl; + */ + //K_neighbor_search search(L, w, D, FT(0), true, + // CGAL::Distance_adapter(&(landmarks[0])) ); + //std::cout << "Safely found nearest landmarks\n"; + /* + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + //Point_etiquette_map::iterator itm = L_i.find(it->first); + //assert(itm != L_i.end()); + //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; + WL[i].push_back(it->first); + //std::cout << "ITFIRST " << it->first << std::endl; + //std::cout << i << " " << it->first << ": " << it->second << std::endl; + } + */ + } + //std::cout << "\n"; + + //std::string out_file = "wl_result"; + write_wl("wl_result",WL); + write_rl("rl_result",ope_limits); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.relaxed_witness_complex(WL, ope_limits); + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + std::cout << Distance().transformed_distance(Point_d(std::vector({0.1,0.1})), Point_d(std::vector({1.9,1.9}))) << std::endl; +} + + +int main (int argc, char * const argv[]) +{ + + if (argc != 5) + { + std::cerr << "Usage: " << argv[0] + << " nbP nbL dim alpha\n"; + return 0; + } + /* + boost::filesystem::path p; + for (; argc > 2; --argc, ++argv) + p /= argv[1]; + */ + + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); + double alpha = atof(argv[4]); + //clock_t start, end; + //Construct the Simplex Tree + Witness_complex<> witnessComplex; + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + //read_points_cust(file_name, point_vector); + generate_points_sphere(point_vector, nbP, dim); + /* + for (auto &p: point_vector) + { + assert(std::count(point_vector.begin(),point_vector.end(),p) == 1); + } + */ + //std::cout << "Successfully read the points\n"; + //witnessComplex.setNbL(nbL); + Point_Vector L; + std::vector chosen_landmarks; + landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + //start = clock(); + + write_points("landmarks/initial_pointset",point_vector); + write_points("landmarks/initial_landmarks",L); + + landmarks_to_witness_complex(point_vector, L, chosen_landmarks, alpha); + //end = clock(); + + /* + std::cout << "Landmark choice took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + start = clock(); + witnessComplex.witness_complex(WL); + // + end = clock(); + std::cout << "Howdy world! The process took " + << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; + */ + + /* + out_file = "output/"+file_name+"_"+argv[2]+".stree"; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + + out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; + std::ofstream ofs2(out_file, std::ofstream::out); + witnessComplex.write_bad_links(ofs2); + ofs2.close(); + */ +} diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index 14d6426d..42bf5e7e 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -323,7 +323,20 @@ read_points_cust ( std::string file_name , Point_Vector & points) void generate_points_grid(Point_Vector& W, int width, int D) { - + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(0.01*(cell_i%width)); + cell_i /= width; + } + W.push_back(point); + } } void generate_points_random_box(Point_Vector& W, int nbP, int dim) @@ -490,8 +503,8 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, { // while (!res.second) // { - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) - chosen_landmark = rand.get_int(0,nbP); + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; @@ -717,7 +730,9 @@ int main (int argc, char * const argv[]) std::cout << "Let the carnage begin!\n"; Point_Vector point_vector; //read_points_cust(file_name, point_vector); - generate_points_random_box(point_vector, nbP, dim); + //generate_points_random_box(point_vector, nbP, dim); + generate_points_grid(point_vector, (int)pow(nbP, 1.0/dim), dim); + nbP = (int)(pow((int)pow(nbP, 1.0/dim), dim)); /* for (auto &p: point_vector) { diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index ec7a5abe..88a7510a 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -194,7 +194,7 @@ void write_edges_gnuplot(std::string file_name, Witness_complex<>& witness_compl /** Function that chooses landmarks from W and place it in the kd-tree L. * Note: nbL hould be removed if the code moves to Witness_complex */ - +/* void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) { std::cout << "Enter landmark choice to kd tree\n"; @@ -216,12 +216,13 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, //std::cout << "Added landmark " << chosen_landmark << std::endl; } } -/* +*/ + void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) { std::cout << "Enter landmark choice to kd tree\n"; //std::vector landmarks; - int chosen_landmark; + int chosen_landmark = 0; //std::pair res = std::make_pair(L_i.begin(),false); Point_d* p; CGAL::Random rand; @@ -229,9 +230,9 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, { // while (!res.second) // { - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0) - chosen_landmark = rand.get_int(0,nbP); - //rand++; + do chosen_landmark = rand.uniform_int(0,nbP); + while (std::find(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark) != landmarks_ind.end()); + //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; //L_i.emplace(chosen_landmark,i); @@ -241,7 +242,7 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, //std::cout << "Added landmark " << chosen_landmark << std::endl; } } -*/ + int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) { @@ -417,7 +418,8 @@ int main (int argc, char * const argv[]) } //write_points("landmarks/initial_pointset",point_vector); write_points("landmarks/initial_landmarks",L); - for (int i = 0; bl != 0; i++) + //for (int i = 0; bl != 0; i++) + for (int i = 0; i < 1; i++) { std::cout << "========== Start iteration " << i << " ========\n"; bl = landmark_perturbation(point_vector, L, chosen_landmarks); diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index f6345411..f2bb9819 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -489,8 +489,7 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, { // while (!res.second) // { - do - chosen_landmark = rand.get_int(0,nbP); + do chosen_landmark = rand.get_int(0,nbP); while (std::find(landmarks_ind.begin(), landmarks_ind.end(), chosen_landmark) != landmarks_ind.end()); //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; -- cgit v1.2.3 From 36a355eb8756a8eb6bdc3e9cad4283d89da4f7f6 Mon Sep 17 00:00:00 2001 From: skachano Date: Sat, 13 Jun 2015 12:29:09 +0000 Subject: Tweaked a bit Witness_complex.h + simplex count git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@612 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 69c0f87a15a44e438750acfd158495713789feee --- .../include/gudhi/Witness_complex.h | 170 +++++++++++++++++++-- 1 file changed, 156 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 8b87ae89..04fcc98f 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -165,6 +165,7 @@ namespace Gudhi { // PRINT2 //print_sc(root()); std::cout << std::endl; int u,v; // two extremities of an edge + int count = 0; if (nbL > 1) // if the supposed dimension of the complex is >0 { for (int i=0; i != nbW; ++i) @@ -174,9 +175,13 @@ namespace Gudhi { v = knn[i][1]; vv = {u,v}; returnValue = this->insert_simplex(vv,Filtration_value(0.0)); + if (returnValue.second) + count++; //print_sc(root()); std::cout << std::endl; //std::cout << "Added edges" << std::endl; } + std::cout << "The number of edges = " << count << std::endl; + count = 0; //print_sc(root()); for (int i=0; i != nbW; ++i) { @@ -206,6 +211,7 @@ namespace Gudhi { { count_good.push_back(0); count_bad.push_back(0); + count++; //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) @@ -220,12 +226,15 @@ namespace Gudhi { for (int i = 0; i != k+1; ++i) simplex_vector.push_back(knn[*it][i]); returnValue = insert_simplex(simplex_vector,0.0); + if (returnValue.second) + count++; it++; } else active_w.erase(it++); //First increase the iterator and then erase the previous element } std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; + std::cout << "** k=" << k << ", num_simplices: " < Reference; typedef boost::graph_traits::vertex_descriptor Vertex_t; typedef boost::graph_traits::edge_descriptor Edge_t; + typedef boost::graph_traits::adjacency_iterator Adj_it; + typedef std::pair Out_edge_it; typedef boost::container::flat_map Graph_map; - + typedef boost::container::flat_map Inv_graph_map; + /* \brief Verifies if the simplices formed by vertices given by link_vertices * form a pseudomanifold. * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional @@ -800,15 +812,75 @@ private: //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; if (boost::out_degree(f_map_it.second, adj_graph) != 2) { - /* - if (boost::out_degree(f_map_it.second, adj_graph) == 3) + /* + if (boost::out_degree(f_map_it.second, adj_graph) >= 3) + { + std::cout << "This simplex has 3+ cofaces: "; + for(auto v : simplex_vertex_range(f_map_it.first)) + std::cout << v << " "; + std::cout << std::endl; + Adj_it ai, ai_end; + for (std::tie(ai, ai_end) = boost::adjacent_vertices(f_map_it.second, adj_graph); ai != ai_end; ++ai) + { + + } + } + */ + count_bad[dimension]++; + return false; + } + } + // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices + // What is left is to check the connexity + //std::vector components(boost::num_vertices(adj_graph)); + return true; //Forget the connexity + //return (boost::connected_components(adj_graph, &components[0]) == 1); + } + + public: +bool complex_is_pseudomanifold(int dimension) + { + Adj_graph adj_graph; + Graph_map d_map, f_map; // d_map = map for d-dimensional simplices + // f_map = map for its facets + Inv_graph_map inv_d_map; + typeVectorVertex init_vector = {}; + std::vector star_vertices; + for (int v: complex_vertex_range()) + star_vertices.push_back(v); + add_max_simplices_to_graph(star_vertices, + star_vertices.begin(), + adj_graph, + d_map, + f_map, + inv_d_map, + init_vector, + 0, dimension); + std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; + std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; + add_edges_to_link_graph(adj_graph, d_map, f_map); + for (auto f_map_it : f_map) + { + //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; + if (boost::out_degree(f_map_it.second, adj_graph) != 2) + { + if (boost::out_degree(f_map_it.second, adj_graph) >= 3) { - std::cout << "This simplex has 3 cofaces: "; + std::cout << "This simplex has 3+ cofaces: "; for(auto v : simplex_vertex_range(f_map_it.first)) std::cout << v << " "; std::cout << std::endl; - - }*/ + Adj_it ai, ai_end; + for (std::tie(ai, ai_end) = boost::adjacent_vertices(f_map_it.second, adj_graph); ai != ai_end; ++ai) + { + auto it = inv_d_map.find(*ai); + assert (it != inv_d_map.end()); + Simplex_handle sh = it->second; + for(auto v : simplex_vertex_range(sh)) + std::cout << v << " "; + std::cout << std::endl; + } + } count_bad[dimension]++; return false; } @@ -820,6 +892,7 @@ private: //return (boost::connected_components(adj_graph, &components[0]) == 1); } + private: void add_vertices_to_link_graph(typeVectorVertex& star_vertices, typename typeVectorVertex::iterator curr_v, Adj_graph& adj_graph, @@ -858,21 +931,18 @@ private: assert(sh != null_simplex()); //ASSERT! vert = boost::add_vertex(adj_graph); d_map.emplace(sh,vert); - for (Simplex_handle sh_b: boundary_simplex_range(sh)) - { - vert = boost::add_vertex(adj_graph); - f_map.emplace(sh_b,vert); - } } else { - /* + if (curr_d == link_dimension-1) { + sh = find(curr_simplex_copy); //a simplex of the link + assert(sh != null_simplex()); vert = boost::add_vertex(adj_graph); - resPair = f_map.emplace(sh,vert); + f_map.emplace(sh,vert); } - */ + //delete (&curr_simplex_copy); //Just so it doesn't stack add_vertices_to_link_graph(star_vertices, it+1, @@ -917,6 +987,78 @@ private: } } } + + void add_max_simplices_to_graph(typeVectorVertex& star_vertices, + typename typeVectorVertex::iterator curr_v, + Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map, + Inv_graph_map& inv_d_map, + typeVectorVertex& curr_simplex, + int curr_d, + int link_dimension) + { + Simplex_handle sh; + Vertex_t vert; + typename typeVectorVertex::iterator it; + //std::pair resPair; + //typename Graph_map::iterator resPair; + //Add vertices + //std::cout << "Entered add vertices\n"; + for (it = curr_v; it != star_vertices.end(); ++it) + { + curr_simplex.push_back(*it); //push next vertex in question + //curr_simplex.push_back(star_vertices[0]); //push the center of the star + /* + std::cout << "Searching for "; + print_vector(curr_simplex); + std::cout << " curr_dim " << curr_d << " d " << dimension << ""; + */ + typeVectorVertex curr_simplex_copy(curr_simplex); + sh = find(curr_simplex_copy); //a simplex of the star + //curr_simplex.pop_back(); //pop the center of the star + curr_simplex_copy = typeVectorVertex(curr_simplex); + if (sh != null_simplex()) + { + //std::cout << " added\n"; + if (curr_d == link_dimension) + { + sh = find(curr_simplex_copy); //a simplex of the link + assert(sh != null_simplex()); //ASSERT! + vert = boost::add_vertex(adj_graph); + d_map.emplace(sh,vert); + inv_d_map.emplace(vert,sh); + } + else + { + + if (curr_d == link_dimension-1) + { + sh = find(curr_simplex_copy); //a simplex of the link + assert(sh != null_simplex()); + vert = boost::add_vertex(adj_graph); + f_map.emplace(sh,vert); + } + + //delete (&curr_simplex_copy); //Just so it doesn't stack + add_max_simplices_to_graph(star_vertices, + it+1, + adj_graph, + d_map, + f_map, + inv_d_map, + curr_simplex, + curr_d+1, link_dimension); + } + } + /* + else + std::cout << "\n"; + */ + curr_simplex.pop_back(); //pop the vertex in question + } + } + }; //class Witness_complex -- cgit v1.2.3 From c88e3b93de22be92cc7027f4c14ea4294f8c366f Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 16 Jun 2015 09:36:00 +0000 Subject: Fixed the changing WL matrix bug in witness complex. Added is_witness_complex test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@615 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 60917e75766b53d08240b510c0508e7d781b56d6 --- .../example/relaxed_witness_complex_sphere.cpp | 1 + .../example/witness_complex_sphere.cpp | 10 +- .../include/gudhi/Relaxed_witness_complex.h | 886 +++++++++++++++++++++ .../include/gudhi/Witness_complex.h | 93 ++- 4 files changed, 962 insertions(+), 28 deletions(-) create mode 100644 src/Witness_complex/include/gudhi/Relaxed_witness_complex.h (limited to 'src') diff --git a/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp b/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp index 53380124..067321ce 100644 --- a/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp +++ b/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp @@ -36,6 +36,7 @@ //#include "gudhi/graph_simplicial_complex.h" #include "gudhi/Relaxed_witness_complex.h" #include "gudhi/reader_utils.h" +#include "gudhi/Collapse/Collapse.h" //#include //#include diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index f2bb9819..d08c763f 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -578,6 +578,10 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< Witness_complex<> witnessComplex; witnessComplex.setNbL(nbL); witnessComplex.witness_complex(WL); + if (witnessComplex.is_witness_complex(WL)) + std::cout << "!!YES. IT IS A WITNESS COMPLEX!!\n"; + else + std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n"; //******************** Making a set of bad link landmarks std::cout << "Entered bad links\n"; std::set< int > perturbL; @@ -614,7 +618,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< for (auto u: perturbL) { - Random_point_iterator rp(D,sqrt(lambda)/8); + Random_point_iterator rp(D,sqrt(lambda)/8*nbL/count_badlinks); //std::cout << landmarks[u] << std::endl; std::vector point; @@ -721,8 +725,8 @@ int main (int argc, char * const argv[]) write_points("landmarks/initial_pointset",point_vector); write_points("landmarks/initial_landmarks",L); - for (int i = 0; bl > 0; i++) - //for (int i = 0; i < 1; i++) + //for (int i = 0; bl > 0; i++) + for (int i = 0; i < 1; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); diff --git a/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h b/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h new file mode 100644 index 00000000..c869628f --- /dev/null +++ b/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h @@ -0,0 +1,886 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_RELAXED_WITNESS_COMPLEX_H_ +#define GUDHI_RELAXED_WITNESS_COMPLEX_H_ + +#include +#include +#include +#include +#include "gudhi/reader_utils.h" +#include "gudhi/distance_functions.h" +#include "gudhi/Simplex_tree.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// Needed for nearest neighbours +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// Needed for the adjacency graph in bad link search +#include +#include +#include + +namespace Gudhi { + + + /** \addtogroup simplex_tree + * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: + * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ + * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that + * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. + */ + template + class Witness_complex: public Simplex_tree<> { + + private: + + struct Active_witness { + int witness_id; + int landmark_id; + Simplex_handle simplex_handle; + + Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + : witness_id(witness_id_), + landmark_id(landmark_id_), + simplex_handle(simplex_handle_) + {} + }; + + + + + public: + + + /** \brief Type for the vertex handle. + * + * Must be a signed integer type. It admits a total order <. */ + typedef VertexHandle Vertex_handle; + + /* Type of node in the simplex tree. */ + typedef Simplex_tree_node_explicit_storage Node; + /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ + typedef typename boost::container::flat_map Dictionary; + typedef typename Dictionary::iterator Simplex_handle; + + typedef std::vector< double > Point_t; + typedef std::vector< Point_t > Point_Vector; + + typedef std::vector< Vertex_handle > typeVectorVertex; + typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; + typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + + typedef int Witness_id; + typedef int Landmark_id; + typedef std::list< Vertex_handle > ActiveWitnessList; + + private: + /** Number of landmarks + */ + int nbL; + /** Desired density + */ + double density; + + public: + + /** \brief Set number of landmarks to nbL_ + */ + void setNbL(int nbL_) + { + nbL = nbL_; + } + + /** \brief Set density to density_ + */ + void setDensity(double density_) + { + density = density_; + } + + /** + * /brief Iterative construction of the relaxed witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks} and (1+epsilon)-limit table {witnesses}*{landmarks} consisting of iterators of k nearest neighbor matrix. + * The line lengths can differ, however both matrices have the same corresponding line lengths. + */ + + template< typename KNearestNeighbours, typename OPELimits > + void relaxed_witness_complex(KNearestNeighbours & knn, OPELimits & rl) + //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) + { + std::cout << "**Start the procedure witness_complex" << std::endl; + //Construction of the active witness list + int nbW = knn.size(); + //int nbL = knn.at(0).size(); + typeVectorVertex vv; + //typeSimplex simplex; + //typePairSimplexBool returnValue; + //int counter = 0; + /* The list of still useful witnesses + * it will diminuish in the course of iterations + */ + ActiveWitnessList active_w;// = new ActiveWitnessList(); + for (int i=0; i != nbL; ++i) { + // initial fill of 0-dimensional simplices + // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore + //counter++; + vv = {i}; + insert_simplex(vv, Filtration_value(0.0)); + /* TODO Error if not inserted : normally no need here though*/ + } + int k=1; /* current dimension in iterative construction */ + //std::cout << "Successfully added landmarks" << std::endl; + // PRINT2 + //print_sc(root()); std::cout << std::endl; + for (int i=0; i != nbW; ++i) + active_w.push_back(i); + /* + int u,v; // two extremities of an edge + if (nbL > 1) // if the supposed dimension of the complex is >0 + { + for (int i=0; i != nbW; ++i) + { + // initial fill of active witnesses list + u = knn[i][0]; + v = knn[i][1]; + vv = {u,v}; + this->insert_simplex(vv,Filtration_value(0.0)); + //print_sc(root()); std::cout << std::endl; + //std::cout << "Added edges" << std::endl; + } + //print_sc(root()); + + } + */ + std::cout << "k=0, active witnesses: " << active_w.size() << std::endl; + //std::cout << "Successfully added edges" << std::endl; + //count_good = {0,0}; + //count_bad = {0,0}; + while (!active_w.empty() && k < nbL ) + { + //count_good.push_back(0); + //count_bad.push_back(0); + //std::cout << "Started the step k=" << k << std::endl; + typename ActiveWitnessList::iterator aw_it = active_w.begin(); + while (aw_it != active_w.end()) + { + std::vector simplex; + bool ok = add_all_faces_of_dimension(k, knn[*aw_it].begin(), rl[*aw_it].begin(), simplex, knn[*aw_it].end(), knn[*aw_it].end()); + if (!ok) + active_w.erase(aw_it++); //First increase the iterator and then erase the previous element + else + aw_it++; + } + std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; + k++; + } + //print_sc(root()); std::cout << std::endl; + } + + /* \brief Adds recursively all the faces of a certain dimension dim witnessed by the same witness + * Iterator is needed to know until how far we can take landmarks to form simplexes + * simplex is the prefix of the simplexes to insert + * The output value indicates if the witness rests active or not + */ + bool add_all_faces_of_dimension(int dim, std::vector::iterator curr_l, typename std::vector< std::vector::iterator >::iterator curr_until, std::vector& simplex, std::vector::iterator until, std::vector::iterator end) + { + /* + std::ofstream ofs ("stree_result.txt", std::ofstream::out); + st_to_file(ofs); + ofs.close(); + */ + //print_sc(root()); + bool will_be_active = false; + if (dim > 0) + for (std::vector::iterator it = curr_l; it != until && it != end; ++it, ++curr_until) + { + simplex.push_back(*it); + if (find(simplex) != null_simplex()) + will_be_active = will_be_active || add_all_faces_of_dimension(dim-1, it+1, curr_until+1, simplex, until, end); + simplex.pop_back(); + if (until == end) + until = *curr_until; + } + else if (dim == 0) + for (std::vector::iterator it = curr_l; it != until && it != end; ++it, ++curr_until) + { + simplex.push_back(*it); + if (all_faces_in(simplex)) + { + will_be_active = true; + insert_simplex(simplex, 0.0); + } + simplex.pop_back(); + if (until == end) + until = *curr_until; + } + return will_be_active; + } + + /** \brief Construction of witness complex from points given explicitly + * nbL must be set to the right value of landmarks for strategies + * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and + * density must be set to the right value for DENSITY_STRATEGY + */ + // void witness_complex_from_points(Point_Vector point_vector) + // { + // std::vector > WL; + // landmark_choice_by_random_points(point_vector, point_vector.size(), WL); + // witness_complex(WL); + // } + +private: + + /** \brief Print functions + */ + void print_sc(Siblings * sibl) + { + if (sibl == NULL) + std::cout << "&"; + else + print_children(sibl->members_); + } + + void print_children(Dictionary map) + { + std::cout << "("; + if (!map.empty()) + { + std::cout << map.begin()->first; + if (has_children(map.begin())) + print_sc(map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + std::cout << "," << it->first; + if (has_children(it)) + print_sc(it->second.children()); + } + } + std::cout << ")"; + } + + public: + /** \brief Print functions + */ + + void st_to_file(std::ofstream& out_file) + { + sc_to_file(out_file, root()); + } + + private: + void sc_to_file(std::ofstream& out_file, Siblings * sibl) + { + assert(sibl); + children_to_file(out_file, sibl->members_); + } + + void children_to_file(std::ofstream& out_file, Dictionary& map) + { + out_file << "(" << std::flush; + if (!map.empty()) + { + out_file << map.begin()->first << std::flush; + if (has_children(map.begin())) + sc_to_file(out_file, map.begin()->second.children()); + typename Dictionary::iterator it; + for (it = map.begin()+1; it != map.end(); ++it) + { + out_file << "," << it->first << std::flush; + if (has_children(it)) + sc_to_file(out_file, it->second.children()); + } + } + out_file << ")" << std::flush; + } + + + /** \brief Check if the facets of the k-dimensional simplex witnessed + * by witness witness_id are already in the complex. + * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id + */ + bool all_faces_in(std::vector& simplex) + { + //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; + std::vector< VertexHandle > facet; + //VertexHandle curr_vh = curr_sh->first; + // CHECK ALL THE FACETS + for (std::vector::iterator not_it = simplex.begin(); not_it != simplex.end(); ++not_it) + { + facet.clear(); + //facet = {}; + for (std::vector::iterator it = simplex.begin(); it != simplex.end(); ++it) + if (it != not_it) + facet.push_back(*it); + if (find(facet) == null_simplex()) + return false; + } //endfor + return true; + } + + template + void print_vector(std::vector v) + { + std::cout << "["; + if (!v.empty()) + { + std::cout << *(v.begin()); + for (auto it = v.begin()+1; it != v.end(); ++it) + { + std::cout << ","; + std::cout << *it; + } + } + std::cout << "]"; + } + + template + void print_vvector(std::vector< std::vector > vv) + { + std::cout << "["; + if (!vv.empty()) + { + print_vector(*(vv.begin())); + for (auto it = vv.begin()+1; it != vv.end(); ++it) + { + std::cout << ","; + print_vector(*it); + } + } + std::cout << "]\n"; + } + + public: +/** + * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the + * current landmark set + * \arg W is the vector of points which will be the witnesses + * \arg nbP is the number of witnesses + * \arg nbL is the number of landmarks + * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) + */ + + template + void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + { + //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; + //std::cout << "W="; print_vvector(W); + //double density = 5.; + Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + typeVectorVertex chosen_landmarks; // landmark list + + WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + double curr_max_dist = 0; // used for defining the furhest point from L + double curr_dist; // used to stock the distance from the current point to L + double infty = std::numeric_limits::infinity(); // infinity (see next entry) + std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points + // double mindist = infty; + int curr_max_w=0; // the point currently furthest from L + int j; + int temp_swap_int; + double temp_swap_double; + + //CHOICE OF THE FIRST LANDMARK + std::cout << "Enter the first landmark stage\n"; + srand(354698); + int rand_int = rand()% nbP; + curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + //curr_max_w at this point is the next landmark + chosen_landmarks.push_back(curr_max_w); + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + for (auto v: WL) + v.push_back(current_number_of_landmarks); + for (int i = 0; i < nbP; ++i) + { + // iteration on points in W. update of distance vectors + + //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); + //std::cout << "The problem is not in distance function\n"; + wit_land_dist[i].push_back(curr_dist); + WL[i].push_back(current_number_of_landmarks); + //std::cout << "Push't back\n"; + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + j = current_number_of_landmarks; + //std::cout << "First half complete\n"; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + // sort the closest landmark vector for every witness + temp_swap_int = WL[i][j]; + WL[i][j] = WL[i][j-1]; + WL[i][j-1] = temp_swap_int; + temp_swap_double = wit_land_dist[i][j]; + wit_land_dist[i][j] = wit_land_dist[i][j-1]; + wit_land_dist[i][j-1] = temp_swap_double; + --j; + } + //std::cout << "result WL="; print_vvector(WL); + //std::cout << "result WLD="; print_vvector(wit_land_dist); + //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; + //std::cout << "End loop\n"; + } + //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; + curr_max_dist = 0; + for (int i = 0; i < nbP; ++i) { + if (dist_to_L[i] > curr_max_dist) + { + curr_max_dist = dist_to_L[i]; + curr_max_w = i; + } + } + //std::cout << "Chose " << curr_max_w << " as new landmark\n"; + } + //std::cout << endl; + } + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * + */ + + // template + // void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) + // { + // std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + // //std::cout << "W="; print_vvector(W); + // std::unordered_set< int > chosen_landmarks; // landmark set + + // Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + + // WL = KNearestNeighbours(nbP,std::vector()); + // int current_number_of_landmarks=0; // counter for landmarks + + // srand(24660); + // int chosen_landmark = rand()%nbP; + // double curr_dist; + + // //int j; + // //int temp_swap_int; + // //double temp_swap_double; + + + // for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + // { + // while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) + // { + // srand((int)clock()); + // chosen_landmark = rand()% nbP; + // //std::cout << chosen_landmark << "\n"; + // } + // chosen_landmarks.insert(chosen_landmark); + // //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + // //std::cout << "WL="; print_vvector(WL); + // //std::cout << "WLD="; print_vvector(wit_land_dist); + // //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + // for (auto v: WL) + // v.push_back(current_number_of_landmarks); + // for (int i = 0; i < nbP; ++i) + // { + // // iteration on points in W. update of distance vectors + + // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + // //std::cout << "The problem is not in distance function\n"; + // wit_land_dist[i].push_back(curr_dist); + // WL[i].push_back(current_number_of_landmarks); + // //std::cout << "Push't back\n"; + // //j = current_number_of_landmarks; + // //std::cout << "First half complete\n"; + // //std::cout << "result WL="; print_vvector(WL); + // //std::cout << "result WLD="; print_vvector(wit_land_dist); + // //std::cout << "End loop\n"; + // } + // } + // for (int i = 0; i < nbP; i++) + // { + // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + // } + // //std::cout << endl; + // } + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * + */ + + // template + void landmark_choice_by_random_points(Point_Vector &W, int nbP, std::set &L) + { + std::cout << "Enter landmark_choice_by_random_points "<< std::endl; + //std::cout << "W="; print_vvector(W); + //std::unordered_set< int > chosen_landmarks; // landmark set + + //Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks + + //WL = KNearestNeighbours(nbP,std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + + srand(24660); + int chosen_landmark = rand()%nbP; + //double curr_dist; + //int j; + //int temp_swap_int; + //double temp_swap_double; + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + while (L.find(chosen_landmark) != L.end()) + { + srand((int)clock()); + chosen_landmark = rand()% nbP; + //std::cout << chosen_landmark << "\n"; + } + L.insert(chosen_landmark); + //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; + //std::cout << "WL="; print_vvector(WL); + //std::cout << "WLD="; print_vvector(wit_land_dist); + //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; + // for (auto v: WL) + // v.push_back(current_number_of_landmarks); + // for (int i = 0; i < nbP; ++i) + // { + // // iteration on points in W. update of distance vectors + + // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; + // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; + // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); + // //std::cout << "The problem is not in distance function\n"; + // wit_land_dist[i].push_back(curr_dist); + // WL[i].push_back(current_number_of_landmarks); + // //std::cout << "Push't back\n"; + // //j = current_number_of_landmarks; + // //std::cout << "First half complete\n"; + // //std::cout << "result WL="; print_vvector(WL); + // //std::cout << "result WLD="; print_vvector(wit_land_dist); + // //std::cout << "End loop\n"; + // } + } + // for (int i = 0; i < nbP; i++) + // { + // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); + // } + //std::cout << endl; + } + + + /** \brief Construct the matrix |W|x(D+1) of D+1 closest landmarks + * where W is the set of witnesses and D is the ambient dimension + */ + template + void nearest_landmarks(Point_Vector &W, std::set &L, KNearestNeighbours &WL) + { + int D = W[0].size(); + int nbP = W.size(); + WL = KNearestNeighbours(nbP,std::vector()); + typedef std::pair dist_i; + typedef bool (*comp)(dist_i,dist_i); + for (int W_i = 0; W_i < nbP; W_i++) + { + //std::cout << "<<<<<<<<<<<<<<" << W_i <<"\n"; + std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); + std::set::iterator L_it; + int L_i; + for (L_it = L.begin(), L_i=0; L_it != L.end(); L_it++, L_i++) + { + dist_i dist = std::make_pair(euclidean_distance(W[W_i],W[*L_it]), L_i); + l_heap.push(dist); + } + for (int i = 0; i < D+1; i++) + { + dist_i dist = l_heap.top(); + WL[W_i].push_back(dist.second); + //WL[W_i].insert(WL[W_i].begin(),dist.second); + //std::cout << dist.first << " " << dist.second << std::endl; + l_heap.pop(); + } + } + } + + /** \brief Search and output links around vertices that are not pseudomanifolds + * + */ + void write_bad_links(std::ofstream& out_file) + { + out_file << "Bad links list\n"; + std::cout << "Entered write_bad_links\n"; + //typeVectorVertex testv = {9,15,17}; + //int count = 0; + for (auto v: complex_vertex_range()) + { + //std::cout << "Vertex " << v << ":\n"; + std::vector< Vertex_handle > link_vertices; + // Fill link_vertices + for (auto u: complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u != v && find(edge) != null_simplex()) + link_vertices.push_back(u); + } + /* + print_vector(link_vertices); + std::cout << "\n"; + */ + // Find the dimension + typeVectorVertex empty_simplex = {}; + int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); + //std::cout << " dim " << d << "\n"; + //Siblings* curr_sibl = root(); + if (link_is_pseudomanifold(link_vertices,d)) + count_good[d]++; + //out_file << "Bad link at " << v << "\n"; + } + //out_file << "Number of bad links: " << count << "/" << root()->size(); + //std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; + nc = nbL; + for (unsigned int i = 0; i != count_good.size(); i++) + { + out_file << "count_good[" << i << "] = " << count_good[i] << std::endl; + nc -= count_good[i]; + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + } + for (unsigned int i = 0; i != count_bad.size(); i++) + { + out_file << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + nc -= count_bad[i]; + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + } + std::cout << "not_connected = " << nc << std::endl; + } + + private: + + std::vector count_good; + std::vector count_bad; + int nc; + + int link_dim(std::vector< Vertex_handle >& link_vertices, + typename std::vector< Vertex_handle >::iterator curr_v, + int curr_d, + typeVectorVertex& curr_simplex) + { + //std::cout << "Entered link_dim for " << *(curr_v-1) << "\n"; + Simplex_handle sh; + int final_d = curr_d; + typename std::vector< Vertex_handle >::iterator it; + for (it = curr_v; it != link_vertices.end(); ++it) + { + curr_simplex.push_back(*it); + /* + std::cout << "Searching for "; + print_vector(curr_simplex); + std::cout << " curr_dim " << curr_d << " final_dim " << final_d; + */ + sh = find(curr_simplex); + if (sh != null_simplex()) + { + //std::cout << " -> " << *it << "\n"; + int d = link_dim(link_vertices, it+1, curr_d+1, curr_simplex); + if (d > final_d) + final_d = d; + } + /* + else + std::cout << "\n"; + */ + curr_simplex.pop_back(); + } + return final_d; + } + + // color is false is a (d-1)-dim face, true is a d-dim face + //typedef bool Color; + // graph is an adjacency list + typedef typename boost::adjacency_list Adj_graph; + // map that gives to a certain simplex its node in graph and its dimension + //typedef std::pair Reference; + typedef boost::graph_traits::vertex_descriptor Vertex_t; + typedef boost::graph_traits::edge_descriptor Edge_t; + + typedef boost::container::flat_map Graph_map; + + /* \brief Verifies if the simplices formed by vertices given by link_vertices + * form a pseudomanifold. + * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional + * faces and edges represent adjacency between them. + */ + bool link_is_pseudomanifold(std::vector< Vertex_handle >& link_vertices, + int dimension) + { + Adj_graph adj_graph; + Graph_map d_map, f_map; // d_map = map for d-dimensional simplices + // f_map = map for its facets + typeVectorVertex empty_vector = {}; + add_vertices(link_vertices, + link_vertices.begin(), + adj_graph, + d_map, + f_map, + empty_vector, + 0, dimension); + //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; + //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; + add_edges(adj_graph, d_map, f_map); + for (auto f_map_it : f_map) + { + //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; + if (boost::out_degree(f_map_it.second, adj_graph) != 2) + { + count_bad[dimension]++; + return false; + } + } + // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices + // What is left is to check the connexity + std::vector components(boost::num_vertices(adj_graph)); + return (boost::connected_components(adj_graph, &components[0]) == 1); + } + + void add_vertices(typeVectorVertex& link_vertices, + typename typeVectorVertex::iterator curr_v, + Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map, + typeVectorVertex& curr_simplex, + int curr_d, + int dimension) + { + Simplex_handle sh; + Vertex_t vert; + typename typeVectorVertex::iterator it; + std::pair resPair; + //typename Graph_map::iterator resPair; + //Add vertices + //std::cout << "Entered add vertices\n"; + for (it = curr_v; it != link_vertices.end(); ++it) + { + curr_simplex.push_back(*it); + /* + std::cout << "Searching for "; + print_vector(curr_simplex); + std::cout << " curr_dim " << curr_d << " d " << dimension << ""; + */ + sh = find(curr_simplex); + if (sh != null_simplex()) + { + //std::cout << " added\n"; + if (curr_d == dimension) + { + vert = boost::add_vertex(adj_graph); + resPair = d_map.emplace(sh,vert); + } + else + { + if (curr_d == dimension-1) + { + vert = boost::add_vertex(adj_graph); + resPair = f_map.emplace(sh,vert); + } + add_vertices(link_vertices, + it+1, + adj_graph, + d_map, + f_map, + curr_simplex, + curr_d+1, dimension); + } + } + /* + else + std::cout << "\n"; + */ + curr_simplex.pop_back(); + } + } + + void add_edges(Adj_graph& adj_graph, + Graph_map& d_map, + Graph_map& f_map) + { + Simplex_handle sh; + // Add edges + //std::cout << "Entered add edges:\n"; + typename Graph_map::iterator map_it; + for (auto d_map_pair : d_map) + { + //std::cout << "*"; + sh = d_map_pair.first; + Vertex_t d_vert = d_map_pair.second; + for (auto facet_sh : boundary_simplex_range(sh)) + //for (auto f_map_it : f_map) + { + //std::cout << "'"; + map_it = f_map.find(facet_sh); + //We must have all the facets in the graph at this point + assert(map_it != f_map.end()); + Vertex_t f_vert = map_it->second; + //std::cout << "Added edge " << sh->first << "-" << map_it->first->first << "\n"; + boost::add_edge(d_vert,f_vert,adj_graph); + } + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////////// + //***********COLLAPSES**************************************************************************// + ////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + + + +}; //class Witness_complex + + + +} // namespace Guhdi + +#endif diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 04fcc98f..201d6525 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -140,7 +140,6 @@ namespace Gudhi { //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) { std::cout << "**Start the procedure witness_complex" << std::endl; - int k=2; /* current dimension in iterative construction */ //Construction of the active witness list int nbW = knn.size(); //int nbL = knn.at(0).size(); @@ -157,13 +156,14 @@ namespace Gudhi { // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; vv = {i}; - /* TODO Filtration */ returnValue = insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ } + int k=1; /* current dimension in iterative construction */ //std::cout << "Successfully added landmarks" << std::endl; // PRINT2 //print_sc(root()); std::cout << std::endl; + /* int u,v; // two extremities of an edge int count = 0; if (nbL > 1) // if the supposed dimension of the complex is >0 @@ -202,39 +202,37 @@ namespace Gudhi { active_w.push_back(i); } } - std::cout << "k=1, active witnesses: " << active_w.size() << std::endl; + */ + for (int i=0; i != nbW; ++i) + active_w.push_back(i); + std::cout << "k=0, active witnesses: " << active_w.size() << std::endl; //std::cout << "Successfully added edges" << std::endl; - count_good = {0,0}; - count_bad = {0,0}; + count_good = {0}; + count_bad = {0}; int D = knn[0].size(); while (!active_w.empty() && k < D ) { count_good.push_back(0); count_bad.push_back(0); - count++; //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { typeVectorVertex simplex_vector; /* THE INSERTION: Checking if all the subfaces are in the simplex tree*/ - // First sort the first k landmarks - VertexHandle inserted_vertex = knn[*it][k]; - bool ok = all_faces_in(knn, *it, k, inserted_vertex); + bool ok = all_faces_in(knn, *it, k); if (ok) { for (int i = 0; i != k+1; ++i) simplex_vector.push_back(knn[*it][i]); returnValue = insert_simplex(simplex_vector,0.0); - if (returnValue.second) - count++; it++; } else active_w.erase(it++); //First increase the iterator and then erase the previous element } std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; - std::cout << "** k=" << k << ", num_simplices: " < - bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k, VertexHandle inserted_vertex) + bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k) { //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; std::vector< VertexHandle > facet; @@ -332,20 +330,17 @@ private: // CHECK ALL THE FACETS for (int i = 0; i != k+1; ++i) { - if (knn[witness_id][i] != inserted_vertex) + facet = {}; + for (int j = 0; j != k+1; ++j) { - facet = {}; - for (int j = 0; j != k+1; ++j) + if (j != i) { - if (j != i) - { - facet.push_back(knn[witness_id][j]); - } - }//endfor - if (find(facet) == null_simplex()) - return false; - //std::cout << "++++ finished loop safely\n"; - }//endif + facet.push_back(knn[witness_id][j]); + } + }//endfor + if (find(facet) == null_simplex()) + return false; + //std::cout << "++++ finished loop safely\n"; } //endfor return true; } @@ -1059,6 +1054,54 @@ bool complex_is_pseudomanifold(int dimension) } } + public: + /** \brief Verification if every simplex in the complex is witnessed + */ + template< class KNearestNeighbors > + bool is_witness_complex(KNearestNeighbors WL) + { + //bool final_result = true; + for (Simplex_handle sh: complex_simplex_range()) + { + bool is_witnessed = false; + typeVectorVertex simplex; + int nbV = 0; //number of verticed in the simplex + for (int v: simplex_vertex_range(sh)) + simplex.push_back(v); + nbV = simplex.size(); + for (typeVectorVertex w: WL) + { + bool has_vertices = true; + for (int v: simplex) + if (std::find(w.begin(), w.begin()+nbV, v) == w.begin()+nbV) + { + has_vertices = false; + //break; + } + if (has_vertices) + { + is_witnessed = true; + std::cout << "The simplex "; + print_vector(simplex); + std::cout << " is witnessed by the witness "; + print_vector(w); + std::cout << std::endl; + break; + } + } + if (!is_witnessed) + { + std::cout << "The following simplex is not witnessed "; + print_vector(simplex); + std::cout << std::endl; + assert(is_witnessed); + return false; + } + } + return true; // Arrive here if the not_witnessed check failed all the time + } + + }; //class Witness_complex -- cgit v1.2.3 From d4c823dce7436f561c8cd545f5a4f80d2d301ca1 Mon Sep 17 00:00:00 2001 From: skachano Date: Sat, 4 Jul 2015 09:49:32 +0000 Subject: Added files for testing on didgeridoo git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@676 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6d8aeda398803d49ee9218b99939095098ceb92e --- src/Witness_complex/example/CMakeLists.txt | 15 +- src/Witness_complex/example/Torus_distance.h | 209 ++++++++ .../example/witness_complex_cube.cpp | 541 +++++++++++++++++++ .../example/witness_complex_cubic_systems.cpp | 547 +++++++++++++++++++ .../example/witness_complex_epsilon.cpp | 566 ++++++++++++++++++++ .../example/witness_complex_flat_torus.cpp | 73 ++- .../example/witness_complex_perturbations.cpp | 2 +- .../example/witness_complex_protected_delaunay.cpp | 594 +++++++++++++++++++++ .../example/witness_complex_sphere.cpp | 248 ++------- 9 files changed, 2582 insertions(+), 213 deletions(-) create mode 100644 src/Witness_complex/example/Torus_distance.h create mode 100644 src/Witness_complex/example/witness_complex_cube.cpp create mode 100644 src/Witness_complex/example/witness_complex_cubic_systems.cpp create mode 100644 src/Witness_complex/example/witness_complex_epsilon.cpp create mode 100644 src/Witness_complex/example/witness_complex_protected_delaunay.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 77f95c79..23919b4a 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -87,8 +87,19 @@ if(CGAL_FOUND) target_link_libraries(witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) add_executable ( relaxed_witness_complex_sphere relaxed_witness_complex_sphere.cpp ) - target_link_libraries(relaxed_witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(relaxed_witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/relaxed_witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_protected_delaunay witness_complex_protected_delaunay.cpp ) + target_link_libraries(witness_complex_protected_delaunay ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_protected_delaunay ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_protected_delaunay ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_cubic_systems witness_complex_cubic_systems.cpp ) + target_link_libraries(witness_complex_cubic_systems ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_cubic_systems ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_cubic_systems ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_cube witness_complex_cube.cpp ) + target_link_libraries(witness_complex_cube ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_cube ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_cube ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable ( witness_complex_epsilon witness_complex_epsilon.cpp ) + target_link_libraries(witness_complex_epsilon ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_test(witness_complex_epsilon ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_epsilon ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) else() message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") endif() diff --git a/src/Witness_complex/example/Torus_distance.h b/src/Witness_complex/example/Torus_distance.h new file mode 100644 index 00000000..5ae127df --- /dev/null +++ b/src/Witness_complex/example/Torus_distance.h @@ -0,0 +1,209 @@ +#ifndef GUDHI_TORUS_DISTANCE_H_ +#define GUDHI_TORUS_DISTANCE_H_ + +#include + +#include +#include +#include + +typedef CGAL::Epick_d K; +typedef K::Point_d Point_d; +typedef K::FT FT; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; + +/** + * \brief Class of distance in a flat torus in dimension D + * + */ +class Torus_distance { + +public: + typedef K::FT FT; + typedef K::Point_d Point_d; + typedef Point_d Query_item; + typedef typename CGAL::Dynamic_dimension_tag D; + + double box_length = 2; + + FT transformed_distance(Query_item q, Point_d p) const + { + FT distance = FT(0); + FT coord = FT(0); + //std::cout << "Hello skitty!\n"; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1), pit = construct_it(p); + for(; qit != qe; qit++, pit++) + { + coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit))); + if (coord*coord <= (box_length-coord)*(box_length-coord)) + distance += coord*coord; + else + distance += (box_length-coord)*(box_length-coord); + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (box_length - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + distance += dist1*dist1; + else + distance += dist2*dist2; + } + } + return distance; + } + + FT min_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance = FT(0); + FT dist1, dist2; + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + //std::cout << r.max_coord(0) << std::endl; + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if((*qit) < r.min_coord(i)) + { + dist1 = (r.min_coord(i)-(*qit)); + dist2 = (box_length - r.max_coord(i)+(*qit)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + //std::cout << "Good stuff1\n"; + } + } + else if ((*qit) > r.max_coord(i)) + { + dist1 = (box_length - (*qit)+r.min_coord(i)); + dist2 = ((*qit) - r.max_coord(i)); + if (dist1 < dist2) + { + dists[i] = dist1; + distance += dist1*dist1; + //std::cout << "Good stuff2\n"; + } + else + { + dists[i] = dist2; + distance += dist2*dist2; + } + } + }; + return distance; + } + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + else + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + else + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + return distance; + } + + + FT max_distance_to_rectangle(const Query_item& q, + const CGAL::Kd_tree_rectangle& r, + std::vector& dists) const { + FT distance=FT(0); + typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); + typename K::Cartesian_const_iterator_d qit = construct_it(q), + qe = construct_it(q,1); + for(unsigned int i = 0;qit != qe; i++, qit++) + { + if (box_length <= (r.min_coord(i)+r.max_coord(i))) + if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = r.max_coord(i)-(*qit); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + } + else + { + dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i))); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + else + if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || + (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) + { + dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit))); + distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); + + } + else + { + dists[i] = (*qit)-r.min_coord(i); + distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); + } + } + return distance; + } + + inline FT new_distance(FT dist, FT old_off, FT new_off, + int ) const { + + FT new_dist = dist + (new_off*new_off - old_off*old_off); + return new_dist; + } + + inline FT transformed_distance(FT d) const { + return d*d; + } + + inline FT inverse_of_transformed_distance(FT d) const { + return sqrt(d); + } + +}; + +#endif diff --git a/src/Witness_complex/example/witness_complex_cube.cpp b/src/Witness_complex/example/witness_complex_cube.cpp new file mode 100644 index 00000000..7545f156 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_cube.cpp @@ -0,0 +1,541 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +#include "Torus_distance.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::Point_d Point_d; +//typedef CGAL::Cartesian_d K; +//typedef CGAL::Point_d Point_d; +typedef K::FT FT; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +typedef CGAL::Delaunay_triangulation Delaunay_triangulation; +typedef Delaunay_triangulation::Facet Facet; +typedef CGAL::Sphere_d Sphere_d; + +bool toric=false; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +void generate_points_grid(Point_Vector& W, int width, int D) +{ + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(0.01*(cell_i%width)); + cell_i /= width; + } + W.push_back(point); + } +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + /* + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + std::vector point; + for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) + point.push_back(*it); + W.push_back(Point_d(point)); + rp++; + } + */ + Random_cube_iterator rp(dim, 1.0); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + + +void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count) +{ + delaunay.insert(W[chosen_landmark]); + landmarks_ind.push_back(chosen_landmark); + landmark_count++; +} + +bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) +{ + Euclidean_distance ed; + Delaunay_triangulation::Vertex_handle v; + Delaunay_triangulation::Face f(t.current_dimension()); + Delaunay_triangulation::Facet ft; + Delaunay_triangulation::Full_cell_handle c; + Delaunay_triangulation::Locate_type lt; + c = t.locate(p, lt, f, ft, v); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + { + std::vector vertices; + for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) + vertices.push_back((*v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, p); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) + return true; + } + return false; +} + +bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) +{ + Euclidean_distance ed; + int D = t.current_dimension(); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + { + //check if vertex belongs to the face + bool belongs = false; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + if (v_it == *fc_v_it) + { + belongs = true; + break; + } + if (!belongs) + { + std::vector vertices; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + vertices.push_back((*fc_v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, v_it->point()); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 <= (r+delta)*(r+delta)) + return false; + } + } + return true; +} + +void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + for (int j = 0; j < landmarks_ind.size(); ++j) + landmarks.push_back(W[landmarks_ind[j]][l]); +} + +void landmark_choice_by_delaunay(Point_Vector& W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +{ + int D = W[0].size(); + Delaunay_triangulation t(D); + CGAL::Random rand; + int chosen_landmark; + int landmark_count = 0; + for (int i = 0; i <= D+1; ++i) + { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); + } + while (landmark_count < nbL) + { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + // If no conflicts then insert in every copy of T^3 + if (!is_violating_protection(W[chosen_landmark], t, D, delta)) + insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); + } +} + + +void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +{ + int D = W[0].size(); + Torus_distance td; + Euclidean_distance ed; + Delaunay_triangulation t(D); + CGAL::Random rand; + int landmark_count = 0; + std::list index_list; + // shuffle the list of indexes (via a vector) + { + std::vector temp_vector; + for (int i = 0; i < nbP; ++i) + temp_vector.push_back(i); + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed)); + for (std::vector::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it) + index_list.push_front(*it); + } + // add the first D+1 vertices to form one non-empty cell + for (int i = 0; i <= D+1; ++i) + { + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + } + // add other vertices if they don't violate protection + std::list::iterator list_it = index_list.begin(); + while (list_it != index_list.end()) + if (!is_violating_protection(W[*list_it], t, D, delta)) + { + // If no conflicts then insert in every copy of T^3 + insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count); + index_list.erase(list_it); + list_it = index_list.begin(); + } + else + list_it++; + fill_landmark_copies(W, landmarks, landmarks_ind); +} + + +int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i landmarks_ext; + int nb_cells = 1; + for (int i = 0; i < D; ++i) + nb_cells *= 3; + for (int i = 0; i < nb_cells; ++i) + for (int k = 0; k < nbL; ++k) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); + cell_i /= 3; + } + landmarks_ext.push_back(point); + } + write_points("landmarks/initial_landmarks",landmarks_ext); + STraits traits(&(landmarks_ext[0])); + std::vector< std::vector > WL(nbP); + + //********************** Neighbor search in a Kd tree + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nb_cells*nbL), + typename Tree::Splitter(), + traits); + std::cout << "Enter (D+1) nearest landmarks\n"; + for (int i = 0; i < nbP; i++) + { + Point_d& w = W[i]; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter(&(landmarks_ext[0])) ); + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) + WL[i].push_back((it->first)%nbL); + } + if (i == landmarks_ind[WL[i][0]]) + { + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + std::string out_file = "wl_result"; + write_wl(out_file,WL); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + //std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); + for (auto u: witnessComplex.complex_vertex_range()) + { + if (!witnessComplex.has_good_link(u, count_bad, count_good)) + { + count_badlinks++; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); + } + } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + + //*********************** Perturb bad link landmarks + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/8); + std::vector point; + for (int i = 0; i < D; i++) + { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); + } + landmarks[u] = Point_d(point); + } + std::cout << "lambda=" << lambda << std::endl; + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + if (argc != 5) + { + std::cerr << "Usage: " << argv[0] + << " nbP nbL dim delta\n"; + return 0; + } + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); + FT delta = atof(argv[4]); + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + generate_points_random_box(point_vector, nbP, dim); + Point_Vector L; + std::vector chosen_landmarks; + bool ok=false; + while (!ok) + { + ok = true; + L = {}; + chosen_landmarks = {}; + //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta); + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); + nbL = chosen_landmarks.size(); + std::cout << "Number of landmarks is " << nbL << std::endl; + //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); + for (auto i: chosen_landmarks) + { + ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + if (!ok) break; + } + + } + int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_landmarks",L); + //for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) + { + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; + write_points("landmarks/landmarks0",L); + } + +} diff --git a/src/Witness_complex/example/witness_complex_cubic_systems.cpp b/src/Witness_complex/example/witness_complex_cubic_systems.cpp new file mode 100644 index 00000000..2f4ee1cb --- /dev/null +++ b/src/Witness_complex/example/witness_complex_cubic_systems.cpp @@ -0,0 +1,547 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +#include "Torus_distance.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::Point_d Point_d; +//typedef CGAL::Cartesian_d K; +//typedef CGAL::Point_d Point_d; +typedef K::FT FT; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +typedef CGAL::Delaunay_triangulation Delaunay_triangulation; +typedef Delaunay_triangulation::Facet Facet; +typedef CGAL::Sphere_d Sphere_d; + +bool toric=false; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + /* + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + std::vector point; + for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) + point.push_back(*it); + W.push_back(Point_d(point)); + rp++; + } + */ + Random_cube_iterator rp(dim, 1.0); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + int chosen_landmark; + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + +void aux_fill_grid(Point_Vector& W, int& width, Point_Vector& landmarks, std::vector& landmarks_ind, std::vector & curr_pattern) +{ + int D = W[0].size(); + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + if (curr_pattern[l]) + point.push_back(-1.0+(2.0/width)*(cell_i%width)+(1.0/width)); + else + point.push_back(-1.0+(2.0/width)*(cell_i%width)); + cell_i /= width; + } + landmarks.push_back(Point_d(point)); + landmarks_ind.push_back(0);//landmarks_ind.push_back(W.size()); + //std::cout << "Added point " << W.size() << std::endl;; + //W.push_back(Point_d(point)); + } +} + +void aux_put_halves(Point_Vector& W, int& width, Point_Vector& landmarks, std::vector& landmarks_ind, std::vector& curr_pattern, std::vector::iterator curr_pattern_it, std::vector::iterator bool_it, std::vector::iterator bool_end) +{ + if (curr_pattern_it != curr_pattern.end()) + { + if (bool_it != bool_end) + { + *curr_pattern_it = false; + aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern_it+1, bool_it, bool_end); + *curr_pattern_it = true; + aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern_it+1, bool_it+1, bool_end); + } + } + else + if (*bool_it) + { + std::cout << "Filling the pattern "; + for (bool b: curr_pattern) + if (b) std::cout << '1'; + else std::cout << '0'; + std::cout << "\n"; + aux_fill_grid(W, width, landmarks, landmarks_ind, curr_pattern); + } +} + +void landmark_choice_cs(Point_Vector& W, int width, Point_Vector& landmarks, std::vector& landmarks_ind, std::vector& face_centers) +{ + std::cout << "Enter landmark choice to kd tree\n"; + //int chosen_landmark; + CGAL::Random rand; + //To speed things up check the last true in the code and put it as the finishing condition + unsigned last_true = face_centers.size()-1; + while (!face_centers[last_true] && last_true != 0) + last_true--; + //Recursive procedure to understand where we put +1/2 in centers' coordinates + std::vector curr_pattern(W[0].size(), false); + aux_put_halves(W, width, landmarks, landmarks_ind, curr_pattern, curr_pattern.begin(), face_centers.begin(), face_centers.begin()+(last_true+1)); + std::cout << "The number of landmarks is: " << landmarks.size() << std::endl; + + } + +int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i landmarks_ext; + int nb_cells = 1; + for (int i = 0; i < D; ++i) + nb_cells *= 3; + for (int i = 0; i < nb_cells; ++i) + for (int k = 0; k < nbL; ++k) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); + cell_i /= 3; + } + landmarks_ext.push_back(point); + } + write_points("landmarks/initial_landmarks",landmarks_ext); + STraits traits(&(landmarks_ext[0])); + std::vector< std::vector > WL(nbP); + + //********************** Neighbor search in a Kd tree + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nb_cells*nbL), + typename Tree::Splitter(), + traits); + std::cout << "Enter (D+1) nearest landmarks\n"; + for (int i = 0; i < nbP; i++) + { + Point_d& w = W[i]; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter(&(landmarks_ext[0])) ); + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) + WL[i].push_back((it->first)%nbL); + } + if (i == landmarks_ind[WL[i][0]]) + { + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + std::string out_file = "wl_result"; + write_wl(out_file,WL); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + //std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); + for (auto u: witnessComplex.complex_vertex_range()) + { + if (!witnessComplex.has_good_link(u, count_bad, count_good, D)) + { + count_badlinks++; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); + } + } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + + //*********************** Perturb bad link landmarks + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/8); + std::vector point; + for (int i = 0; i < D; i++) + { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); + } + landmarks[u] = Point_d(point); + } + std::cout << "lambda=" << lambda << std::endl; + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + return count_badlinks; +} + +void exaustive_search(Point_Vector& W, int width) +{ + int D = W[0].size()+1; + int nb_points = pow(2,D); + std::vector face_centers(D, false); + int bl = 0; //Bad links + std::vector> good_patterns; + for (int i = 0; i < nb_points; ++i) + { + int cell_i = i; + for (int l = 0; l < D; ++l) + { + if (cell_i%2 == 0) + face_centers[l] = false; + else + face_centers[l] = true; + cell_i /= 2; + } + std::cout << "**Current pattern "; + for (bool b: face_centers) + if (b) std::cout << '1'; + else std::cout << '0'; + std::cout << "\n"; + Point_Vector landmarks; + std::vector landmarks_ind; + Point_Vector W_copy(W); + landmark_choice_cs(W_copy, width, landmarks, landmarks_ind, face_centers); + if (landmarks.size() != 0) + { + bl = landmark_perturbation(W_copy, landmarks, landmarks_ind); + if ((1.0*bl)/landmarks.size() < 0.5) + good_patterns.push_back(face_centers); + } + } + std::cout << "The following patterns worked: "; + for (std::vector pattern : good_patterns) + { + std::cout << "["; + for (bool b: pattern) + if (b) std::cout << '1'; + else std::cout << '0'; + std::cout << "] "; + } + std::cout << "\n"; +} + +int main (int argc, char * const argv[]) +{ + unsigned nbP = atoi(argv[1]); + unsigned width = atoi(argv[2]); + unsigned dim = atoi(argv[3]); + std::string code = (std::string) argv[4]; + bool e_option = false; + int c; + if (argc != 5) + { + std::cerr << "Usage: " << argv[0] + << "witness_complex_cubic_systems nbP width dim code || witness_complex_systems -e nbP width dim\n" + << "where nbP stands for the number of witnesses, width for the width of the grid, dim for dimension " + << "and code is a sequence of (dim+1) symbols 0 and 1 representing if we take the centers of k-dimensional faces of the cubic system depending if it is 0 or 1." + << "-e stands for the 'exaustive' option"; + return 0; + } + while ((c = getopt (argc, argv, "e::")) != -1) + switch(c) + { + case 'e' : + e_option = true; + nbP = atoi(argv[2]); + width = atoi(argv[3]); + dim = atoi(argv[4]); + break; + default : + nbP = atoi(argv[1]); + width = atoi(argv[2]); + dim = atoi(argv[3]); + code = (std::string) argv[4]; + } + Point_Vector point_vector; + generate_points_random_box(point_vector, nbP, dim); + + // Exaustive search + if (e_option) + { + std::cout << "Start exaustive search!\n"; + exaustive_search(point_vector, width); + return 0; + } + // Search with a specific cubic system + std::vector face_centers; + if (code.size() != dim+1) + { + std::cerr << "The code should contain (dim+1) symbols"; + return 1; + } + for (char c: code) + if (c == '0') + face_centers.push_back(false); + else + face_centers.push_back(true); + std::cout << "Let the carnage begin!\n"; + Point_Vector L; + std::vector chosen_landmarks; + + landmark_choice_cs(point_vector, width, L, chosen_landmarks, face_centers); + + int nbL = width; //!!!!!!!!!!!!! + int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_landmarks",L); + //for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) + { + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; + write_points("landmarks/landmarks0",L); + } + +} diff --git a/src/Witness_complex/example/witness_complex_epsilon.cpp b/src/Witness_complex/example/witness_complex_epsilon.cpp new file mode 100644 index 00000000..d091bdb7 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_epsilon.cpp @@ -0,0 +1,566 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +#include "Torus_distance.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::Point_d Point_d; +//typedef CGAL::Cartesian_d K; +//typedef CGAL::Point_d Point_d; +typedef K::FT FT; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +typedef CGAL::Delaunay_triangulation Delaunay_triangulation; +typedef Delaunay_triangulation::Facet Facet; +typedef CGAL::Sphere_d Sphere_d; + +bool toric=false; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +void generate_points_grid(Point_Vector& W, int width, int D) +{ + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(0.01*(cell_i%width)); + cell_i /= width; + } + W.push_back(point); + } +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + /* + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + std::vector point; + for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) + point.push_back(*it); + W.push_back(Point_d(point)); + rp++; + } + */ + Random_cube_iterator rp(dim, 1.0); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + int chosen_landmark; + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + +void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count) +{ + delaunay.insert(W[chosen_landmark]); + landmarks_ind.push_back(chosen_landmark); + landmark_count++; +} + +bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) +{ + Euclidean_distance ed; + Delaunay_triangulation::Vertex_handle v; + Delaunay_triangulation::Face f(t.current_dimension()); + Delaunay_triangulation::Facet ft; + Delaunay_triangulation::Full_cell_handle c; + Delaunay_triangulation::Locate_type lt; + c = t.locate(p, lt, f, ft, v); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + { + std::vector vertices; + for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) + vertices.push_back((*v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, p); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) + return true; + } + return false; +} + +bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) +{ + Euclidean_distance ed; + int D = t.current_dimension(); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + { + //check if vertex belongs to the face + bool belongs = false; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + if (v_it == *fc_v_it) + { + belongs = true; + break; + } + if (!belongs) + { + std::vector vertices; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + vertices.push_back((*fc_v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, v_it->point()); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 <= (r+delta)*(r+delta)) + return false; + } + } + return true; +} + +FT sampling_radius(Delaunay_triangulation& t) +{ + int D = t.current_dimension(); + FT epsilon2 = 4.0; + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + { + Point_Vector vertices; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + vertices.push_back((*fc_v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin())); + if (epsilon2 > r2) + epsilon2 = r2; + } + return sqrt(epsilon2); +} + +FT point_sampling_radius_by_delaunay(Point_Vector& points) +{ + Delaunay_triangulation t(points[0].size()); + t.insert(points.begin(), points.end()); + return sampling_radius(t); +} + +void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +{ + int D = W[0].size(); + Torus_distance td; + Euclidean_distance ed; + Delaunay_triangulation t(D); + CGAL::Random rand; + int landmark_count = 0; + std::list index_list; + // shuffle the list of indexes (via a vector) + { + std::vector temp_vector; + for (int i = 0; i < nbP; ++i) + temp_vector.push_back(i); + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed)); + for (std::vector::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it) + index_list.push_front(*it); + } + // add the first D+1 vertices to form one non-empty cell + for (int i = 0; i <= D+1; ++i) + { + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + } + // add other vertices if they don't violate protection + std::list::iterator list_it = index_list.begin(); + while (list_it != index_list.end()) + if (!is_violating_protection(W[*list_it], t, D, delta)) + { + // If no conflicts then insert in every copy of T^3 + insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count); + index_list.erase(list_it); + list_it = index_list.begin(); + } + else + list_it++; + for (std::vector::iterator it = landmarks_ind.begin(); it != landmarks_ind.end(); ++it) + landmarks.push_back(W[*it]); +} + + +int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i landmarks_ext; + int nb_cells = 1; + for (int i = 0; i < D; ++i) + nb_cells *= 3; + for (int i = 0; i < nb_cells; ++i) + for (int k = 0; k < nbL; ++k) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); + cell_i /= 3; + } + landmarks_ext.push_back(point); + } + write_points("landmarks/initial_landmarks",landmarks_ext); + STraits traits(&(landmarks_ext[0])); + std::vector< std::vector > WL(nbP); + + //********************** Neighbor search in a Kd tree + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nb_cells*nbL), + typename Tree::Splitter(), + traits); + std::cout << "Enter (D+1) nearest landmarks\n"; + for (int i = 0; i < nbP; i++) + { + Point_d& w = W[i]; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter(&(landmarks_ext[0])) ); + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) + WL[i].push_back((it->first)%nbL); + } + if (i == landmarks_ind[WL[i][0]]) + { + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + std::string out_file = "wl_result"; + write_wl(out_file,WL); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + //std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); + for (auto u: witnessComplex.complex_vertex_range()) + { + if (!witnessComplex.has_good_link(u, count_bad, count_good)) + { + count_badlinks++; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); + } + } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + + //*********************** Perturb bad link landmarks + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/8); + std::vector point; + for (int i = 0; i < D; i++) + { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); + } + landmarks[u] = Point_d(point); + } + std::cout << "lambda=" << lambda << std::endl; + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + if (argc != 5) + { + std::cerr << "Usage: " << argv[0] + << " nbP nbL dim delta\n"; + return 0; + } + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); + FT delta = atof(argv[4]); + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + generate_points_random_box(point_vector, nbP, dim); + FT epsilon = point_sampling_radius_by_delaunay(point_vector); + std::cout << "Initial epsilon = " << epsilon << std::endl; + Point_Vector L; + std::vector chosen_landmarks; + bool ok=false; + while (!ok) + { + ok = true; + L = {}; + chosen_landmarks = {}; + //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta); + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); + nbL = chosen_landmarks.size(); + std::cout << "Number of landmarks is " << nbL << std::endl; + //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); + for (auto i: chosen_landmarks) + { + ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + if (!ok) break; + } + + } + FT epsilon2 = point_sampling_radius_by_delaunay(L); + std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon/epsilon2 << std::endl; + int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_landmarks",L); + //for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) + { + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; + write_points("landmarks/landmarks0",L); + } + +} diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index 42bf5e7e..06bf5a9f 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -63,8 +63,10 @@ using namespace Gudhi; //using namespace boost::filesystem; typedef CGAL::Epick_d K; -typedef K::FT FT; typedef K::Point_d Point_d; +//typedef CGAL::Cartesian_d K; +//typedef CGAL::Point_d Point_d; +typedef K::FT FT; typedef CGAL::Search_traits< FT, Point_d, typename K::Cartesian_const_iterator_d, @@ -72,7 +74,7 @@ typedef CGAL::Search_traits< typedef CGAL::Euclidean_distance Euclidean_distance; /** - * \brief Class of distance in a flat torus in dimaension D + * \brief Class of distance in a flat torus in dimension D * */ //class Torus_distance : public Euclidean_distance { @@ -288,10 +290,11 @@ typedef CGAL::Fuzzy_sphere Fuzzy_sphere; typedef std::vector Point_Vector; //typedef K::Equal_d Equal_d; +//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; typedef CGAL::Random_points_in_cube_d Random_cube_iterator; typedef CGAL::Random_points_in_ball_d Random_point_iterator; -bool toric=true; +bool toric=false; /** * \brief Customized version of read_points @@ -341,7 +344,18 @@ void generate_points_grid(Point_Vector& W, int width, int D) void generate_points_random_box(Point_Vector& W, int nbP, int dim) { + /* Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + std::vector point; + for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) + point.push_back(*it); + W.push_back(Point_d(point)); + rp++; + } + */ + Random_cube_iterator rp(dim, 1.0); for (int i = 0; i < nbP; i++) { W.push_back(*rp++); @@ -494,9 +508,7 @@ void write_edges(std::string file_name, Witness_complex<>& witness_complex, Poin void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) { std::cout << "Enter landmark choice to kd tree\n"; - //std::vector landmarks; int chosen_landmark; - //std::pair res = std::make_pair(L_i.begin(),false); Point_d* p; CGAL::Random rand; for (int i = 0; i < nbL; i++) @@ -516,6 +528,33 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, } } +/** \brief Choose landmarks on a body-central cubic system + */ +void landmark_choice_bcc(Point_Vector &W, int nbP, int width, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + int D = W[0].size(); + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + std::vector cpoint; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(-1.0+(2.0/width)*(cell_i%width)); + cpoint.push_back(-1.0+(2.0/width)*(cell_i%width)+(1.0/width)); + cell_i /= width; + } + landmarks.push_back(point); + landmarks.push_back(cpoint); + landmarks_ind.push_back(2*i); + landmarks_ind.push_back(2*i+1); + } + std::cout << "The number of landmarks is: " << landmarks.size() << std::endl; +} + int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) { @@ -548,7 +587,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< int cell_i = i; for (int l = 0; l < D; ++l) { - point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1)); + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); cell_i /= 3; } landmarks_ext.push_back(point); @@ -587,7 +626,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //Point_etiquette_map::iterator itm = L_i.find(it->first); //assert(itm != L_i.end()); //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; - WL[i].push_back((it->first)%nbL); + if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) + WL[i].push_back((it->first)%nbL); //std::cout << "ITFIRST " << it->first << std::endl; //std::cout << i << " " << it->first << ": " << it->second << std::endl; } @@ -609,6 +649,12 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< Witness_complex<> witnessComplex; witnessComplex.setNbL(nbL); witnessComplex.witness_complex(WL); + /* + if (witnessComplex.is_witness_complex(WL)) + std::cout << "!!YES. IT IS A WITNESS COMPLEX!!\n"; + else + std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n"; + */ //******************** Making a set of bad link landmarks std::cout << "Entered bad links\n"; std::set< int > perturbL; @@ -730,9 +776,9 @@ int main (int argc, char * const argv[]) std::cout << "Let the carnage begin!\n"; Point_Vector point_vector; //read_points_cust(file_name, point_vector); - //generate_points_random_box(point_vector, nbP, dim); - generate_points_grid(point_vector, (int)pow(nbP, 1.0/dim), dim); - nbP = (int)(pow((int)pow(nbP, 1.0/dim), dim)); + generate_points_random_box(point_vector, nbP, dim); + //generate_points_grid(point_vector, (int)pow(nbP, 1.0/dim), dim); + //nbP = (int)(pow((int)pow(nbP, 1.0/dim), dim)); /* for (auto &p: point_vector) { @@ -757,17 +803,20 @@ int main (int argc, char * const argv[]) L = {}; chosen_landmarks = {}; landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + + //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); for (auto i: chosen_landmarks) { ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); if (!ok) break; } + } int bl = nbL, curr_min = bl; write_points("landmarks/initial_pointset",point_vector); //write_points("landmarks/initial_landmarks",L); - - for (int i = 0; bl > 0; i++) + for (int i = 0; i < 1; i++) + //for (int i = 0; bl > 0; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index 88a7510a..b3b84b1f 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -416,7 +416,7 @@ int main (int argc, char * const argv[]) { file_name.erase(0, last_slash_idx + 1); } - //write_points("landmarks/initial_pointset",point_vector); + write_points("landmarks/initial_pointset",point_vector); write_points("landmarks/initial_landmarks",L); //for (int i = 0; bl != 0; i++) for (int i = 0; i < 1; i++) diff --git a/src/Witness_complex/example/witness_complex_protected_delaunay.cpp b/src/Witness_complex/example/witness_complex_protected_delaunay.cpp new file mode 100644 index 00000000..2f795a5f --- /dev/null +++ b/src/Witness_complex/example/witness_complex_protected_delaunay.cpp @@ -0,0 +1,594 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +//#include + +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/reader_utils.h" +#include "Torus_distance.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +using namespace Gudhi; +//using namespace boost::filesystem; + +typedef CGAL::Epick_d K; +typedef K::Point_d Point_d; +//typedef CGAL::Cartesian_d K; +//typedef CGAL::Point_d Point_d; +typedef K::FT FT; +typedef CGAL::Search_traits< + FT, Point_d, + typename K::Cartesian_const_iterator_d, + typename K::Construct_cartesian_const_iterator_d> Traits_base; +typedef CGAL::Euclidean_distance Euclidean_distance; + + +typedef std::vector< Vertex_handle > typeVectorVertex; + +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +typedef CGAL::Search_traits_adapter< + std::ptrdiff_t, Point_d*, Traits_base> STraits; +//typedef K TreeTraits; +//typedef CGAL::Distance_adapter Euclidean_adapter; +//typedef CGAL::Kd_tree Kd_tree; +typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; +typedef K_neighbor_search::Tree Tree; +typedef K_neighbor_search::Distance Distance; +typedef K_neighbor_search::iterator KNS_iterator; +typedef K_neighbor_search::iterator KNS_range; +typedef boost::container::flat_map Point_etiquette_map; +typedef CGAL::Kd_tree Tree2; + +typedef CGAL::Fuzzy_sphere Fuzzy_sphere; + +typedef std::vector Point_Vector; + +//typedef K::Equal_d Equal_d; +//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +typedef CGAL::Delaunay_triangulation Delaunay_triangulation; +typedef Delaunay_triangulation::Facet Facet; +typedef CGAL::Sphere_d Sphere_d; + +bool toric=false; + + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +void generate_points_grid(Point_Vector& W, int width, int D) +{ + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(0.01*(cell_i%width)); + cell_i /= width; + } + W.push_back(point); + } +} + +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + /* + Random_cube_iterator rp(dim, 1); + for (int i = 0; i < nbP; i++) + { + std::vector point; + for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) + point.push_back(*it); + W.push_back(Point_d(point)); + rp++; + } + */ + Random_cube_iterator rp(dim, 1.0); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + + +void write_wl( std::string file_name, std::vector< std::vector > & WL) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : WL) + { + for (auto l: w) + ofs << l << " "; + ofs << "\n"; + } + ofs.close(); +} + + +void write_points( std::string file_name, std::vector< Point_d > & points) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto w : points) + { + for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + } + ofs.close(); +} + +void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) +{ + std::ofstream ofs (file_name, std::ofstream::out); + for (auto u: witness_complex.complex_vertex_range()) + for (auto v: witness_complex.complex_vertex_range()) + { + typeVectorVertex edge = {u,v}; + if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) + { + for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n"; + for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) + ofs << *it << " "; + ofs << "\n\n\n"; + } + } + ofs.close(); +} + + +/** Function that chooses landmarks from W and place it in the kd-tree L. + * Note: nbL hould be removed if the code moves to Witness_complex + */ +void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + std::cout << "Enter landmark choice to kd tree\n"; + int chosen_landmark; + Point_d* p; + CGAL::Random rand; + for (int i = 0; i < nbL; i++) + { + // while (!res.second) + // { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + //rand++; + //std::cout << "Chose " << chosen_landmark << std::endl; + p = &W[chosen_landmark]; + //L_i.emplace(chosen_landmark,i); + // } + landmarks.push_back(*p); + landmarks_ind.push_back(chosen_landmark); + //std::cout << "Added landmark " << chosen_landmark << std::endl; + } + } + +void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count) +{ + int D = W[0].size(); + int nb_cells = pow(3, D); + for (int i = 0; i < nb_cells; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(W[chosen_landmark][l] + 2.0*(cell_i%3-1)); + cell_i /= 3; + } + delaunay.insert(point); + } + landmarks_ind.push_back(chosen_landmark); + landmark_count++; +} + +bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) +{ + Euclidean_distance ed; + Delaunay_triangulation::Vertex_handle v; + Delaunay_triangulation::Face f(t.current_dimension()); + Delaunay_triangulation::Facet ft; + Delaunay_triangulation::Full_cell_handle c; + Delaunay_triangulation::Locate_type lt; + c = t.locate(p, lt, f, ft, v); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + { + std::vector vertices; + for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) + vertices.push_back((*v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, p); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) + return true; + } + return false; +} + +bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) +{ + Euclidean_distance ed; + int D = t.current_dimension(); + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + if (!t.is_infinite(fc_it)) + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + { + //check if vertex belongs to the face + bool belongs = false; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + if (v_it == *fc_v_it) + { + belongs = true; + break; + } + if (!belongs) + { + std::vector vertices; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + vertices.push_back((*fc_v_it)->point()); + Sphere_d cs(D, vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT dist2 = ed.transformed_distance(center_cs, v_it->point()); + //if the new point is inside the protection ball of a non conflicting simplex + if (dist2 <= (r+delta)*(r+delta)) + return false; + } + } + return true; +} + +void fill_landmark_copies(Point_Vector& W, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + int D = W[0].size(); + int nb_cells = pow(3, D); + int nbL = landmarks_ind.size(); + // Fill landmarks + for (int i = 0; i < nb_cells-1; ++i) + for (int j = 0; j < nbL; ++j) + { + int cell_i = i; + Point_d point; + for (int l = 0; l < D; ++l) + { + point.push_back(W[landmarks_ind[j]][l] + 2.0*(cell_i-1)); + cell_i /= 3; + } + landmarks.push_back(point); + } +} + +void landmark_choice_by_delaunay(Point_Vector& W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +{ + int D = W[0].size(); + Delaunay_triangulation t(D); + CGAL::Random rand; + int chosen_landmark; + int landmark_count = 0; + for (int i = 0; i <= D+1; ++i) + { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); + } + while (landmark_count < nbL) + { + do chosen_landmark = rand.get_int(0,nbP); + while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + // If no conflicts then insert in every copy of T^3 + if (!is_violating_protection(W[chosen_landmark], t, D, delta)) + insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); + } + fill_landmark_copies(W, landmarks, landmarks_ind); +} + + +void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +{ + int D = W[0].size(); + Torus_distance td; + Euclidean_distance ed; + Delaunay_triangulation t(D); + CGAL::Random rand; + int landmark_count = 0; + std::list index_list; + // shuffle the list of indexes (via a vector) + { + std::vector temp_vector; + for (int i = 0; i < nbP; ++i) + temp_vector.push_back(i); + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed)); + for (std::vector::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it) + index_list.push_front(*it); + } + // add the first D+1 vertices to form one non-empty cell + for (int i = 0; i <= D+1; ++i) + { + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + } + // add other vertices if they don't violate protection + std::list::iterator list_it = index_list.begin(); + while (list_it != index_list.end()) + if (!is_violating_protection(W[*list_it], t, D, delta)) + { + // If no conflicts then insert in every copy of T^3 + insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count); + index_list.erase(list_it); + list_it = index_list.begin(); + } + else + list_it++; + fill_landmark_copies(W, landmarks, landmarks_ind); +} + + +int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + //******************** Preface: origin point + int D = W[0].size(); + std::vector orig_vector; + for (int i=0; i landmarks_ext; + int nb_cells = 1; + for (int i = 0; i < D; ++i) + nb_cells *= 3; + for (int i = 0; i < nb_cells; ++i) + for (int k = 0; k < nbL; ++k) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); + cell_i /= 3; + } + landmarks_ext.push_back(point); + } + write_points("landmarks/initial_landmarks",landmarks_ext); + STraits traits(&(landmarks_ext[0])); + std::vector< std::vector > WL(nbP); + + //********************** Neighbor search in a Kd tree + Tree L(boost::counting_iterator(0), + boost::counting_iterator(nb_cells*nbL), + typename Tree::Splitter(), + traits); + std::cout << "Enter (D+1) nearest landmarks\n"; + for (int i = 0; i < nbP; i++) + { + Point_d& w = W[i]; + ////Search D+1 nearest neighbours from the tree of landmarks L + K_neighbor_search search(L, w, D+1, FT(0), true, + CGAL::Distance_adapter(&(landmarks_ext[0])) ); + for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) + { + if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) + WL[i].push_back((it->first)%nbL); + } + if (i == landmarks_ind[WL[i][0]]) + { + FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); + if (dist < lambda) + lambda = dist; + } + } + std::string out_file = "wl_result"; + write_wl(out_file,WL); + + //******************** Constructng a witness complex + std::cout << "Entered witness complex construction\n"; + Witness_complex<> witnessComplex; + witnessComplex.setNbL(nbL); + witnessComplex.witness_complex(WL); + + //******************** Making a set of bad link landmarks + std::cout << "Entered bad links\n"; + std::set< int > perturbL; + int count_badlinks = 0; + //std::cout << "Bad links around "; + std::vector< int > count_bad(D); + std::vector< int > count_good(D); + for (auto u: witnessComplex.complex_vertex_range()) + { + if (!witnessComplex.has_good_link(u, count_bad, count_good)) + { + count_badlinks++; + Point_d& l = landmarks[u]; + Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + std::vector curr_perturb; + L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); + for (int i: curr_perturb) + perturbL.insert(i%nbL); + } + } + for (unsigned int i = 0; i != count_good.size(); i++) + if (count_good[i] != 0) + std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; + for (unsigned int i = 0; i != count_bad.size(); i++) + if (count_bad[i] != 0) + std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; + std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; + + //*********************** Perturb bad link landmarks + for (auto u: perturbL) + { + Random_point_iterator rp(D,sqrt(lambda)/8); + std::vector point; + for (int i = 0; i < D; i++) + { + while (K().squared_distance_d_object()(*rp,origin) < lambda/256) + rp++; + FT coord = landmarks[u][i] + (*rp)[i]; + if (coord > 1) + point.push_back(coord-1); + else if (coord < -1) + point.push_back(coord+1); + else + point.push_back(coord); + } + landmarks[u] = Point_d(point); + } + std::cout << "lambda=" << lambda << std::endl; + char buffer[100]; + int i = sprintf(buffer,"stree_result.txt"); + + if (i >= 0) + { + std::string out_file = (std::string)buffer; + std::ofstream ofs (out_file, std::ofstream::out); + witnessComplex.st_to_file(ofs); + ofs.close(); + } + write_edges("landmarks/edges", witnessComplex, landmarks); + return count_badlinks; +} + + +int main (int argc, char * const argv[]) +{ + if (argc != 5) + { + std::cerr << "Usage: " << argv[0] + << " nbP nbL dim delta\n"; + return 0; + } + int nbP = atoi(argv[1]); + int nbL = atoi(argv[2]); + int dim = atoi(argv[3]); + FT delta = atof(argv[4]); + + std::cout << "Let the carnage begin!\n"; + Point_Vector point_vector; + generate_points_random_box(point_vector, nbP, dim); + Point_Vector L; + std::vector chosen_landmarks; + bool ok=false; + while (!ok) + { + ok = true; + L = {}; + chosen_landmarks = {}; + //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta); + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); + nbL = chosen_landmarks.size(); + std::cout << "Number of landmarks is " << nbL << std::endl; + //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); + for (auto i: chosen_landmarks) + { + ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); + if (!ok) break; + } + + } + int bl = nbL, curr_min = bl; + write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_landmarks",L); + //for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) + { + std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks); + if (bl < curr_min) + curr_min=bl; + write_points("landmarks/landmarks0",L); + } + +} diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index d08c763f..74aae875 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -71,199 +71,6 @@ typedef CGAL::Search_traits< typename K::Construct_cartesian_const_iterator_d> Traits_base; typedef CGAL::Euclidean_distance Euclidean_distance; -/** - * \brief Class of distance in a flat torus in dimaension D - * - */ -//class Torus_distance : public Euclidean_distance { - class Torus_distance { - -public: - typedef K::FT FT; - typedef K::Point_d Point_d; - typedef Point_d Query_item; - typedef typename CGAL::Dynamic_dimension_tag D; - - double box_length = 2; - - FT transformed_distance(Query_item q, Point_d p) const - { - FT distance = FT(0); - FT coord = FT(0); - //std::cout << "Hello skitty!\n"; - typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); - typename K::Cartesian_const_iterator_d qit = construct_it(q), - qe = construct_it(q,1), pit = construct_it(p); - for(; qit != qe; qit++, pit++) - { - coord = sqrt(((*qit)-(*pit))*((*qit)-(*pit))); - if (coord*coord <= (box_length-coord)*(box_length-coord)) - distance += coord*coord; - else - distance += (box_length-coord)*(box_length-coord); - } - return distance; - } - - FT min_distance_to_rectangle(const Query_item& q, - const CGAL::Kd_tree_rectangle& r) const { - FT distance = FT(0); - FT dist1, dist2; - typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); - typename K::Cartesian_const_iterator_d qit = construct_it(q), - qe = construct_it(q,1); - for(unsigned int i = 0;qit != qe; i++, qit++) - { - if((*qit) < r.min_coord(i)) - { - dist1 = (r.min_coord(i)-(*qit)); - dist2 = (box_length - r.max_coord(i)+(*qit)); - if (dist1 < dist2) - distance += dist1*dist1; - else - distance += dist2*dist2; - } - else if ((*qit) > r.max_coord(i)) - { - dist1 = (box_length - (*qit)+r.min_coord(i)); - dist2 = ((*qit) - r.max_coord(i)); - if (dist1 < dist2) - distance += dist1*dist1; - else - distance += dist2*dist2; - } - } - return distance; - } - - FT min_distance_to_rectangle(const Query_item& q, - const CGAL::Kd_tree_rectangle& r, - std::vector& dists) const { - FT distance = FT(0); - FT dist1, dist2; - typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); - typename K::Cartesian_const_iterator_d qit = construct_it(q), - qe = construct_it(q,1); - //std::cout << r.max_coord(0) << std::endl; - for(unsigned int i = 0;qit != qe; i++, qit++) - { - if((*qit) < r.min_coord(i)) - { - dist1 = (r.min_coord(i)-(*qit)); - dist2 = (box_length - r.max_coord(i)+(*qit)); - if (dist1 < dist2) - { - dists[i] = dist1; - distance += dist1*dist1; - } - else - { - dists[i] = dist2; - distance += dist2*dist2; - //std::cout << "Good stuff1\n"; - } - } - else if ((*qit) > r.max_coord(i)) - { - dist1 = (box_length - (*qit)+r.min_coord(i)); - dist2 = ((*qit) - r.max_coord(i)); - if (dist1 < dist2) - { - dists[i] = dist1; - distance += dist1*dist1; - //std::cout << "Good stuff2\n"; - } - else - { - dists[i] = dist2; - distance += dist2*dist2; - } - } - }; - return distance; - } - - FT max_distance_to_rectangle(const Query_item& q, - const CGAL::Kd_tree_rectangle& r) const { - FT distance=FT(0); - typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); - typename K::Cartesian_const_iterator_d qit = construct_it(q), - qe = construct_it(q,1); - for(unsigned int i = 0;qit != qe; i++, qit++) - { - if (box_length <= (r.min_coord(i)+r.max_coord(i))) - if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && - (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) - distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); - else - distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); - else - if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || - (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) - distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); - else - distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); - } - return distance; - } - - - FT max_distance_to_rectangle(const Query_item& q, - const CGAL::Kd_tree_rectangle& r, - std::vector& dists) const { - FT distance=FT(0); - typename K::Construct_cartesian_const_iterator_d construct_it=Traits_base().construct_cartesian_const_iterator_d_object(); - typename K::Cartesian_const_iterator_d qit = construct_it(q), - qe = construct_it(q,1); - for(unsigned int i = 0;qit != qe; i++, qit++) - { - if (box_length <= (r.min_coord(i)+r.max_coord(i))) - if ((r.max_coord(i)+r.min_coord(i)-box_length)/FT(2.0) <= (*qit) && - (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) - { - dists[i] = r.max_coord(i)-(*qit); - distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); - } - else - { - dists[i] = sqrt(((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i))); - distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); - } - else - if ((box_length-r.max_coord(i)-r.min_coord(i))/FT(2.0) <= (*qit) || - (*qit) <= (r.min_coord(i)+r.max_coord(i))/FT(2.0)) - { - dists[i] = sqrt((r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit))); - distance += (r.max_coord(i)-(*qit))*(r.max_coord(i)-(*qit)); - - } - else - { - dists[i] = (*qit)-r.min_coord(i); - distance += ((*qit)-r.min_coord(i))*((*qit)-r.min_coord(i)); - } - } - return distance; - } - - inline FT new_distance(FT dist, FT old_off, FT new_off, - int /* cutting_dimension */) const { - - FT new_dist = dist + (new_off*new_off - old_off*old_off); - return new_dist; - } - - inline FT transformed_distance(FT d) const { - return d*d; - } - - inline FT inverse_of_transformed_distance(FT d) const { - return sqrt(d); - } - -}; - - typedef std::vector< Vertex_handle > typeVectorVertex; //typedef std::pair typeSimplex; @@ -502,6 +309,49 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, } } +/** \brief A test with 600cell, the generalisation of icosaedre in 4d + */ +void landmark_choice_600cell(Point_Vector&W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +{ + assert(W[0].size() == 4); //4-dimensionality required + FT phi = (1+sqrt(5))/2; + FT phi_1 = FT(1)/phi; + std::vector p; + // 16 vertices + for (FT a = -0.5; a < 1; a += 1) + for (FT b = -0.5; b < 1; b += 1) + for (FT c = -0.5; c < 1; c += 1) + for (FT d = -0.5; d < 1; d += 1) + landmarks.push_back(Point_d(std::vector({a,b,c,d}))); + // 8 vertices + for (FT a = -0.5; a < 1; a += 1) + { + landmarks.push_back(Point_d(std::vector({a,0,0,0}))); + landmarks.push_back(Point_d(std::vector({0,a,0,0}))); + landmarks.push_back(Point_d(std::vector({0,0,a,0}))); + landmarks.push_back(Point_d(std::vector({0,0,0,a}))); + } + // 96 vertices + for (FT a = -phi/2; a < phi; a += phi) + for (FT b = -0.5; b < 1; b += 1) + for (FT c = -phi_1/2; c < phi_1; c += phi_1) + { + landmarks.push_back(Point_d(std::vector({a,b,c,0}))); + landmarks.push_back(Point_d(std::vector({b,a,0,c}))); + landmarks.push_back(Point_d(std::vector({c,0,a,b}))); + landmarks.push_back(Point_d(std::vector({0,c,b,a}))); + landmarks.push_back(Point_d(std::vector({a,c,0,b}))); + landmarks.push_back(Point_d(std::vector({a,0,b,c}))); + landmarks.push_back(Point_d(std::vector({c,b,0,a}))); + landmarks.push_back(Point_d(std::vector({0,b,a,c}))); + landmarks.push_back(Point_d(std::vector({b,0,c,a}))); + landmarks.push_back(Point_d(std::vector({0,a,c,b}))); + landmarks.push_back(Point_d(std::vector({b,c,a,0}))); + landmarks.push_back(Point_d(std::vector({c,a,b,0}))); + } + for (int i = 0; i < 120; ++i) + landmarks_ind.push_back(i); +} int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind) { @@ -516,10 +366,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< //******************** Constructing a WL matrix int nbP = W.size(); int nbL = landmarks.size(); - //Point_Vector landmarks_ = landmarks; - Torus_distance ed; - //Equal_d ed; - //Point_d p1(std::vector({0.8,0.8})), p2(std::vector({0.1,0.1})); + Euclidean_distance ed; FT lambda = ed.transformed_distance(landmarks[0],landmarks[1]); //std::cout << "Lambda=" << lambda << std::endl; //FT lambda = 0.1;//Euclidean_distance(); @@ -578,10 +425,12 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< Witness_complex<> witnessComplex; witnessComplex.setNbL(nbL); witnessComplex.witness_complex(WL); + /* if (witnessComplex.is_witness_complex(WL)) std::cout << "!!YES. IT IS A WITNESS COMPLEX!!\n"; else - std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n"; + std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n"; + */ //******************** Making a set of bad link landmarks std::cout << "Entered bad links\n"; std::set< int > perturbL; @@ -715,11 +564,14 @@ int main (int argc, char * const argv[]) L = {}; chosen_landmarks = {}; landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); + //landmark_choice_600cell(point_vector, nbP, nbL, L, chosen_landmarks); + /* for (auto i: chosen_landmarks) { ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); if (!ok) break; } + */ } int bl = nbL, curr_min = bl; write_points("landmarks/initial_pointset",point_vector); -- cgit v1.2.3 From 1bcbd5e259d3c13211a9b71c66cacadaad35404c Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 6 Jul 2015 07:04:53 +0000 Subject: Corrected errors in witness_complex_cube git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@680 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e0a33544c992889344cdaaed947479a5bc458ce3 --- .../example/witness_complex_cube.cpp | 59 +++++++++------------- .../example/witness_complex_flat_torus.cpp | 6 +-- .../example/witness_complex_perturbations.cpp | 20 +++++--- .../example/witness_complex_sphere.cpp | 7 +-- 4 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_cube.cpp b/src/Witness_complex/example/witness_complex_cube.cpp index 7545f156..b6051a5f 100644 --- a/src/Witness_complex/example/witness_complex_cube.cpp +++ b/src/Witness_complex/example/witness_complex_cube.cpp @@ -291,8 +291,8 @@ bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector& landmarks_ind) { - for (int j = 0; j < landmarks_ind.size(); ++j) - landmarks.push_back(W[landmarks_ind[j]][l]); + for (unsigned j = 0; j < landmarks_ind.size(); ++j) + landmarks.push_back(W[landmarks_ind[j]]); } void landmark_choice_by_delaunay(Point_Vector& W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) @@ -356,7 +356,7 @@ void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& } else list_it++; - fill_landmark_copies(W, landmarks, landmarks_ind); + fill_landmarks(W, landmarks, landmarks_ind); } @@ -427,6 +427,7 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std witnessComplex.witness_complex(WL); //******************** Making a set of bad link landmarks + /* std::cout << "Entered bad links\n"; std::set< int > perturbL; int count_badlinks = 0; @@ -453,8 +454,9 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std if (count_bad[i] != 0) std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; - + */ //*********************** Perturb bad link landmarks + /* for (auto u: perturbL) { Random_point_iterator rp(D,sqrt(lambda)/8); @@ -486,56 +488,41 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std } write_edges("landmarks/edges", witnessComplex, landmarks); return count_badlinks; + */ + return 0; } int main (int argc, char * const argv[]) { - if (argc != 5) + if (argc != 3) { std::cerr << "Usage: " << argv[0] - << " nbP nbL dim delta\n"; + << " nbP dim\n"; return 0; } int nbP = atoi(argv[1]); - int nbL = atoi(argv[2]); - int dim = atoi(argv[3]); - FT delta = atof(argv[4]); + int dim = atoi(argv[2]); std::cout << "Let the carnage begin!\n"; Point_Vector point_vector; generate_points_random_box(point_vector, nbP, dim); Point_Vector L; std::vector chosen_landmarks; - bool ok=false; - while (!ok) - { - ok = true; - L = {}; - chosen_landmarks = {}; - //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta); - landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); - nbL = chosen_landmarks.size(); - std::cout << "Number of landmarks is " << nbL << std::endl; - //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); - for (auto i: chosen_landmarks) - { - ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); - if (!ok) break; - } - - } - int bl = nbL, curr_min = bl; - write_points("landmarks/initial_pointset",point_vector); + //write_points("landmarks/initial_pointset",point_vector); //write_points("landmarks/initial_landmarks",L); - //for (int i = 0; i < 1; i++) - for (int i = 0; bl > 0; i++) + for (int i = 0; i < 11; i++) + //for (int i = 0; bl > 0; i++) { - std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; - bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks); - if (bl < curr_min) - curr_min=bl; - write_points("landmarks/landmarks0",L); + //std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; + double delta = pow(10, -(1.0*i)/2); + std::cout << "delta = " << delta << std::endl; + L = {}; chosen_landmarks = {}; + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); + int nbL = chosen_landmarks.size(); + std::cout << "Number of landmarks = " << nbL << std::endl; + landmark_perturbation(point_vector, nbL, L, chosen_landmarks); + //write_points("landmarks/landmarks0",L); } } diff --git a/src/Witness_complex/example/witness_complex_flat_torus.cpp b/src/Witness_complex/example/witness_complex_flat_torus.cpp index 06bf5a9f..69ef5fbf 100644 --- a/src/Witness_complex/example/witness_complex_flat_torus.cpp +++ b/src/Witness_complex/example/witness_complex_flat_torus.cpp @@ -335,7 +335,7 @@ void generate_points_grid(Point_Vector& W, int width, int D) int cell_i = i; for (int l = 0; l < D; ++l) { - point.push_back(0.01*(cell_i%width)); + point.push_back((2.0/width)*(cell_i%width)); cell_i /= width; } W.push_back(point); @@ -516,7 +516,7 @@ void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, // while (!res.second) // { do chosen_landmark = rand.get_int(0,nbP); - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); + while (std::find(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=landmarks_ind.end()); //rand++; //std::cout << "Chose " << chosen_landmark << std::endl; p = &W[chosen_landmark]; @@ -672,7 +672,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< count_badlinks++; //std::cout << u << " "; Point_d& l = landmarks[u]; - Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + Fuzzy_sphere fs(l, sqrt(lambda), 0, traits); std::vector curr_perturb; L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); for (int i: curr_perturb) diff --git a/src/Witness_complex/example/witness_complex_perturbations.cpp b/src/Witness_complex/example/witness_complex_perturbations.cpp index b3b84b1f..f78bcdab 100644 --- a/src/Witness_complex/example/witness_complex_perturbations.cpp +++ b/src/Witness_complex/example/witness_complex_perturbations.cpp @@ -267,6 +267,8 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::cout << "Enter (D+1) nearest landmarks\n"; //std::cout << "Size of the tree is " << L.size() << std::endl; int D = W[0].size(); + clock_t start, end; + start = clock(); for (int i = 0; i < nbP; i++) { //std::cout << "Entered witness number " << i << std::endl; @@ -294,18 +296,23 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< lambda = dist; } //std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; - - } + } //std::cout << "\n"; + end = clock(); + std::cout << "WL matrix construction on " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; + std::string out_file = "wl_result"; - write_wl(out_file,WL); + //write_wl(out_file,WL); //******************** Constructng a witness complex std::cout << "Entered witness complex construction\n"; Witness_complex<> witnessComplex; witnessComplex.setNbL(nbL); + start = clock(); witnessComplex.witness_complex(WL); + end = clock(); + std::cout << "Witness complex construction on " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << "s.\n"; //******************** Making a set of bad link landmarks std::cout << "Entered bad links\n"; std::set< int > perturbL; @@ -355,7 +362,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< std::cout << "lambda=" << lambda << std::endl; // Write the WL matrix in a file - + /* char buffer[100]; int i = sprintf(buffer,"stree_result.txt"); @@ -366,8 +373,9 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< witnessComplex.st_to_file(ofs); ofs.close(); } + */ //witnessComplex.write_badlinks("badlinks"); - write_edges_gnuplot("landmarks/edges", witnessComplex, landmarks); + //write_edges_gnuplot("landmarks/edges", witnessComplex, landmarks); return count_badlinks; } @@ -417,7 +425,7 @@ int main (int argc, char * const argv[]) file_name.erase(0, last_slash_idx + 1); } write_points("landmarks/initial_pointset",point_vector); - write_points("landmarks/initial_landmarks",L); + //write_points("landmarks/initial_landmarks",L); //for (int i = 0; bl != 0; i++) for (int i = 0; i < 1; i++) { diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 74aae875..550c9392 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -431,6 +431,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< else std::cout << "??NO. IT IS NOT A WITNESS COMPLEX??\n"; */ + */ //******************** Making a set of bad link landmarks std::cout << "Entered bad links\n"; std::set< int > perturbL; @@ -446,7 +447,7 @@ int landmark_perturbation(Point_Vector &W, Point_Vector& landmarks, std::vector< count_badlinks++; //std::cout << u << " "; Point_d& l = landmarks[u]; - Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); + Fuzzy_sphere fs(l, sqrt(lambda), 0, traits); std::vector curr_perturb; L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); for (int i: curr_perturb) @@ -577,8 +578,8 @@ int main (int argc, char * const argv[]) write_points("landmarks/initial_pointset",point_vector); write_points("landmarks/initial_landmarks",L); - //for (int i = 0; bl > 0; i++) - for (int i = 0; i < 1; i++) + for (int i = 0; bl > 0; i++) + //for (int i = 0; i < 1; i++) { std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; bl=landmark_perturbation(point_vector, L, chosen_landmarks); -- cgit v1.2.3 From da39f7cd8a0db5d7fa13c9c87f8fc3e038c10d01 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 15 Jul 2015 12:56:11 +0000 Subject: The construction of a protected set worked! FY! git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@716 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c2fec169cc227d123c3386007ef4e5799e8e3209 --- .../example/witness_complex_cube.cpp | 484 ++++++++++++++++-- .../example/witness_complex_epsilon.cpp | 565 +-------------------- 2 files changed, 462 insertions(+), 587 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_cube.cpp b/src/Witness_complex/example/witness_complex_cube.cpp index b6051a5f..a9a2959b 100644 --- a/src/Witness_complex/example/witness_complex_cube.cpp +++ b/src/Witness_complex/example/witness_complex_cube.cpp @@ -47,12 +47,15 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include @@ -66,7 +69,10 @@ using namespace Gudhi; typedef CGAL::Epick_d K; typedef K::Point_d Point_d; -//typedef CGAL::Cartesian_d K; +typedef K::Vector_d Vector_d; +typedef K::Oriented_side_d Oriented_side_d; +typedef K::Has_on_positive_side_d Has_on_positive_side_d; + //typedef CGAL::Point_d Point_d; typedef K::FT FT; typedef CGAL::Search_traits< @@ -105,7 +111,12 @@ typedef CGAL::Random_points_in_ball_d Random_point_iterator; typedef CGAL::Delaunay_triangulation Delaunay_triangulation; typedef Delaunay_triangulation::Facet Facet; -typedef CGAL::Sphere_d Sphere_d; +typedef Delaunay_triangulation::Vertex_handle Delaunay_vertex; +typedef Delaunay_triangulation::Full_cell_handle Full_cell_handle; +//typedef CGAL::Sphere_d Sphere_d; +typedef K::Sphere_d Sphere_d; +typedef K::Hyperplane_d Hyperplane_d; + bool toric=false; @@ -230,7 +241,187 @@ void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, landmark_count++; } +bool vertex_is_in_full_cell(Delaunay_triangulation::Vertex_handle v, Full_cell_handle fc) +{ + for (auto v_it = fc->vertices_begin(); v_it != fc->vertices_end(); ++v_it) + if (*v_it == v) + return true; + return false; +} + +bool new_cell_is_violated(Delaunay_triangulation& t, std::vector& vertices, bool is_infinite, const Point_d& p, FT delta) +{ + if (!is_infinite) + // FINITE CASE + { + Sphere_d cs(vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(Euclidean_distance().transformed_distance(center_cs, vertices[0])); + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + if (!t.is_infinite(v_it)) + { + //CGAL::Oriented_side side = Oriented_side_d()(cs, (v_it)->point()); + if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end()) + { + FT dist2 = Euclidean_distance().transformed_distance(center_cs, (v_it)->point()); + //if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) + if (dist2 >= r*r && dist2 <= r*r+delta*delta) + return true; + } + } + } + else + // INFINITE CASE + { + Delaunay_triangulation::Vertex_iterator v = t.vertices_begin(); + while (t.is_infinite(v) || std::find(vertices.begin(), vertices.end(), v->point()) == vertices.end()) + v++; + Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v->point(), CGAL::ON_POSITIVE_SIDE); + Vector_d orth_v = facet_plane.orthogonal_vector(); + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + if (!t.is_infinite(v_it)) + if (std::find(vertices.begin(), vertices.end(), v_it->point()) == vertices.end()) + { + std::vector coords; + Point_d p = v_it->point(); + auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin(); + for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i) + coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length())); + Point_d p_delta = Point_d(coords); + bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p); + bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta); + if (!p_is_inside && p_delta_is_inside) + return true; + } + } + return false; +} + + +bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, Full_cell_handle c, Full_cell_handle parent_cell, int index, int D, FT delta, std::vector& marked_cells) +{ + Euclidean_distance ed; + std::vector vertices; + if (!t.is_infinite(c)) + { + // if the cell is finite, we look if the protection is violated + for (auto v_it = c->vertices_begin(); v_it != c->vertices_end(); ++v_it) + vertices.push_back((*v_it)->point()); + Sphere_d cs( vertices.begin(), vertices.end()); + Point_d center_cs = cs.center(); + FT r = sqrt(ed.transformed_distance(center_cs, vertices[0])); + FT dist2 = ed.transformed_distance(center_cs, p); + // if the new point is inside the protection ball of a non conflicting simplex + //if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) + if (dist2 >= r*r && dist2 <= r*r+delta*delta) + return true; + c->tds_data().mark_visited(); + marked_cells.push_back(c); + // if the new point is inside the circumscribing ball : continue violation searching on neughbours + if (dist2 < r*r) + for (int i = 0; i < D+1; ++i) + { + Full_cell_handle next_c = c->neighbor(i); + if (next_c->tds_data().is_clear() && + is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells)) + return true; + } + // if the new point is outside the protection sphere + else + { + // facet f is on the border of the conflict zone : check protection of simplex {p,f} + // the new simplex is guaranteed to be finite + vertices.clear(); vertices.push_back(p); + for (int i = 0; i < D+1; ++i) + if (i != index) + vertices.push_back(parent_cell->vertex(i)->point()); + Delaunay_vertex vertex_to_check; + for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it) + if (!vertex_is_in_full_cell(*vh_it, parent_cell)) + { + vertex_to_check = *vh_it; break; + } + if (new_cell_is_violated(t, vertices, false, vertex_to_check->point(), delta)) + return true; + } + } + else + { + // Inside of the convex hull is + side. Outside is - side. + for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it) + if (!t.is_infinite(*vh_it)) + vertices.push_back((*vh_it)->point()); + Delaunay_triangulation::Vertex_iterator v_it = t.vertices_begin(); + while (t.is_infinite(v_it) || vertex_is_in_full_cell(v_it, c)) + v_it++; + Hyperplane_d facet_plane(vertices.begin(), vertices.end(), v_it->point(), CGAL::ON_POSITIVE_SIDE); + //CGAL::Oriented_side outside = Oriented_side_d()(facet_plane, v_it->point()); + Vector_d orth_v = facet_plane.orthogonal_vector(); + std::vector coords; + auto orth_i = orth_v.cartesian_begin(), p_i = p.cartesian_begin(); + for (; orth_i != orth_v.cartesian_end(); ++orth_i, ++p_i) + coords.push_back((*p_i) - (*orth_i) * delta / sqrt(orth_v.squared_length())); + Point_d p_delta = Point_d(coords); + bool p_is_inside = !Has_on_positive_side_d()(facet_plane, p); + bool p_delta_is_inside = !Has_on_positive_side_d()(facet_plane, p_delta); + + if (!p_is_inside && p_delta_is_inside) + return true; + //if the cell is infinite we look at the neighbours regardless + c->tds_data().mark_visited(); + marked_cells.push_back(c); + if (p_is_inside) + for (int i = 0; i < D+1; ++i) + { + Full_cell_handle next_c = c->neighbor(i); + if (next_c->tds_data().is_clear() && + is_violating_protection(p, t, next_c, c, i, D, delta, marked_cells)) + return true; + } + else + { + // facet f is on the border of the conflict zone : check protection of simplex {p,f} + // the new simplex is finite if the parent cell is finite + vertices.clear(); vertices.push_back(p); + bool new_simplex_is_finite = false; + for (int i = 0; i < D+1; ++i) + if (i != index) + { + if (t.is_infinite(parent_cell->vertex(i))) + new_simplex_is_finite = true; + else + vertices.push_back(parent_cell->vertex(i)->point()); + } + Delaunay_vertex vertex_to_check; + for (auto vh_it = c->vertices_begin(); vh_it != c->vertices_end(); ++vh_it) + if (!vertex_is_in_full_cell(*vh_it, parent_cell)) + { + vertex_to_check = *vh_it; break; + } + if (new_cell_is_violated(t, vertices, new_simplex_is_finite, vertex_to_check->point(), delta)) + return true; + } + } + return false; +} + bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) +{ + Euclidean_distance ed; + Delaunay_triangulation::Vertex_handle v; + Delaunay_triangulation::Face f(t.current_dimension()); + Delaunay_triangulation::Facet ft; + Delaunay_triangulation::Full_cell_handle c; + Delaunay_triangulation::Locate_type lt; + std::vector marked_cells; + c = t.locate(p, lt, f, ft, v); + bool violation_existing_cells = is_violating_protection(p, t, c, c, 0, D, delta, marked_cells); + for (Full_cell_handle fc : marked_cells) + fc->tds_data().clear(); + return violation_existing_cells; +} + +bool old_is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) { Euclidean_distance ed; Delaunay_triangulation::Vertex_handle v; @@ -245,7 +436,7 @@ bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT de std::vector vertices; for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) vertices.push_back((*v_it)->point()); - Sphere_d cs(D, vertices.begin(), vertices.end()); + Sphere_d cs( vertices.begin(), vertices.end()); Point_d center_cs = cs.center(); FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); FT dist2 = ed.transformed_distance(center_cs, p); @@ -253,39 +444,88 @@ bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT de if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) return true; } + t.insert(p, c); return false; } +void write_delaunay_mesh(Delaunay_triangulation& t, const Point_d& p) +{ + std::ofstream ofs ("delaunay.mesh", std::ofstream::out); + int nbV = t.number_of_vertices()+1; + ofs << "MeshVersionFormatted 1\nDimension 2\n"; + ofs << "Vertices\n" << nbV << "\n"; + int ind = 1; //index of a vertex + std::map index_of_vertex; + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + { + if (t.is_infinite(v_it)) + continue; + for (auto coord = v_it->point().cartesian_begin(); coord != v_it->point().cartesian_end(); ++coord) + ofs << *coord << " "; + ofs << "508\n"; + index_of_vertex[v_it] = ind++; + } + for (auto coord = p.cartesian_begin(); coord != p.cartesian_end(); ++coord) + ofs << *coord << " "; + ofs << "208\n"; + /* + int nbFacets = 0; + for (auto ft_it = t.finite_facets_begin(); ft_it != t.finite_facets_end(); ++ft_it) + nbFacets++; + ofs << "\nEdges\n" << nbFacets << "\n\n"; + for (auto ft_it = t.facets_begin(); ft_it != t.facets_end(); ++ft_it) + { + if (t.is_infinite(ft_it)) + continue; + for (auto vh_it = ft_it->vertices_begin(); vh_it != ft_it->vertices_end(); ++vh_it) + ofs << index_of_vertex[*vh_it] << " "; + } + */ + ofs << "Triangles " << t.number_of_finite_full_cells()+1 << "\n"; + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + { + if (t.is_infinite(fc_it)) + continue; + for (auto vh_it = fc_it->vertices_begin(); vh_it != fc_it->vertices_end(); ++vh_it) + ofs << index_of_vertex[*vh_it] << " "; + ofs << "508\n"; + } + ofs << nbV << " " << nbV << " " << nbV << " " << 208 << "\n"; + ofs << "End\n"; + ofs.close(); +} + bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) { + // Verification part Euclidean_distance ed; - int D = t.current_dimension(); for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) if (!t.is_infinite(fc_it)) for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) - { + if (!t.is_infinite(v_it)) //check if vertex belongs to the face - bool belongs = false; - for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) - if (v_it == *fc_v_it) - { - belongs = true; - break; - } - if (!belongs) + if (!vertex_is_in_full_cell(v_it, fc_it)) { std::vector vertices; for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) vertices.push_back((*fc_v_it)->point()); - Sphere_d cs(D, vertices.begin(), vertices.end()); + Sphere_d cs( vertices.begin(), vertices.end()); Point_d center_cs = cs.center(); - FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); + FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(0)->point())); FT dist2 = ed.transformed_distance(center_cs, v_it->point()); //if the new point is inside the protection ball of a non conflicting simplex - if (dist2 <= (r+delta)*(r+delta)) - return false; + //std::cout << "Dist^2 = " << dist2 << " (r+delta)*(r+delta) = " << (r+delta)*(r+delta) << " r^2 = " << r*r <<"\n"; + //if (dist2 <= (r+delta)*(r+delta) && dist2 >= r*r) + if (dist2 <= r*r+delta*delta && dist2 >= r*r) + { + write_delaunay_mesh(t, v_it->point()); + std::cout << "Problematic vertex " << *v_it << " "; + std::cout << "Problematic cell " << *fc_it << "\n"; + std::cout << "r^2 = " << r*r << ", d^2 = " << dist2 << ", r^2+delta^2 = " << r*r+delta*delta << "\n"; + return false; + } } - } + return true; } @@ -295,33 +535,65 @@ void fill_landmarks(Point_Vector& W, Point_Vector& landmarks, std::vector& landmarks.push_back(W[landmarks_ind[j]]); } -void landmark_choice_by_delaunay(Point_Vector& W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +void fill_full_cell_vector(Delaunay_triangulation& t, std::vector>& full_cells) { - int D = W[0].size(); - Delaunay_triangulation t(D); - CGAL::Random rand; - int chosen_landmark; - int landmark_count = 0; - for (int i = 0; i <= D+1; ++i) + // Store vertex indices in a map + int ind = 0; //index of a vertex + std::map index_of_vertex; + for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) + if (t.is_infinite(v_it)) + continue; + else + index_of_vertex[v_it] = ind++; + // Write full cells as vectors in full_cells + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) { - do chosen_landmark = rand.get_int(0,nbP); - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); - insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); + if (t.is_infinite(fc_it)) + continue; + std::vector cell; + for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) + cell.push_back(index_of_vertex[*v_it]); + full_cells.push_back(cell); } - while (landmark_count < nbL) - { - do chosen_landmark = rand.get_int(0,nbP); - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); - // If no conflicts then insert in every copy of T^3 - if (!is_violating_protection(W[chosen_landmark], t, D, delta)) - insert_delaunay_landmark_with_copies(W, chosen_landmark, landmarks_ind, t, landmark_count); +} + +FT sampling_radius(Delaunay_triangulation& t) +{ + FT epsilon2 = 4.0; + for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) + { + if (t.is_infinite(fc_it)) + continue; + Point_Vector vertices; + for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) + vertices.push_back((*fc_v_it)->point()); + Sphere_d cs( vertices.begin(), vertices.end()); + Point_d csc = cs.center(); + bool in_cube = true; + for (auto xi = csc.cartesian_begin(); xi != csc.cartesian_end(); ++xi) + if (*xi > 1.0 || *xi < -1.0) + { + in_cube = false; break; + } + if (!in_cube) + continue; + FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin())); + if (epsilon2 > r2) + epsilon2 = r2; } + return sqrt(epsilon2); } +FT point_sampling_radius_by_delaunay(Point_Vector& points) +{ + Delaunay_triangulation t(points[0].size()); + t.insert(points.begin(), points.end()); + return sampling_radius(t); +} -void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) +void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta, std::vector>& full_cells) { - int D = W[0].size(); + unsigned D = W[0].size(); Torus_distance td; Euclidean_distance ed; Delaunay_triangulation t(D); @@ -335,32 +607,106 @@ void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& temp_vector.push_back(i); unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed)); + //CGAL::spatial_sort(temp_vector.begin(), temp_vector.end()); for (std::vector::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it) index_list.push_front(*it); } - // add the first D+1 vertices to form one non-empty cell + for (unsigned pos1 = 0; pos1 < D+1; ++pos1) + { + std::vector point; + for (unsigned i = 0; i < pos1; ++i) + point.push_back(-1); + if (pos1 != D) + point.push_back(1); + for (unsigned i = pos1+1; i < D; ++i) + point.push_back(0); + assert(point.size() == D); + W[index_list.front()] = Point_d(point); + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + } + // add the first D+1 vertices to form one finite cell + /* for (int i = 0; i <= D+1; ++i) { + t.insert(W[index_list.front()]); insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); index_list.pop_front(); } + */ + /* + { + std::vector coords; + for (int i = 0; i < D; ++i) + coords.push_back(-1); + W[index_list.front()] = Point_d(coords); + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + for (int i = 0; i < D; ++i) + { + coords.clear(); + for (int j = 0; j < D; ++j) + if (i == j) + coords.push_back(1); + else + coords.push_back(-1); + W[index_list.front()] = Point_d(coords); + insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); + index_list.pop_front(); + } + } + */ + //std::cout << t; + //assert(t.number_of_vertices() == D+1); + //assert(landmarks_ind.size() == D+1); + //assert(W[landmarks_ind[0]][0] == 0); // add other vertices if they don't violate protection std::list::iterator list_it = index_list.begin(); while (list_it != index_list.end()) - if (!is_violating_protection(W[*list_it], t, D, delta)) - { + { + if (!is_violating_protection(W[*list_it], t, D, delta)) + { // If no conflicts then insert in every copy of T^3 + is_violating_protection(W[*list_it], t, D, delta); insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count); index_list.erase(list_it); list_it = index_list.begin(); + //std::cout << "index_list_size() = " << index_list.size() << "\n"; } - else - list_it++; + else + { + list_it++; + //std::cout << "!!!!!WARNING!!!!! A POINT HAS BEEN OMITTED!!!\n"; + } + //write_delaunay_mesh(t, W[*list_it]); + } fill_landmarks(W, landmarks, landmarks_ind); + fill_full_cell_vector(t, full_cells); + if (triangulation_is_protected(t, delta)) + std::cout << "Triangulation is ok\n"; + else + std::cout << "Triangulation is BAD!! T_T しくしく!\n"; + write_delaunay_mesh(t, Point_d(std::vector({0,0}))); + //std::cout << t << std::endl; } +template +void print_vector(std::vector v) +{ + std::cout << "["; + if (!v.empty()) + { + std::cout << *(v.begin()); + for (auto it = v.begin()+1; it != v.end(); ++it) + { + std::cout << ","; + std::cout << *it; + } + } + std::cout << "]"; +} -int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) +int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind, std::vector>& full_cells) { //******************** Preface: origin point int D = W[0].size(); @@ -426,6 +772,20 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std witnessComplex.setNbL(nbL); witnessComplex.witness_complex(WL); + //******************** Verifying if all full cells are in the complex + + int in=0, not_in=0; + for (auto cell : full_cells) + { + //print_vector(cell); + if (witnessComplex.find(cell) != witnessComplex.null_simplex()) + in++; + else + not_in++; + } + std::cout << "Out of all the cells in Delaunay triangulation:\n" << in << " are in the witness complex\n" << + not_in << " are not.\n"; + //******************** Making a set of bad link landmarks /* std::cout << "Entered bad links\n"; @@ -476,6 +836,7 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std landmarks[u] = Point_d(point); } std::cout << "lambda=" << lambda << std::endl; + */ char buffer[100]; int i = sprintf(buffer,"stree_result.txt"); @@ -486,7 +847,9 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std witnessComplex.st_to_file(ofs); ofs.close(); } + write_edges("landmarks/edges", witnessComplex, landmarks); + /* return count_badlinks; */ return 0; @@ -495,22 +858,27 @@ int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std int main (int argc, char * const argv[]) { - if (argc != 3) + if (argc != 4) { std::cerr << "Usage: " << argv[0] - << " nbP dim\n"; + << " nbP dim delta\n"; return 0; } int nbP = atoi(argv[1]); int dim = atoi(argv[2]); + double delta = atof(argv[3]); std::cout << "Let the carnage begin!\n"; Point_Vector point_vector; generate_points_random_box(point_vector, nbP, dim); + FT epsilon = point_sampling_radius_by_delaunay(point_vector); + std::cout << "Initial epsilon = " << epsilon << std::endl; Point_Vector L; std::vector chosen_landmarks; //write_points("landmarks/initial_pointset",point_vector); //write_points("landmarks/initial_landmarks",L); + CGAL::Timer timer; + /* for (int i = 0; i < 11; i++) //for (int i = 0; bl > 0; i++) { @@ -518,11 +886,29 @@ int main (int argc, char * const argv[]) double delta = pow(10, -(1.0*i)/2); std::cout << "delta = " << delta << std::endl; L = {}; chosen_landmarks = {}; - landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); + std::vector> full_cells; + timer.start(); + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta, full_cells); + timer.stop(); + FT epsilon2 = point_sampling_radius_by_delaunay(L); + std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon/epsilon2 << std::endl; + write_points("landmarks/initial_landmarks",L); int nbL = chosen_landmarks.size(); - std::cout << "Number of landmarks = " << nbL << std::endl; - landmark_perturbation(point_vector, nbL, L, chosen_landmarks); + std::cout << "Number of landmarks = " << nbL << ", time= " << timer.time() << "s"<< std::endl; + landmark_perturbation(point_vector, nbL, L, chosen_landmarks, full_cells); + timer.reset(); //write_points("landmarks/landmarks0",L); } - + */ + std::vector> full_cells; + timer.start(); + landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta, full_cells); + timer.stop(); + FT epsilon2 = point_sampling_radius_by_delaunay(L); + std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon/epsilon2 << std::endl; + write_points("landmarks/initial_landmarks",L); + int nbL = chosen_landmarks.size(); + std::cout << "Number of landmarks = " << nbL << ", time= " << timer.time() << "s"<< std::endl; + landmark_perturbation(point_vector, nbL, L, chosen_landmarks, full_cells); + timer.reset(); } diff --git a/src/Witness_complex/example/witness_complex_epsilon.cpp b/src/Witness_complex/example/witness_complex_epsilon.cpp index d091bdb7..7f8b985f 100644 --- a/src/Witness_complex/example/witness_complex_epsilon.cpp +++ b/src/Witness_complex/example/witness_complex_epsilon.cpp @@ -21,546 +21,35 @@ */ #include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include -//#include - -//#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Witness_complex.h" -#include "gudhi/reader_utils.h" -#include "Torus_distance.h" - -#include -#include -#include -#include #include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -using namespace Gudhi; -//using namespace boost::filesystem; +#include typedef CGAL::Epick_d K; -typedef K::Point_d Point_d; -//typedef CGAL::Cartesian_d K; -//typedef CGAL::Point_d Point_d; -typedef K::FT FT; -typedef CGAL::Search_traits< - FT, Point_d, - typename K::Cartesian_const_iterator_d, - typename K::Construct_cartesian_const_iterator_d> Traits_base; -typedef CGAL::Euclidean_distance Euclidean_distance; - - -typedef std::vector< Vertex_handle > typeVectorVertex; - -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -typedef CGAL::Search_traits_adapter< - std::ptrdiff_t, Point_d*, Traits_base> STraits; -//typedef K TreeTraits; -//typedef CGAL::Distance_adapter Euclidean_adapter; -//typedef CGAL::Kd_tree Kd_tree; -typedef CGAL::Orthogonal_k_neighbor_search> K_neighbor_search; -typedef K_neighbor_search::Tree Tree; -typedef K_neighbor_search::Distance Distance; -typedef K_neighbor_search::iterator KNS_iterator; -typedef K_neighbor_search::iterator KNS_range; -typedef boost::container::flat_map Point_etiquette_map; -typedef CGAL::Kd_tree Tree2; - -typedef CGAL::Fuzzy_sphere Fuzzy_sphere; - -typedef std::vector Point_Vector; - -//typedef K::Equal_d Equal_d; -//typedef CGAL::Random_points_in_cube_d > > Random_cube_iterator; -typedef CGAL::Random_points_in_cube_d Random_cube_iterator; -typedef CGAL::Random_points_in_ball_d Random_point_iterator; - -typedef CGAL::Delaunay_triangulation Delaunay_triangulation; -typedef Delaunay_triangulation::Facet Facet; -typedef CGAL::Sphere_d Sphere_d; - -bool toric=false; - - -/** - * \brief Customized version of read_points - * which takes into account a possible nbP first line - * - */ -inline void -read_points_cust ( std::string file_name , Point_Vector & points) -{ - std::ifstream in_file (file_name.c_str(),std::ios::in); - if(!in_file.is_open()) - { - std::cerr << "Unable to open file " << file_name << std::endl; - return; - } - std::string line; - double x; - while( getline ( in_file , line ) ) - { - std::vector< double > point; - std::istringstream iss( line ); - while(iss >> x) { point.push_back(x); } - Point_d p(point.begin(), point.end()); - if (point.size() != 1) - points.push_back(p); - } - in_file.close(); -} - -void generate_points_grid(Point_Vector& W, int width, int D) -{ - int nb_points = 1; - for (int i = 0; i < D; ++i) - nb_points *= width; - for (int i = 0; i < nb_points; ++i) - { - std::vector point; - int cell_i = i; - for (int l = 0; l < D; ++l) - { - point.push_back(0.01*(cell_i%width)); - cell_i /= width; - } - W.push_back(point); - } -} - -void generate_points_random_box(Point_Vector& W, int nbP, int dim) -{ - /* - Random_cube_iterator rp(dim, 1); - for (int i = 0; i < nbP; i++) - { - std::vector point; - for (auto it = rp->cartesian_begin(); it != rp->cartesian_end(); ++it) - point.push_back(*it); - W.push_back(Point_d(point)); - rp++; - } - */ - Random_cube_iterator rp(dim, 1.0); - for (int i = 0; i < nbP; i++) - { - W.push_back(*rp++); - } -} - - -void write_wl( std::string file_name, std::vector< std::vector > & WL) -{ - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : WL) - { - for (auto l: w) - ofs << l << " "; - ofs << "\n"; - } - ofs.close(); -} - - -void write_points( std::string file_name, std::vector< Point_d > & points) -{ - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : points) - { - for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - } - ofs.close(); -} - -void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) -{ - std::ofstream ofs (file_name, std::ofstream::out); - for (auto u: witness_complex.complex_vertex_range()) - for (auto v: witness_complex.complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) - { - for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n\n\n"; - } - } - ofs.close(); -} - - -/** Function that chooses landmarks from W and place it in the kd-tree L. - * Note: nbL hould be removed if the code moves to Witness_complex - */ -void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) -{ - std::cout << "Enter landmark choice to kd tree\n"; - int chosen_landmark; - Point_d* p; - CGAL::Random rand; - for (int i = 0; i < nbL; i++) - { - // while (!res.second) - // { - do chosen_landmark = rand.get_int(0,nbP); - while (std::count(landmarks_ind.begin(),landmarks_ind.end(),chosen_landmark)!=0); - //rand++; - //std::cout << "Chose " << chosen_landmark << std::endl; - p = &W[chosen_landmark]; - //L_i.emplace(chosen_landmark,i); - // } - landmarks.push_back(*p); - landmarks_ind.push_back(chosen_landmark); - //std::cout << "Added landmark " << chosen_landmark << std::endl; - } - } - -void insert_delaunay_landmark_with_copies(Point_Vector& W, int chosen_landmark, std::vector& landmarks_ind, Delaunay_triangulation& delaunay, int& landmark_count) -{ - delaunay.insert(W[chosen_landmark]); - landmarks_ind.push_back(chosen_landmark); - landmark_count++; -} - -bool is_violating_protection(Point_d& p, Delaunay_triangulation& t, int D, FT delta) -{ - Euclidean_distance ed; - Delaunay_triangulation::Vertex_handle v; - Delaunay_triangulation::Face f(t.current_dimension()); - Delaunay_triangulation::Facet ft; - Delaunay_triangulation::Full_cell_handle c; - Delaunay_triangulation::Locate_type lt; - c = t.locate(p, lt, f, ft, v); - for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) - if (!t.is_infinite(fc_it)) - { - std::vector vertices; - for (auto v_it = fc_it->vertices_begin(); v_it != fc_it->vertices_end(); ++v_it) - vertices.push_back((*v_it)->point()); - Sphere_d cs(D, vertices.begin(), vertices.end()); - Point_d center_cs = cs.center(); - FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); - FT dist2 = ed.transformed_distance(center_cs, p); - //if the new point is inside the protection ball of a non conflicting simplex - if (dist2 >= r*r && dist2 <= (r+delta)*(r+delta)) - return true; - } - return false; -} - -bool triangulation_is_protected(Delaunay_triangulation& t, FT delta) -{ - Euclidean_distance ed; - int D = t.current_dimension(); - for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) - if (!t.is_infinite(fc_it)) - for (auto v_it = t.vertices_begin(); v_it != t.vertices_end(); ++v_it) - { - //check if vertex belongs to the face - bool belongs = false; - for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) - if (v_it == *fc_v_it) - { - belongs = true; - break; - } - if (!belongs) - { - std::vector vertices; - for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) - vertices.push_back((*fc_v_it)->point()); - Sphere_d cs(D, vertices.begin(), vertices.end()); - Point_d center_cs = cs.center(); - FT r = sqrt(ed.transformed_distance(center_cs, fc_it->vertex(1)->point())); - FT dist2 = ed.transformed_distance(center_cs, v_it->point()); - //if the new point is inside the protection ball of a non conflicting simplex - if (dist2 <= (r+delta)*(r+delta)) - return false; - } - } - return true; -} - -FT sampling_radius(Delaunay_triangulation& t) -{ - int D = t.current_dimension(); - FT epsilon2 = 4.0; - for (auto fc_it = t.full_cells_begin(); fc_it != t.full_cells_end(); ++fc_it) - { - Point_Vector vertices; - for (auto fc_v_it = fc_it->vertices_begin(); fc_v_it != fc_it->vertices_end(); ++fc_v_it) - vertices.push_back((*fc_v_it)->point()); - Sphere_d cs(D, vertices.begin(), vertices.end()); - FT r2 = Euclidean_distance().transformed_distance(cs.center(), *(vertices.begin())); - if (epsilon2 > r2) - epsilon2 = r2; - } - return sqrt(epsilon2); -} - -FT point_sampling_radius_by_delaunay(Point_Vector& points) -{ - Delaunay_triangulation t(points[0].size()); - t.insert(points.begin(), points.end()); - return sampling_radius(t); -} - -void landmark_choice_protected_delaunay(Point_Vector& W, int nbP, Point_Vector& landmarks, std::vector& landmarks_ind, FT delta) -{ - int D = W[0].size(); - Torus_distance td; - Euclidean_distance ed; - Delaunay_triangulation t(D); - CGAL::Random rand; - int landmark_count = 0; - std::list index_list; - // shuffle the list of indexes (via a vector) - { - std::vector temp_vector; - for (int i = 0; i < nbP; ++i) - temp_vector.push_back(i); - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); - std::shuffle(temp_vector.begin(), temp_vector.end(), std::default_random_engine(seed)); - for (std::vector::iterator it = temp_vector.begin(); it != temp_vector.end(); ++it) - index_list.push_front(*it); - } - // add the first D+1 vertices to form one non-empty cell - for (int i = 0; i <= D+1; ++i) - { - insert_delaunay_landmark_with_copies(W, index_list.front(), landmarks_ind, t, landmark_count); - index_list.pop_front(); - } - // add other vertices if they don't violate protection - std::list::iterator list_it = index_list.begin(); - while (list_it != index_list.end()) - if (!is_violating_protection(W[*list_it], t, D, delta)) - { - // If no conflicts then insert in every copy of T^3 - insert_delaunay_landmark_with_copies(W, *list_it, landmarks_ind, t, landmark_count); - index_list.erase(list_it); - list_it = index_list.begin(); - } - else - list_it++; - for (std::vector::iterator it = landmarks_ind.begin(); it != landmarks_ind.end(); ++it) - landmarks.push_back(W[*it]); -} - - -int landmark_perturbation(Point_Vector &W, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) -{ - //******************** Preface: origin point - int D = W[0].size(); - std::vector orig_vector; - for (int i=0; i landmarks_ext; - int nb_cells = 1; - for (int i = 0; i < D; ++i) - nb_cells *= 3; - for (int i = 0; i < nb_cells; ++i) - for (int k = 0; k < nbL; ++k) - { - std::vector point; - int cell_i = i; - for (int l = 0; l < D; ++l) - { - point.push_back(landmarks[k][l] + 2.0*((cell_i%3)-1.0)); - cell_i /= 3; - } - landmarks_ext.push_back(point); - } - write_points("landmarks/initial_landmarks",landmarks_ext); - STraits traits(&(landmarks_ext[0])); - std::vector< std::vector > WL(nbP); - - //********************** Neighbor search in a Kd tree - Tree L(boost::counting_iterator(0), - boost::counting_iterator(nb_cells*nbL), - typename Tree::Splitter(), - traits); - std::cout << "Enter (D+1) nearest landmarks\n"; - for (int i = 0; i < nbP; i++) - { - Point_d& w = W[i]; - ////Search D+1 nearest neighbours from the tree of landmarks L - K_neighbor_search search(L, w, D+1, FT(0), true, - CGAL::Distance_adapter(&(landmarks_ext[0])) ); - for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) - { - if (std::find(WL[i].begin(), WL[i].end(), (it->first)%nbL) == WL[i].end()) - WL[i].push_back((it->first)%nbL); - } - if (i == landmarks_ind[WL[i][0]]) - { - FT dist = ed.transformed_distance(W[i], landmarks[WL[i][1]]); - if (dist < lambda) - lambda = dist; - } - } - std::string out_file = "wl_result"; - write_wl(out_file,WL); - - //******************** Constructng a witness complex - std::cout << "Entered witness complex construction\n"; - Witness_complex<> witnessComplex; - witnessComplex.setNbL(nbL); - witnessComplex.witness_complex(WL); - - //******************** Making a set of bad link landmarks - std::cout << "Entered bad links\n"; - std::set< int > perturbL; - int count_badlinks = 0; - //std::cout << "Bad links around "; - std::vector< int > count_bad(D); - std::vector< int > count_good(D); - for (auto u: witnessComplex.complex_vertex_range()) - { - if (!witnessComplex.has_good_link(u, count_bad, count_good)) - { - count_badlinks++; - Point_d& l = landmarks[u]; - Fuzzy_sphere fs(l, sqrt(lambda)*3, 0, traits); - std::vector curr_perturb; - L.search(std::insert_iterator>(curr_perturb,curr_perturb.begin()),fs); - for (int i: curr_perturb) - perturbL.insert(i%nbL); - } - } - for (unsigned int i = 0; i != count_good.size(); i++) - if (count_good[i] != 0) - std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; - for (unsigned int i = 0; i != count_bad.size(); i++) - if (count_bad[i] != 0) - std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; - std::cout << "\nBad links total: " << count_badlinks << " Points to perturb: " << perturbL.size() << std::endl; - - //*********************** Perturb bad link landmarks - for (auto u: perturbL) - { - Random_point_iterator rp(D,sqrt(lambda)/8); - std::vector point; - for (int i = 0; i < D; i++) - { - while (K().squared_distance_d_object()(*rp,origin) < lambda/256) - rp++; - FT coord = landmarks[u][i] + (*rp)[i]; - if (coord > 1) - point.push_back(coord-1); - else if (coord < -1) - point.push_back(coord+1); - else - point.push_back(coord); - } - landmarks[u] = Point_d(point); - } - std::cout << "lambda=" << lambda << std::endl; - char buffer[100]; - int i = sprintf(buffer,"stree_result.txt"); - - if (i >= 0) - { - std::string out_file = (std::string)buffer; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - } - write_edges("landmarks/edges", witnessComplex, landmarks); - return count_badlinks; -} - - -int main (int argc, char * const argv[]) -{ - if (argc != 5) - { - std::cerr << "Usage: " << argv[0] - << " nbP nbL dim delta\n"; - return 0; - } - int nbP = atoi(argv[1]); - int nbL = atoi(argv[2]); - int dim = atoi(argv[3]); - FT delta = atof(argv[4]); - - std::cout << "Let the carnage begin!\n"; - Point_Vector point_vector; - generate_points_random_box(point_vector, nbP, dim); - FT epsilon = point_sampling_radius_by_delaunay(point_vector); - std::cout << "Initial epsilon = " << epsilon << std::endl; - Point_Vector L; - std::vector chosen_landmarks; - bool ok=false; - while (!ok) - { - ok = true; - L = {}; - chosen_landmarks = {}; - //landmark_choice_by_delaunay(point_vector, nbP, nbL, L, chosen_landmarks, delta); - landmark_choice_protected_delaunay(point_vector, nbP, L, chosen_landmarks, delta); - nbL = chosen_landmarks.size(); - std::cout << "Number of landmarks is " << nbL << std::endl; - //int width = (int)pow(nbL, 1.0/dim); landmark_choice_bcc(point_vector, nbP, width, L, chosen_landmarks); - for (auto i: chosen_landmarks) - { - ok = ok && (std::count(chosen_landmarks.begin(),chosen_landmarks.end(),i) == 1); - if (!ok) break; - } - - } - FT epsilon2 = point_sampling_radius_by_delaunay(L); - std::cout << "Final epsilon = " << epsilon2 << ". Ratio = " << epsilon/epsilon2 << std::endl; - int bl = nbL, curr_min = bl; - write_points("landmarks/initial_pointset",point_vector); - //write_points("landmarks/initial_landmarks",L); - //for (int i = 0; i < 1; i++) - for (int i = 0; bl > 0; i++) - { - std::cout << "========== Start iteration " << i << "== curr_min(" << curr_min << ")========\n"; - bl=landmark_perturbation(point_vector, nbL, L, chosen_landmarks); - if (bl < curr_min) - curr_min=bl; - write_points("landmarks/landmarks0",L); - } - +typedef K::Point_d Point_d; +typedef K::FT FT; +typedef K::Hyperplane_d Hyperplane_d; +typedef K::Has_on_positive_side_d Has_on_positive_side_d; + +int main () +{ + std::vector vertices; + Point_d v1(std::vector({-1,1})); + Point_d v2(std::vector({1,-1})); + vertices.push_back(v1); + vertices.push_back(v2); + Point_d p(std::vector({-1,-1})); + Hyperplane_d hp(vertices.begin(), vertices.end()); + //Hyperplane_d hp(vertices.begin(), vertices.end(), p, CGAL::ON_POSITIVE_SIDE); + if (Has_on_positive_side_d()(hp, p)) + std::cout << "OK\n"; + else + std::cout << "NOK\n"; + CGAL::Oriented_side side_p = K::Oriented_side_d()(hp, p); + if (side_p == CGAL::ZERO) + std::cout << "Point (-1,-1) is on the line passing through (-1,1) and (1,-1)"; + CGAL::Oriented_side side_v2 = K::Oriented_side_d()(hp, v2); + if (side_v2 != CGAL::ZERO) + std::cout << "Point (1,-1) is not on the line passing through (-1,1) and (1,-1)"; } -- cgit v1.2.3 From 5ea1f5a9e96a3c937531516176cabc7226bed9da Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 6 Oct 2015 15:31:40 +0000 Subject: Introduce Options::contiguous_vertices. For now only used and checked in find_vertex. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@833 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ceee8ba85eb21991a836b8f1d1117bcaafeb8c1b --- src/Simplex_tree/concept/SimplexTreeOptions.h | 2 ++ src/Simplex_tree/include/gudhi/Simplex_tree.h | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/concept/SimplexTreeOptions.h b/src/Simplex_tree/concept/SimplexTreeOptions.h index a50a2bf1..4a88f936 100644 --- a/src/Simplex_tree/concept/SimplexTreeOptions.h +++ b/src/Simplex_tree/concept/SimplexTreeOptions.h @@ -37,5 +37,7 @@ struct SimplexTreeOptions { static constexpr bool store_key; /// If true, each simplex has extra storage for one `Filtration_value`, and this value is propagated by operations like `Gudhi::Simplex_tree::expansion`. Without it, `Persistent_cohomology` degenerates to computing usual (non-persistent) cohomology. static constexpr bool store_filtration; + /// If true, the list of vertices present in the complex must always be 0, ..., num_vertices-1, without any hole. + static constexpr bool contiguous_vertices; }; diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 96565ff1..d19071fb 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -85,6 +85,7 @@ struct Simplex_tree_options_full_featured { typedef int Simplex_key; static const bool store_key = true; static const bool store_filtration = true; + static const bool contiguous_vertices = true; }; /** @@ -564,9 +565,21 @@ class Simplex_tree { /** \brief Returns the Simplex_handle corresponding to the 0-simplex * representing the vertex with Vertex_handle v. */ Simplex_handle find_vertex(Vertex_handle v) { - return root_.members_.begin() + v; + if (Options::contiguous_vertices) { + assert(contiguous_vertices()); + return root_.members_.begin() + v; + } else { + return root_.members_.find(v); + } + } + + /** \private \brief Test if the vertices have contiguous numbering: 0, 1, etc. */ + bool contiguous_vertices() const { + if(root_.members_.empty()) return true; + if(root_.members_.front()!=0) return false; + if(root_.members_.back()!=root_.members_.size()-1) return false; + return true; } - //{ return root_.members_.find(v); } private: /** \brief Inserts a simplex represented by a vector of vertex. -- cgit v1.2.3 From 82424630adfec94295157491a3379bc7888d5f12 Mon Sep 17 00:00:00 2001 From: glisse Date: Thu, 8 Oct 2015 12:28:13 +0000 Subject: Fix contiguous_vertices(). Use it in boundary iterator. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@838 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5b4475f39fe6adf2190223a753625057260e8805 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 5 +++-- .../include/gudhi/Simplex_tree/Simplex_tree_iterators.h | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index d19071fb..30faebc8 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -573,11 +573,12 @@ class Simplex_tree { } } + public: /** \private \brief Test if the vertices have contiguous numbering: 0, 1, etc. */ bool contiguous_vertices() const { if(root_.members_.empty()) return true; - if(root_.members_.front()!=0) return false; - if(root_.members_.back()!=root_.members_.size()-1) return false; + if(root_.members_.begin()->first!=0) return false; + if(std::prev(root_.members_.end())->first!=root_.members_.size()-1) return false; return true; } diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h index f83f5ea8..856fdbdd 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h @@ -135,14 +135,27 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< } Siblings * for_sib = sib_; - for (auto rit = suffix_.rbegin(); rit != suffix_.rend(); ++rit) { + Siblings * new_sib = sib_->oncles(); + auto rit = suffix_.rbegin(); + if (SimplexTree::Options::contiguous_vertices + && new_sib == nullptr + && rit != suffix_.rend()) { + // We reached the root, use a short-cut to find a vertex. We could also + // optimize finding the second vertex of a segment, but people are + // expected to call endpoints(). + assert(st_->contiguous_vertices()); + sh_ = for_sib->members_.begin()+*rit; + for_sib = sh_->second.children(); + ++rit; + } + for (; rit != suffix_.rend(); ++rit) { sh_ = for_sib->find(*rit); for_sib = sh_->second.children(); } sh_ = for_sib->find(last_); // sh_ points to the right simplex now suffix_.push_back(next_); next_ = sib_->parent(); - sib_ = sib_->oncles(); + sib_ = new_sib; } // Most of the storage should be moved to the range, iterators should be light. -- cgit v1.2.3 From ff6ad8b959f6c20380f3d68ebb1bbbf1224adcfd Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 13 Oct 2015 15:34:28 +0000 Subject: Manual merge of skb_simplex_insertion after last trunk big modifications on Skbl git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/skb_simplex_insertion_merge@855 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d7f7721e2963de439a28040196423d4c0df07d3f --- src/Contraction/example/Rips_contraction.cpp | 4 +- src/Contraction/include/gudhi/Edge_contraction.h | 4 +- .../include/gudhi/Skeleton_blocker_contractor.h | 11 +- src/GudhUI/model/Model.h | 6 +- src/GudhUI/utils/Is_manifold.h | 2 +- src/GudhUI/view/Viewer_instructor.cpp | 2 +- src/GudhUI/view/Viewer_instructor.h | 4 +- .../example/Skeleton_blocker_from_simplices.cpp | 29 +- .../example/Skeleton_blocker_iteration.cpp | 7 +- .../example/Skeleton_blocker_link.cpp | 2 +- .../include/gudhi/Skeleton_blocker.h | 33 +- .../Skeleton_blocker_complex_visitor.h | 10 +- .../Skeleton_blocker_link_superior.h | 6 +- .../Skeleton_blocker/Skeleton_blocker_off_io.h | 8 +- .../Skeleton_blocker_sub_complex.h | 24 +- .../include/gudhi/Skeleton_blocker/internal/Trie.h | 34 +- .../Skeleton_blockers_blockers_iterators.h | 4 +- .../Skeleton_blockers_simplices_iterators.h | 109 +- .../Skeleton_blockers_triangles_iterators.h | 18 +- .../include/gudhi/Skeleton_blocker_complex.h | 176 ++- .../gudhi/Skeleton_blocker_geometric_complex.h | 10 +- .../include/gudhi/Skeleton_blocker_link_complex.h | 53 +- .../gudhi/Skeleton_blocker_simplifiable_complex.h | 92 +- src/Skeleton_blocker/test/TestGeometricComplex.cpp | 154 +- src/Skeleton_blocker/test/TestSimplifiable.cpp | 620 ++++---- .../test/TestSkeletonBlockerComplex.cpp | 1632 ++++++++++---------- 26 files changed, 1619 insertions(+), 1435 deletions(-) (limited to 'src') diff --git a/src/Contraction/example/Rips_contraction.cpp b/src/Contraction/example/Rips_contraction.cpp index d21246ed..f80cc2dc 100644 --- a/src/Contraction/example/Rips_contraction.cpp +++ b/src/Contraction/example/Rips_contraction.cpp @@ -49,7 +49,7 @@ void build_rips(ComplexType& complex, double offset) { for (auto p = vertices.begin(); p != vertices.end(); ++p) for (auto q = p; ++q != vertices.end(); /**/) { if (squared_dist(complex.point(*p), complex.point(*q)) < 4 * offset * offset) - complex.add_edge(*p, *q); + complex.add_edge_without_blockers(*p, *q); } } @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) { contractor.contract_edges(); std::cout << "Counting final number of simplices \n"; - unsigned num_simplices = std::distance(complex.simplex_range().begin(), complex.simplex_range().end()); + unsigned num_simplices = std::distance(complex.complex_simplex_range().begin(), complex.complex_simplex_range().end()); std::cout << "Final complex has " << complex.num_vertices() << " vertices, " << diff --git a/src/Contraction/include/gudhi/Edge_contraction.h b/src/Contraction/include/gudhi/Edge_contraction.h index dfce8d1b..b996d9fb 100644 --- a/src/Contraction/include/gudhi/Edge_contraction.h +++ b/src/Contraction/include/gudhi/Edge_contraction.h @@ -158,7 +158,7 @@ void build_rips(ComplexType& complex, double offset){ for (auto p = vertices.begin(); p != vertices.end(); ++p) for (auto q = p; ++q != vertices.end(); ) if (eucl_distance(complex.point(*p), complex.point(*q)) < 2 * offset) - complex.add_edge(*p,*q); + complex.add_edge_without_blockers(*p,*q); } int main (int argc, char *argv[]) @@ -194,7 +194,7 @@ int main (int argc, char *argv[]) contractor.contract_edges(); std::cout << "Counting final number of simplices \n"; - unsigned num_simplices = std::distance(complex.simplex_range().begin(),complex.simplex_range().end()); + unsigned num_simplices = std::distance(complex.star_simplex_range().begin(),complex.star_simplex_range().end()); std::cout << "Final complex has "<< complex.num_vertices()<<" vertices, "<< diff --git a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h index 2759b540..d6350a2c 100644 --- a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h +++ b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h @@ -107,13 +107,8 @@ typename GeometricSimplifiableComplex::Vertex_handle> { public: typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex; typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle; - typedef typename GeometricSimplifiableComplex::Simplex_handle Simplex_handle; - typedef typename GeometricSimplifiableComplex::Simplex_handle_iterator Simplex_handle_iterator; - - - + typedef typename GeometricSimplifiableComplex::Simplex Simplex; typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle; - typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge; typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle; typedef typename GeometricSimplifiableComplex::Point Point; @@ -535,14 +530,14 @@ typename GeometricSimplifiableComplex::Vertex_handle> { * All the edges that passes through the blocker may be edge-contractible * again and are thus reinserted in the heap. */ - void on_delete_blocker(const Simplex_handle * blocker) override { + void on_delete_blocker(const Simplex * blocker) override { // we go for all pairs xy that belongs to the blocker // note that such pairs xy are necessarily edges of the complex // by definition of a blocker // todo uniqument utile pour la link condition // laisser a l'utilisateur ? booleen update_heap_on_removed_blocker? - Simplex_handle blocker_copy(*blocker); + Simplex blocker_copy(*blocker); for (auto x = blocker_copy.begin(); x != blocker_copy.end(); ++x) { for (auto y = x; ++y != blocker_copy.end();) { auto edge_descr(complex_[std::make_pair(*x, *y)]); diff --git a/src/GudhUI/model/Model.h b/src/GudhUI/model/Model.h index d78cbad9..07a67a0c 100644 --- a/src/GudhUI/model/Model.h +++ b/src/GudhUI/model/Model.h @@ -249,7 +249,7 @@ class Model { int euler = 0; int dimension = 0; Clock clock; - for (const auto &s : complex_.simplex_range()) { + for (const auto &s : complex_.complex_simplex_range()) { num_simplices++; dimension = (std::max)(s.dimension(), dimension); if (s.dimension() % 2 == 0) @@ -281,7 +281,7 @@ class Model { unsigned num_simplices = 0; int euler = 0; int dimension = 0; - for (const auto &s : complex_.simplex_range()) { + for (const auto &s : complex_.complex_simplex_range()) { num_simplices++; dimension = (std::max)(s.dimension(), dimension); if (s.dimension() % 2 == 0) @@ -328,7 +328,7 @@ class Model { void save_complex_in_file_for_chomp() { std::ofstream file; file.open("chomp.sim"); - for (const auto &s : complex_.simplex_range()) { + for (const auto &s : complex_.complex_simplex_range()) { bool first = true; file << "("; for (auto x : s) { diff --git a/src/GudhUI/utils/Is_manifold.h b/src/GudhUI/utils/Is_manifold.h index b6b19ee0..0640ea47 100644 --- a/src/GudhUI/utils/Is_manifold.h +++ b/src/GudhUI/utils/Is_manifold.h @@ -69,7 +69,7 @@ template class Is_manifold { private: unsigned local_dimension(Vertex_handle v) { unsigned dim = 0; - for (const auto& s : input_complex_.simplex_range(v)) + for (const auto& s : input_complex_.star_simplex_range(v)) dim = (std::max)(dim, (unsigned) s.dimension()); return dim; } diff --git a/src/GudhUI/view/Viewer_instructor.cpp b/src/GudhUI/view/Viewer_instructor.cpp index 4446d209..1ddd4d8b 100644 --- a/src/GudhUI/view/Viewer_instructor.cpp +++ b/src/GudhUI/view/Viewer_instructor.cpp @@ -159,7 +159,7 @@ void Viewer_instructor::set_color_edge(Edge_handle eh) { viewer_->set_color(Color(view_params_.light_edges, view_params_.light_edges, view_params_.light_edges)); } -void Viewer_instructor::set_color_triangle(const Simplex_handle& triangle) { +void Viewer_instructor::set_color_triangle(const Simplex& triangle) { viewer_->set_color(Color(view_params_.light_triangles, view_params_.light_triangles, view_params_.light_triangles)); } diff --git a/src/GudhUI/view/Viewer_instructor.h b/src/GudhUI/view/Viewer_instructor.h index 31a1d273..82c8e346 100644 --- a/src/GudhUI/view/Viewer_instructor.h +++ b/src/GudhUI/view/Viewer_instructor.h @@ -52,7 +52,7 @@ class Viewer_instructor : public QWidget { typedef Complex::Point Point; typedef Complex::Vertex_handle Vertex_handle; typedef Complex::Edge_handle Edge_handle; - typedef Complex::Simplex_handle Simplex_handle; + typedef Complex::Simplex Simplex; Viewer* viewer_; View_parameter view_params_; @@ -98,7 +98,7 @@ class Viewer_instructor : public QWidget { void set_color_vertex(Vertex_handle vh); void set_color_edge(Edge_handle eh); - void set_color_triangle(const Simplex_handle& triangle); + void set_color_triangle(const Simplex& triangle); private: /** diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp index 2738c01c..5935a56d 100644 --- a/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp +++ b/src/Skeleton_blocker/example/Skeleton_blocker_from_simplices.cpp @@ -35,24 +35,23 @@ using namespace skbl; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; -typedef Complex::Simplex_handle Simplex_handle; -typedef Complex::Simplex_handle Simplex; +typedef Complex::Simplex Simplex; int main(int argc, char *argv[]) { - std::vector simplices; + std::vector simplices; // add 4 triangles of a tetrahedron 0123 - simplices.push_back(Simplex_handle(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); - simplices.push_back(Simplex_handle(Vertex_handle(3), Vertex_handle(0), Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(3), Vertex_handle(0), Vertex_handle(1))); + simplices.push_back(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); + simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(0), Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(0), Vertex_handle(1))); // get complex from top faces Complex complex(make_complex_from_top_faces(simplices.begin(), simplices.end())); std::cout << "Simplices:" << std::endl; - for (const Simplex & s : complex.simplex_range()) + for (const Simplex & s : complex.complex_simplex_range()) std::cout << s << " "; std::cout << std::endl; @@ -61,16 +60,16 @@ int main(int argc, char *argv[]) { // now build a complex from its full list of simplices simplices.clear(); - simplices.push_back(Simplex_handle(Vertex_handle(0))); - simplices.push_back(Simplex_handle(Vertex_handle(1))); - simplices.push_back(Simplex_handle(Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(0), Vertex_handle(1))); - simplices.push_back(Simplex_handle(Vertex_handle(1), Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(2), Vertex_handle(0))); + simplices.push_back(Simplex(Vertex_handle(0))); + simplices.push_back(Simplex(Vertex_handle(1))); + simplices.push_back(Simplex(Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(0), Vertex_handle(1))); + simplices.push_back(Simplex(Vertex_handle(1), Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(2), Vertex_handle(0))); complex = Complex(simplices.begin(), simplices.end()); std::cout << "Simplices:" << std::endl; - for (const Simplex & s : complex.simplex_range()) + for (const Simplex & s : complex.complex_simplex_range()) std::cout << s << " "; std::cout << std::endl; diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp index 69557694..41b5ee00 100644 --- a/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp +++ b/src/Skeleton_blocker/example/Skeleton_blocker_iteration.cpp @@ -37,7 +37,7 @@ using namespace skbl; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; -typedef Complex::Simplex_handle Simplex; +typedef Complex::Simplex Simplex; Complex build_complete_complex(int n) { // build a full complex with n vertices and 2^n-1 simplices @@ -46,8 +46,7 @@ Complex build_complete_complex(int n) { complex.add_vertex(); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) - // note that add_edge, add the edge and all its cofaces - complex.add_edge(Vertex_handle(i), Vertex_handle(j)); + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); return complex; } @@ -77,7 +76,7 @@ int main(int argc, char *argv[]) { // we use a reference to a simplex instead of a copy // value here because a simplex is a set of integers // and copying it cost time - for (const Simplex & s : complex.simplex_range()) { + for (const Simplex & s : complex.complex_simplex_range()) { ++num_simplices; if (s.dimension() % 2 == 0) euler += 1; diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp index 002cbc49..5c717938 100644 --- a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp +++ b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp @@ -35,7 +35,7 @@ using namespace skbl; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; typedef Complex::Root_vertex_handle Root_vertex_handle; -typedef Complex::Simplex_handle Simplex; +typedef Complex::Simplex Simplex; int main(int argc, char *argv[]) { // build a full complex with 4 vertices and 2^4-1 simplices diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h index 792a7994..e1f53f48 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h @@ -129,7 +129,7 @@ of a simplicial complex. \code{.cpp} typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; - typedef Complex::Simplex_handle Simplex; + typedef Complex::Simplex Simplex; const int n = 15; @@ -139,8 +139,7 @@ of a simplicial complex. complex.add_vertex(); for(int i=0;i simplices; + std::vector simplices; //add 4 triangles of a tetrahedron 0123 - simplices.push_back(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3))); - simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(0),Vertex_handle(1))); + simplices.push_back(Simplex(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3))); + simplices.push_back(Simplex(Vertex_handle(3),Vertex_handle(0),Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(3),Vertex_handle(0),Vertex_handle(1))); Complex complex; //get complex from top faces make_complex_from_top_faces(complex,simplices.begin(),simplices.end()); std::cout << "Simplices:"<(parent_complex, alpha_parent_adress, true) { } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h index ec000986..ad2d2f85 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h @@ -61,7 +61,7 @@ class Skeleton_blocker_off_flag_visitor_reader { if (!load_only_points_) { for (size_t i = 0; i < face.size(); ++i) for (size_t j = i + 1; j < face.size(); ++j) { - complex_.add_edge(Vertex_handle(face[i]), Vertex_handle(face[j])); + complex_.add_edge_without_blockers(Vertex_handle(face[i]), Vertex_handle(face[j])); } } } @@ -76,12 +76,12 @@ template class Skeleton_blocker_off_visitor_reader { Complex& complex_; typedef typename Complex::Vertex_handle Vertex_handle; - typedef typename Complex::Simplex_handle Simplex_handle; + typedef typename Complex::Simplex Simplex; typedef typename Complex::Point Point; const bool load_only_points_; std::vector points_; - std::vector maximal_faces_; + std::vector maximal_faces_; public: explicit Skeleton_blocker_off_visitor_reader(Complex& complex, bool load_only_points = false) : @@ -99,7 +99,7 @@ class Skeleton_blocker_off_visitor_reader { void maximal_face(const std::vector& face) { if (!load_only_points_) { - Simplex_handle s; + Simplex s; for (auto x : face) s.add_vertex(Vertex_handle(x)); maximal_faces_.emplace_back(s); diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h index b33b9606..50a83345 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h @@ -66,12 +66,12 @@ class Skeleton_blocker_sub_complex : public ComplexType { public: using ComplexType::add_vertex; - using ComplexType::add_edge; + using ComplexType::add_edge_without_blockers; using ComplexType::add_blocker; typedef typename ComplexType::Vertex_handle Vertex_handle; typedef typename ComplexType::Root_vertex_handle Root_vertex_handle; - typedef typename ComplexType::Simplex_handle Simplex_handle; + typedef typename ComplexType::Simplex Simplex; typedef typename ComplexType::Root_simplex_handle Root_simplex_handle; protected: @@ -109,11 +109,11 @@ class Skeleton_blocker_sub_complex : public ComplexType { * It assumes that both vertices corresponding to v1_root and v2_root are present * in the sub-complex. */ - void add_edge(Root_vertex_handle v1_root, Root_vertex_handle v2_root) { + void add_edge_without_blockers(Root_vertex_handle v1_root, Root_vertex_handle v2_root) { auto v1_sub(this->get_address(v1_root)); auto v2_sub(this->get_address(v2_root)); assert(v1_sub && v2_sub); - this->ComplexType::add_edge(*v1_sub, *v2_sub); + this->ComplexType::add_edge_without_blockers(*v1_sub, *v2_sub); } /** @@ -124,7 +124,7 @@ class Skeleton_blocker_sub_complex : public ComplexType { void add_blocker(const Root_simplex_handle& blocker_root) { auto blocker_sub = this->get_address(blocker_root); assert(blocker_sub); - this->add_blocker(new Simplex_handle(*blocker_sub)); + this->add_blocker(new Simplex(*blocker_sub)); } public: @@ -133,7 +133,7 @@ class Skeleton_blocker_sub_complex : public ComplexType { * vertices of 'simplex'. */ void make_restricted_complex(const ComplexType & parent_complex, - const Simplex_handle& simplex) { + const Simplex& simplex) { this->clear(); // add vertices to the sub complex for (auto x : simplex) { @@ -145,11 +145,11 @@ class Skeleton_blocker_sub_complex : public ComplexType { // add edges to the sub complex for (auto x : simplex) { // x_neigh is the neighbor of x intersected with vertices_simplex - Simplex_handle x_neigh; + Simplex x_neigh; parent_complex.add_neighbours(x, x_neigh, true); x_neigh.intersection(simplex); for (auto y : x_neigh) { - this->add_edge(parent_complex[x].get_id(), parent_complex[y].get_id()); + this->add_edge_without_blockers(parent_complex[x].get_id(), parent_complex[y].get_id()); } } @@ -158,9 +158,9 @@ class Skeleton_blocker_sub_complex : public ComplexType { // check if it is the first time we encounter the blocker if (simplex.contains(*blocker)) { Root_simplex_handle blocker_root(parent_complex.get_id(*(blocker))); - Simplex_handle blocker_restr( + Simplex blocker_restr( *(this->get_simplex_address(blocker_root))); - this->add_blocker(new Simplex_handle(blocker_restr)); + this->add_blocker(new Simplex(blocker_restr)); } } } @@ -188,7 +188,7 @@ class Skeleton_blocker_sub_complex : public ComplexType { // * Allocates a simplex in L corresponding to the simplex s in K // * with its local adresses and returns an AddressSimplex. // */ - // boost::optional get_address(const Root_simplex_handle & s) const; + // boost::optional get_address(const Root_simplex_handle & s) const; // private: /** @@ -220,7 +220,7 @@ bool proper_face_in_union( // we test that all vertices of 'addresses_sigma_in_link' but 'vertex_to_be_ignored' // are in link1 if it is the case we construct the corresponding simplex bool vertices_sigma_are_in_link = true; - typename ComplexType::Simplex_handle sigma_in_link; + typename ComplexType::Simplex sigma_in_link; for (int i = 0; i < addresses_sigma_in_link.size(); ++i) { if (i != vertex_to_be_ignored) { if (!addresses_sigma_in_link[i]) { diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h index aa0416ef..499980c4 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/internal/Trie.h @@ -36,7 +36,7 @@ namespace skbl { template struct Trie { - typedef SimplexHandle Simplex_handle; + typedef SimplexHandle Simplex; typedef typename SimplexHandle::Vertex_handle Vertex_handle; Vertex_handle v; @@ -64,7 +64,7 @@ struct Trie { } } - typedef typename Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator; + typedef typename Simplex::Simplex_vertex_const_iterator Simplex_vertex_const_iterator; Trie* make_trie(Simplex_vertex_const_iterator s_it, Simplex_vertex_const_iterator s_end) { if (s_it == s_end) { @@ -97,7 +97,7 @@ struct Trie { return; } - void maximal_faces_helper(std::vector& res) const { + void maximal_faces_helper(std::vector& res) const { if (is_leaf()) res.push_back(simplex()); else for (auto child : childs) @@ -108,14 +108,14 @@ struct Trie { /** * adds the simplex to the trie */ - void add_simplex(const Simplex_handle& s) { + void add_simplex(const Simplex& s) { if (s.empty()) return; assert(v == s.first_vertex()); add_simplex_helper(s.begin(), s.end()); } - std::vector maximal_faces() const { - std::vector res; + std::vector maximal_faces() const { + std::vector res; maximal_faces_helper(res); return res; } @@ -123,14 +123,14 @@ struct Trie { /** * Goes to the root in the trie to consitute simplex */ - void add_vertices_up_to_the_root(Simplex_handle& res) const { + void add_vertices_up_to_the_root(Simplex& res) const { res.add_vertex(v); if (parent_) parent_->add_vertices_up_to_the_root(res); } - Simplex_handle simplex() const { - Simplex_handle res; + Simplex simplex() const { + Simplex res; add_vertices_up_to_the_root(res); return res; } @@ -156,7 +156,7 @@ struct Trie { /** * true iff the simplex corresponds to one node in the trie */ - bool contains(const Simplex_handle& s) const { + bool contains(const Simplex& s) const { Trie const* current = this; if (s.empty()) return true; if (current->v != s.first_vertex()) return false; @@ -196,9 +196,9 @@ struct Trie { template struct Tries { typedef typename SimplexHandle::Vertex_handle Vertex_handle; - typedef SimplexHandle Simplex_handle; + typedef SimplexHandle Simplex; - typedef Trie STrie; + typedef Trie STrie; template Tries(unsigned num_vertices, SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) : @@ -218,14 +218,14 @@ struct Tries { // return a simplex that consists in all u such uv is an edge and u>v - Simplex_handle positive_neighbors(Vertex_handle v) const { - Simplex_handle res; + Simplex positive_neighbors(Vertex_handle v) const { + Simplex res; for (auto child : cofaces_[v]->childs) res.add_vertex(child->v); return res; } - bool contains(const Simplex_handle& s) const { + bool contains(const Simplex& s) const { auto first_v = s.first_vertex(); return cofaces_[first_v]->contains(s); } @@ -238,8 +238,8 @@ struct Tries { // init_next_dimension must be called first - std::vector next_dimension_simplices() const { - std::vector res; + std::vector next_dimension_simplices() const { + std::vector res; while (!to_see_.empty() && to_see_.front()->simplex().dimension() == current_dimension_) { res.emplace_back(to_see_.front()->simplex()); for (auto child : to_see_.front()->childs) diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h index 56a20a24..4a437ac6 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_blockers_iterators.h @@ -31,7 +31,7 @@ namespace skbl { /** * @brief Iterator through the blockers of a vertex. */ -// ReturnType = const Simplex_handle* or Simplex_handle* +// ReturnType = const Simplex* or Simplex* // MapIteratorType = BlockerMapConstIterator or BlockerMapIterator template @@ -83,7 +83,7 @@ ReturnType /** * @brief Iterator through the blockers of a vertex */ -// ReturnType = const Simplex_handle* or Simplex_handle* +// ReturnType = const Simplex* or Simplex* // MapIteratorType = BlockerMapConstIterator or BlockerMapIterator template diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h index 4d71b3f5..ce565166 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h @@ -48,20 +48,20 @@ namespace skbl { template class Simplex_around_vertex_iterator : public boost::iterator_facade < Simplex_around_vertex_iterator -, typename SkeletonBlockerComplex::Simplex_handle +, typename SkeletonBlockerComplex::Simplex , boost::forward_traversal_tag -, typename SkeletonBlockerComplex::Simplex_handle +, typename SkeletonBlockerComplex::Simplex > { friend class boost::iterator_core_access; typedef SkeletonBlockerComplex Complex; typedef typename Complex::Vertex_handle Vertex_handle; typedef typename Complex::Edge_handle Edge_handle; - typedef typename Complex::Simplex_handle Simplex_handle; + typedef typename Complex::Simplex Simplex; // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion typedef typename Link::Vertex_handle Link_vertex_handle; - typedef typename Gudhi::skbl::Trie Trie; + typedef typename Gudhi::skbl::Trie Trie; private: const Complex* complex; @@ -120,7 +120,7 @@ public boost::iterator_facade < Simplex_around_vertex_iteratorvertex_range(link_vh)) { if (link_vh < nv) { - Simplex_handle simplex_node_plus_nv(res->simplex()); + Simplex simplex_node_plus_nv(res->simplex()); simplex_node_plus_nv.add_vertex(parent_vertex(nv)); if (complex->contains(simplex_node_plus_nv)) { res->add_child(build_trie(nv, res)); @@ -176,13 +176,13 @@ public boost::iterator_facade < Simplex_around_vertex_iteratorsimplex(); } - Simplex_handle get_trie_address() const { + Simplex get_trie_address() const { assert(!nodes_to_be_seen.empty()); return nodes_to_be_seen.front(); } @@ -200,9 +200,9 @@ public boost::iterator_facade < Simplex_around_vertex_iterator class Simplex_iterator : public boost::iterator_facade < Simplex_iterator -, typename SkeletonBlockerComplex::Simplex_handle +, typename SkeletonBlockerComplex::Simplex , boost::forward_traversal_tag -, typename SkeletonBlockerComplex::Simplex_handle +, typename SkeletonBlockerComplex::Simplex > { typedef Skeleton_blocker_link_superior Link; @@ -213,7 +213,7 @@ public boost::iterator_facade < Simplex_iterator typedef SkeletonBlockerComplex Complex; typedef typename Complex::Vertex_handle Vertex_handle; typedef typename Complex::Edge_handle Edge_handle; - typedef typename Complex::Simplex_handle Simplex_handle; + typedef typename Complex::Simplex Simplex; typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator; typedef typename Link::Vertex_handle Link_vertex_handle; @@ -290,7 +290,7 @@ public boost::iterator_facade < Simplex_iterator } } - Simplex_handle dereference() const { + Simplex dereference() const { return current_simplex_around_current_vertex_.dereference(); } @@ -304,6 +304,93 @@ public boost::iterator_facade < Simplex_iterator } }; +/** + * Iterator through the maximal faces of the coboundary of a simplex. + */ +template +class Simplex_coboundary_iterator : +public boost::iterator_facade < Simplex_coboundary_iterator +, typename SkeletonBlockerComplex::Simplex, boost::forward_traversal_tag, typename SkeletonBlockerComplex::Simplex> { + friend class boost::iterator_core_access; + typedef SkeletonBlockerComplex Complex; + typedef typename Complex::Vertex_handle Vertex_handle; + typedef typename Complex::Edge_handle Edge_handle; + typedef typename Complex::Simplex Simplex; + typedef typename Complex::Complex_vertex_iterator Complex_vertex_iterator; + + // Link_vertex_handle == Complex_Vertex_handle but this renaming helps avoiding confusion + typedef typename Link::Vertex_handle Link_vertex_handle; + + private: + const Complex* complex; + const Simplex& sigma; + std::shared_ptr link; + Complex_vertex_iterator current_vertex; + Complex_vertex_iterator link_vertex_end; + + public: + Simplex_coboundary_iterator() : complex(0) {} + + Simplex_coboundary_iterator(const Complex* complex_, const Simplex& sigma_) : + complex(complex_), + sigma(sigma_), + //need only vertices of the link hence the true flag + link(new Link(*complex_, sigma_, false, true)) { + auto link_vertex_range = link->vertex_range(); + current_vertex = link_vertex_range.begin(); + link_vertex_end = link_vertex_range.end(); + } + + Simplex_coboundary_iterator(const Simplex_coboundary_iterator& other) : + complex(other.complex), + sigma(other.sigma), + link(other.link), + current_vertex(other.current_vertex), + link_vertex_end(other.link_vertex_end) { } + + // returns an iterator to the end + Simplex_coboundary_iterator(const Complex* complex_,const Simplex& sigma_, bool end) : + complex(complex_), + sigma(sigma_) { + // to represent an end iterator without having to build a useless link, we use + // the convection that link is not initialized. + } + + private: + Vertex_handle parent_vertex(Link_vertex_handle link_vh) const { + return complex->convert_handle_from_another_complex(*link, link_vh); + } + +public: + friend std::ostream& operator<<(std::ostream& stream, const Simplex_coboundary_iterator& sci) { + return stream; + } + + // assume that iterator points to the same complex and comes from the same simplex + bool equal(const Simplex_coboundary_iterator& other) const { + assert(complex == other.complex && sigma == other.sigma); + if(is_end()) return other.is_end(); + if(other.is_end()) return is_end(); + return *current_vertex == *(other.current_vertex); + } + + void increment() { + ++current_vertex; + } + + Simplex dereference() const { + Simplex res(sigma); + res.add_vertex(parent_vertex(*current_vertex)); + return res; + } + +private: + bool is_end() const { + return !link || current_vertex == link_vertex_end; + } +}; + + } // namespace skbl } // namespace Gudhi diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h index 28f5805d..116023d7 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/iterators/Skeleton_blockers_triangles_iterators.h @@ -37,15 +37,15 @@ namespace skbl { template class Triangle_around_vertex_iterator : public boost::iterator_facade < Triangle_around_vertex_iterator -, typename Complex::Simplex_handle const +, typename Complex::Simplex const , boost::forward_traversal_tag -, typename Complex::Simplex_handle const> { +, typename Complex::Simplex const> { friend class boost::iterator_core_access; template friend class Triangle_iterator; private: typedef typename LinkType::Vertex_handle Vertex_handle; typedef typename LinkType::Root_vertex_handle Root_vertex_handle; - typedef typename LinkType::Simplex_handle Simplex_handle; + typedef typename LinkType::Simplex Simplex; typedef typename Complex::Complex_edge_iterator Complex_edge_iterator_; const Complex* complex_; @@ -87,10 +87,10 @@ class Triangle_around_vertex_iterator : public boost::iterator_facade return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_); } - Simplex_handle dereference() const { + Simplex dereference() const { Root_vertex_handle v1 = (*link_)[*current_edge_].first(); Root_vertex_handle v2 = (*link_)[*current_edge_].second(); - return Simplex_handle(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2))); + return Simplex(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2))); } void increment() { @@ -112,14 +112,14 @@ class Triangle_around_vertex_iterator : public boost::iterator_facade template class Triangle_iterator : public boost::iterator_facade< Triangle_iterator , -typename SkeletonBlockerComplex::Simplex_handle const +typename SkeletonBlockerComplex::Simplex const , boost::forward_traversal_tag -, typename SkeletonBlockerComplex::Simplex_handle const> { +, typename SkeletonBlockerComplex::Simplex const> { friend class boost::iterator_core_access; private: typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle; typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle; - typedef typename SkeletonBlockerComplex::Simplex_handle Simplex_handle; + typedef typename SkeletonBlockerComplex::Simplex Simplex; typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI; typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator; @@ -175,7 +175,7 @@ typename SkeletonBlockerComplex::Simplex_handle const current_vertex_ == other.current_vertex_ && current_triangle_ == other.current_triangle_)); } - Simplex_handle dereference() const { + Simplex dereference() const { return *current_triangle_; } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index 07f371a2..78384abf 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -94,16 +94,16 @@ class Skeleton_blocker_complex { /** * @brief A ordered set of integers that represents a simplex. */ - typedef Skeleton_blocker_simplex Simplex_handle; + typedef Skeleton_blocker_simplex Simplex; typedef Skeleton_blocker_simplex Root_simplex_handle; /** * @brief Handle to a blocker of the complex. */ - typedef Simplex_handle* Blocker_handle; + typedef Simplex* Blocker_handle; typedef typename Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_iterator; - typedef typename Simplex_handle::Simplex_vertex_const_iterator Simplex_handle_iterator; + typedef typename Simplex::Simplex_vertex_const_iterator Simplex_handle_iterator; protected: typedef typename boost::adjacency_list::edge_descriptor Edge_handle; protected: - typedef std::multimap BlockerMap; - typedef typename std::multimap::value_type BlockerPair; - typedef typename std::multimap::iterator BlockerMapIterator; - typedef typename std::multimap::const_iterator BlockerMapConstIterator; + typedef std::multimap BlockerMap; + typedef typename std::multimap::value_type BlockerPair; + typedef typename std::multimap::iterator BlockerMapIterator; + typedef typename std::multimap::const_iterator BlockerMapConstIterator; protected: int num_vertices_; @@ -174,7 +174,7 @@ class Skeleton_blocker_complex { private: // typedef Trie> STrie; - typedef Trie STrie; + typedef Trie STrie; public: /** @@ -207,12 +207,12 @@ class Skeleton_blocker_complex { while (num_vertex-- >= 0) add_vertex(); for (const auto& e : edges) - add_edge(e.first, e.second); + add_edge_without_blockers(e.first, e.second); } template void add_blockers(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) { - Tries tries(num_vertices(), simplex_begin, simplex_end); + Tries tries(num_vertices(), simplex_begin, simplex_end); tries.init_next_dimension(); auto simplices(tries.next_dimension_simplices()); @@ -221,7 +221,7 @@ class Skeleton_blocker_complex { 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())); + Simplex 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)); @@ -427,7 +427,7 @@ class Skeleton_blocker_complex { * @return true iff the simplicial complex contains all vertices * of simplex sigma */ - bool contains_vertices(const Simplex_handle & sigma) const { + bool contains_vertices(const Simplex & sigma) const { for (auto vertex : sigma) if (!contains_vertex(vertex)) return false; @@ -535,41 +535,68 @@ class Skeleton_blocker_complex { * @details it assumes that the edge is present in the complex */ - Simplex_handle get_vertices(Edge_handle edge_handle) const { + Simplex get_vertices(Edge_handle edge_handle) const { auto edge((*this)[edge_handle]); - return Simplex_handle((*this)[edge.first()], (*this)[edge.second()]); + return Simplex((*this)[edge.first()], (*this)[edge.second()]); } /** - * @brief Adds an edge between vertices a and b and all its cofaces. + * @brief Adds an edge between vertices a and b. + * @details For instance, the complex contains edge 01 and 12, then calling + * add_edge with vertex 0 and 2 will create a complex containing + * the edges 01, 12, 20 but not the triangle 012 (and hence this complex + * will contains a blocker 012). */ - Edge_handle add_edge(Vertex_handle a, Vertex_handle b) { + Edge_handle add_edge(Vertex_handle a, Vertex_handle b) { + //if the edge is already there we musnt go further + //as we may add blockers that should not be here + if(contains_edge(a,b)) + return *((*this)[std::make_pair(a,b)]); + auto res = add_edge_without_blockers(a,b); + add_blockers_after_simplex_insertion(Simplex(a,b)); + return res; + } + + /** + * @brief Adds all edges of s in the complex. + */ + void add_edge(const Simplex& s) { + for(auto i = s.begin(); i != s.end(); ++i) + for(auto j = i; ++j != s.end(); /**/) + add_edge(*i,*j); + } + + /** + * @brief Adds an edge between vertices a and b without blockers. + * @details For instance, the complex contains edge 01 and 12, then calling + * add_edge with vertex 0 and 2 will create a complex containing + * the triangle 012. + */ + Edge_handle add_edge_without_blockers(Vertex_handle a, Vertex_handle b) { assert(contains_vertex(a) && contains_vertex(b)); assert(a != b); auto edge_handle((*this)[std::make_pair(a, b)]); - // std::pair pair_descr_bool = (*this)[std::make_pair(a,b)]; - // Edge_handle edge_descr; - // bool edge_present = pair_descr_bool.second; if (!edge_handle) { edge_handle = boost::add_edge(a.vertex, b.vertex, skeleton).first; (*this)[*edge_handle].setId(get_id(a), get_id(b)); degree_[a.vertex]++; degree_[b.vertex]++; if (visitor) - visitor->on_add_edge(a, b); + visitor->on_add_edge_without_blockers(a, b); } return *edge_handle; } + /** - * @brief Adds all edges and their cofaces of a simplex to the simplicial complex. + * @brief Adds all edges of s in the complex without adding blockers. */ - void add_edges(const Simplex_handle & sigma) { - Simplex_handle_iterator i, j; - for (i = sigma.begin(); i != sigma.end(); ++i) - for (j = i, j++; j != sigma.end(); ++j) - add_edge(*i, *j); + void add_edge_without_blockers(Simplex s) { + for(auto i = s.begin(); i != s.end(); ++i){ + for(auto j = i; ++j != s.end(); /**/) + add_edge_without_blockers(*i,*j); + } } /** @@ -627,7 +654,7 @@ class Skeleton_blocker_complex { * @return true iff the simplicial complex contains all vertices * and all edges of simplex sigma */ - bool contains_edges(const Simplex_handle & sigma) const { + bool contains_edges(const Simplex & sigma) const { for (auto i = sigma.begin(); i != sigma.end(); ++i) { if (!contains_vertex(*i)) return false; @@ -649,15 +676,14 @@ class Skeleton_blocker_complex { * @brief Adds the simplex to the set of blockers and * returns a Blocker_handle toward it if was not present before and 0 otherwise. */ - Blocker_handle add_blocker(const Simplex_handle& blocker) { + Blocker_handle add_blocker(const Simplex& blocker) { assert(blocker.dimension() > 1); if (contains_blocker(blocker)) { - // std::cerr << "ATTEMPT TO ADD A BLOCKER ALREADY THERE ---> BLOCKER IGNORED" << endl; return 0; } else { if (visitor) visitor->on_add_blocker(blocker); - Blocker_handle blocker_pt = new Simplex_handle(blocker); + Blocker_handle blocker_pt = new Simplex(blocker); num_blockers_++; auto vertex = blocker_pt->begin(); while (vertex != blocker_pt->end()) { @@ -739,7 +765,7 @@ class Skeleton_blocker_complex { * * @remark contrarily to delete_blockers does not call the destructor */ - void remove_blocker(const Simplex_handle& sigma) { + void remove_blocker(const Simplex& sigma) { assert(contains_blocker(sigma)); for (auto vertex : sigma) remove_blocker(sigma, vertex); @@ -777,7 +803,7 @@ class Skeleton_blocker_complex { /** * @return true iff s is a blocker of the simplicial complex */ - bool contains_blocker(const Simplex_handle & s) const { + bool contains_blocker(const Simplex & s) const { if (s.dimension() < 2) return false; @@ -795,7 +821,7 @@ class Skeleton_blocker_complex { * @return true iff a blocker of the simplicial complex * is a face of sigma. */ - bool blocks(const Simplex_handle & sigma) const { + bool blocks(const Simplex & sigma) const { for (auto s : sigma) for (auto blocker : const_blocker_range(s)) if (sigma.contains(*blocker)) @@ -810,7 +836,7 @@ class Skeleton_blocker_complex { * @details Adds to simplex the neighbours of v e.g. \f$ n \leftarrow n \cup N(v) \f$. * If keep_only_superior is true then only vertices that are greater than v are added. */ - virtual void add_neighbours(Vertex_handle v, Simplex_handle & n, + virtual void add_neighbours(Vertex_handle v, Simplex & n, bool keep_only_superior = false) const { boost_adjacency_iterator ai, ai_end; for (tie(ai, ai_end) = adjacent_vertices(v.vertex, skeleton); ai != ai_end; @@ -833,7 +859,7 @@ class Skeleton_blocker_complex { * todo revoir * */ - virtual void add_neighbours(const Simplex_handle &alpha, Simplex_handle & res, + virtual void add_neighbours(const Simplex &alpha, Simplex & res, bool keep_only_superior = false) const { res.clear(); auto alpha_vertex = alpha.begin(); @@ -848,9 +874,9 @@ class Skeleton_blocker_complex { * not neighbours of v e.g. \f$ res \leftarrow res \cap N(v) \f$. * If 'keep_only_superior' is true then only vertices that are greater than v are keeped. */ - virtual void keep_neighbours(Vertex_handle v, Simplex_handle& res, + virtual void keep_neighbours(Vertex_handle v, Simplex& res, bool keep_only_superior = false) const { - Simplex_handle nv; + Simplex nv; add_neighbours(v, nv, keep_only_superior); res.intersection(nv); } @@ -860,9 +886,9 @@ class Skeleton_blocker_complex { * neighbours of v eg \f$ res \leftarrow res \setminus N(v) \f$. * If 'keep_only_superior' is true then only vertices that are greater than v are added. */ - virtual void remove_neighbours(Vertex_handle v, Simplex_handle & res, + virtual void remove_neighbours(Vertex_handle v, Simplex & res, bool keep_only_superior = false) const { - Simplex_handle nv; + Simplex nv; add_neighbours(v, nv, keep_only_superior); res.difference(nv); } @@ -874,7 +900,7 @@ class Skeleton_blocker_complex { * Constructs the link of 'simplex' with points coordinates. */ Link_complex link(Vertex_handle v) const { - return Link_complex(*this, Simplex_handle(v)); + return Link_complex(*this, Simplex(v)); } /** @@ -887,7 +913,7 @@ class Skeleton_blocker_complex { /** * Constructs the link of 'simplex' with points coordinates. */ - Link_complex link(const Simplex_handle& simplex) const { + Link_complex link(const Simplex& simplex) const { return Link_complex(*this, simplex); } @@ -899,11 +925,11 @@ class Skeleton_blocker_complex { */ // xxx rename get_address et place un using dans sub_complex - boost::optional get_simplex_address( + boost::optional get_simplex_address( const Root_simplex_handle& s) const { - boost::optional res; + boost::optional res; - Simplex_handle s_address; + Simplex s_address; // Root_simplex_const_iterator i; for (auto i = s.begin(); i != s.end(); ++i) { boost::optional address = get_address(*i); @@ -920,7 +946,7 @@ class Skeleton_blocker_complex { * @brief returns a simplex with vertices which are the id of vertices of the * argument. */ - Root_simplex_handle get_id(const Simplex_handle& local_simplex) const { + Root_simplex_handle get_id(const Simplex& local_simplex) const { Root_simplex_handle global_simplex; for (auto x = local_simplex.begin(); x != local_simplex.end(); ++x) { global_simplex.add_vertex(get_id(*x)); @@ -932,7 +958,7 @@ class Skeleton_blocker_complex { * @brief returns true iff the simplex s belongs to the simplicial * complex. */ - virtual bool contains(const Simplex_handle & s) const { + virtual bool contains(const Simplex & s) const { if (s.dimension() == -1) { return false; } else if (s.dimension() == 0) { @@ -1061,7 +1087,7 @@ class Skeleton_blocker_complex { * Furthermore, all simplices tau of the form sigma \setminus simplex_to_be_removed must be added * whenever the dimension of tau is at least 2. */ - void update_blockers_after_remove_star_of_vertex_or_edge(const Simplex_handle& simplex_to_be_removed); + void update_blockers_after_remove_star_of_vertex_or_edge(const Simplex& simplex_to_be_removed); public: /** @@ -1078,31 +1104,36 @@ class Skeleton_blocker_complex { /** * Remove the star of the simplex 'sigma' which needs to belong to the complex */ - void remove_star(const Simplex_handle& sigma); + void remove_star(const Simplex& sigma); /** - * @brief add a maximal simplex plus all its cofaces. - * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge). + * @brief add a simplex. + * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge_without_blockers). + * and all vertices lower than the higher vertex of sigma must already be in the complex. + * if some edges of sigma are not in the complex, then insert_edges_of_sigma flag must be + * set to true. */ - void add_simplex(const Simplex_handle& sigma); + void add_simplex(const Simplex& sigma, bool insert_edges_of_sigma = false); private: + void add_blockers_after_simplex_insertion(Simplex s); + /** * remove all blockers that contains sigma */ - void remove_blocker_containing_simplex(const Simplex_handle& sigma); + void remove_blocker_containing_simplex(const Simplex& sigma); /** * remove all blockers that contains sigma */ - void remove_blocker_include_in_simplex(const Simplex_handle& sigma); + void remove_blocker_include_in_simplex(const Simplex& sigma); public: enum simplifiable_status { NOT_HOMOTOPY_EQ, MAYBE_HOMOTOPY_EQ, HOMOTOPY_EQ }; - simplifiable_status is_remove_star_homotopy_preserving(const Simplex_handle& simplex) { + simplifiable_status is_remove_star_homotopy_preserving(const Simplex& simplex) { // todo write a virtual method 'link' in Skeleton_blocker_complex which will be overloaded by the current one of // Skeleton_blocker_geometric_complex // then call it there to build the link and return the value of link.is_contractible() @@ -1174,7 +1205,7 @@ class Skeleton_blocker_complex { * that may be used to construct a new blocker after contracting ab. * It requires that the link condition is satisfied. */ - void tip_blockers(Vertex_handle a, Vertex_handle b, std::vector & buffer) const; + void tip_blockers(Vertex_handle a, Vertex_handle b, std::vector & buffer) const; private: /** @@ -1217,7 +1248,7 @@ class Skeleton_blocker_complex { private: void get_blockers_to_be_added_after_contraction(Vertex_handle a, Vertex_handle b, - std::set& blockers_to_add); + std::set& blockers_to_add); /** * delete all blockers that passes through a or b */ @@ -1358,12 +1389,28 @@ class Skeleton_blocker_complex { /** * @brief Returns a Complex_simplex_around_vertex_range over all the simplices around a vertex of the complex */ - Complex_simplex_around_vertex_range simplex_range(Vertex_handle v) const { + Complex_simplex_around_vertex_range star_simplex_range(Vertex_handle v) const { assert(contains_vertex(v)); return Complex_simplex_around_vertex_range( Complex_simplex_around_vertex_iterator(this, v), Complex_simplex_around_vertex_iterator(this, v, true)); } + typedef Simplex_coboundary_iterator Complex_simplex_coboundary_iterator; + + /** + * @brief Range over the simplices of the coboundary of a simplex. + * Methods .begin() and .end() return a Complex_simplex_coboundary_iterator. + */ + typedef boost::iterator_range < Complex_simplex_coboundary_iterator > Complex_coboundary_range; + + /** + * @brief Returns a Complex_simplex_coboundary_iterator over the simplices of the coboundary of a simplex. + */ + Complex_coboundary_range coboundary_range(const Simplex& s) const { + assert(contains(s)); + return Complex_coboundary_range(Complex_simplex_coboundary_iterator(this, s), + Complex_simplex_coboundary_iterator(this, s, true)); + } // typedef Simplex_iterator Complex_simplex_iterator; typedef Simplex_iterator Complex_simplex_iterator; @@ -1373,7 +1420,7 @@ class Skeleton_blocker_complex { /** * @brief Returns a Complex_simplex_range over all the simplices of the complex */ - Complex_simplex_range simplex_range() const { + Complex_simplex_range complex_simplex_range() const { Complex_simplex_iterator end(this, true); if (empty()) { return Complex_simplex_range(end, end); @@ -1393,7 +1440,7 @@ class Skeleton_blocker_complex { * @brief Iterator over the blockers adjacent to a vertex */ typedef Blocker_iterator_around_vertex_internal< - typename std::multimap::iterator, + typename std::multimap::iterator, Blocker_handle> Complex_blocker_around_vertex_iterator; @@ -1401,7 +1448,7 @@ class Skeleton_blocker_complex { * @brief Iterator over (constant) blockers adjacent to a vertex */ typedef Blocker_iterator_around_vertex_internal< - typename std::multimap::const_iterator, + typename std::multimap::const_iterator, const Blocker_handle> Const_complex_blocker_around_vertex_iterator; @@ -1433,7 +1480,7 @@ class Skeleton_blocker_complex { * @brief Iterator over the blockers. */ typedef Blocker_iterator_internal< - typename std::multimap::iterator, + typename std::multimap::iterator, Blocker_handle> Complex_blocker_iterator; @@ -1441,7 +1488,7 @@ class Skeleton_blocker_complex { * @brief Iterator over the (constant) blockers. */ typedef Blocker_iterator_internal< - typename std::multimap::const_iterator, + typename std::multimap::const_iterator, const Blocker_handle> Const_complex_blocker_iterator; @@ -1517,8 +1564,9 @@ class Skeleton_blocker_complex { template Complex make_complex_from_top_faces(SimplexHandleIterator simplex_begin, SimplexHandleIterator simplex_end, bool is_flag_complex = false) { - typedef typename Complex::Simplex_handle Simplex_handle; - std::vector simplices; + //todo use add_simplex instead! should be more efficient and more elegant :) + typedef typename Complex::Simplex Simplex; + std::vector simplices; for (auto top_face = simplex_begin; top_face != simplex_end; ++top_face) { auto subfaces_topface = subfaces(*top_face); simplices.insert(simplices.end(), subfaces_topface.begin(), subfaces_topface.end()); diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h index b8395251..5c898152 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_geometric_complex.h @@ -46,7 +46,7 @@ public Skeleton_blocker_complex { typedef typename SimplifiableSkeletonblocker::Vertex_handle Vertex_handle; typedef typename SimplifiableSkeletonblocker::Root_vertex_handle Root_vertex_handle; typedef typename SimplifiableSkeletonblocker::Edge_handle Edge_handle; - typedef typename SimplifiableSkeletonblocker::Simplex_handle Simplex_handle; + typedef typename SimplifiableSkeletonblocker::Simplex Simplex; typedef typename SimplifiableSkeletonblocker::Graph_vertex Graph_vertex; @@ -140,7 +140,7 @@ public Skeleton_blocker_complex { * Constructs the link of 'simplex' with points coordinates. */ Geometric_link link(Vertex_handle v) const { - Geometric_link link(*this, Simplex_handle(v)); + Geometric_link link(*this, Simplex(v)); // we now add the point info add_points_to_link(link); return link; @@ -149,7 +149,7 @@ public Skeleton_blocker_complex { /** * Constructs the link of 'simplex' with points coordinates. */ - Geometric_link link(const Simplex_handle& simplex) const { + Geometric_link link(const Simplex& simplex) const { Geometric_link link(*this, simplex); // we now add the point info add_points_to_link(link); @@ -172,13 +172,13 @@ public Skeleton_blocker_complex { * Constructs the abstract link of v (without points coordinates). */ Abstract_link abstract_link(Vertex_handle v) const { - return Abstract_link(*this, Simplex_handle(v)); + return Abstract_link(*this, Simplex(v)); } /** * Constructs the link of 'simplex' with points coordinates. */ - Abstract_link abstract_link(const Simplex_handle& simplex) const { + Abstract_link abstract_link(const Simplex& simplex) const { return Abstract_link(*this, simplex); } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h index 95d8fa97..85a6b0b5 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_link_complex.h @@ -52,12 +52,11 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< typedef typename ComplexType::Vertex_handle Vertex_handle; typedef typename ComplexType::Root_vertex_handle Root_vertex_handle; - typedef typename ComplexType::Simplex_handle Simplex_handle; + typedef typename ComplexType::Simplex Simplex; typedef typename ComplexType::Root_simplex_handle Root_simplex_handle; typedef typename ComplexType::Blocker_handle Blocker_handle; - typedef typename ComplexType::Simplex_handle::Simplex_vertex_const_iterator Simplex_handle_iterator; typedef typename ComplexType::Root_simplex_handle::Simplex_vertex_const_iterator Root_simplex_handle_iterator; explicit Skeleton_blocker_link_complex(bool only_superior_vertices = false) @@ -67,13 +66,15 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< /** * If the parameter only_superior_vertices is true, * only vertices greater than the one of alpha are added. + * Only vertices are computed if only_vertices is true. */ Skeleton_blocker_link_complex(const ComplexType & parent_complex, - const Simplex_handle& alpha_parent_adress, - bool only_superior_vertices = false) + const Simplex& alpha_parent_adress, + bool only_superior_vertices = false, + bool only_vertices = false) : only_superior_vertices_(only_superior_vertices) { if (!alpha_parent_adress.empty()) - build_link(parent_complex, alpha_parent_adress); + build_link(parent_complex, alpha_parent_adress, only_vertices); } /** @@ -84,7 +85,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< Vertex_handle a_parent_adress, bool only_superior_vertices = false) : only_superior_vertices_(only_superior_vertices) { - Simplex_handle alpha_simplex(a_parent_adress); + Simplex alpha_simplex(a_parent_adress); build_link(parent_complex, alpha_simplex); } @@ -96,7 +97,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< Edge_handle edge, bool only_superior_vertices = false) : only_superior_vertices_(only_superior_vertices) { - Simplex_handle alpha_simplex(parent_complex.first_vertex(edge), + Simplex alpha_simplex(parent_complex.first_vertex(edge), parent_complex.second_vertex(edge)); build_link(parent_complex, alpha_simplex); } @@ -108,7 +109,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< * are greater than vertices of alpha_parent_adress are added. */ void compute_link_vertices(const ComplexType & parent_complex, - const Simplex_handle& alpha_parent_adress, + const Simplex& alpha_parent_adress, bool only_superior_vertices, bool is_alpha_blocker = false) { if (alpha_parent_adress.dimension() == 0) { @@ -119,7 +120,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< only_superior_vertices_); } else { // we compute the intersection of neighbors of alpha and store it in link_vertices - Simplex_handle link_vertices_parent; + Simplex link_vertices_parent; parent_complex.add_neighbours(alpha_parent_adress, link_vertices_parent, only_superior_vertices); // For all vertex 'v' in this intersection, we go through all its adjacent blockers. @@ -162,13 +163,8 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< } void compute_link_edges(const ComplexType & parent_complex, - const Simplex_handle& alpha_parent_adress, + const Simplex& alpha_parent_adress, bool is_alpha_blocker = false) { - Simplex_handle_iterator y_link, x_parent, y_parent; - // ---------------------------- - // Compute edges in the link - // ------------------------- - if (this->num_vertices() <= 1) return; @@ -194,7 +190,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< } } if (new_edge) - this->add_edge(*x_link, *y_link); + this->add_edge_without_blockers(*x_link, *y_link); } } } @@ -217,7 +213,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< * the blocker is anticollapsed. */ void compute_link_blockers(const ComplexType & parent_complex, - const Simplex_handle& alpha_parent, + const Simplex& alpha_parent, bool is_alpha_blocker = false) { for (auto x_link : this->vertex_range()) { Vertex_handle x_parent = *this->give_equivalent_vertex(parent_complex, @@ -225,7 +221,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< for (auto blocker_parent : parent_complex.const_blocker_range(x_parent)) { if (!is_alpha_blocker || *blocker_parent != alpha_parent) { - Simplex_handle sigma_parent(*blocker_parent); + Simplex sigma_parent(*blocker_parent); sigma_parent.difference(alpha_parent); @@ -239,7 +235,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< for (auto a : alpha_parent) { for (auto eta_parent : parent_complex.const_blocker_range(a)) { if (!is_alpha_blocker || *eta_parent != alpha_parent) { - Simplex_handle eta_minus_alpha(*eta_parent); + Simplex eta_minus_alpha(*eta_parent); eta_minus_alpha.difference(alpha_parent); if (eta_minus_alpha != sigma_parent && sigma_parent.contains_difference(*eta_parent, @@ -253,7 +249,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< break; } if (is_new_blocker) - this->add_blocker(new Simplex_handle(*sigma_link)); + this->add_blocker(new Simplex(*sigma_link)); } } } @@ -268,14 +264,15 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< * with vertices that are greater than vertices of alpha_parent_adress. */ void build_link(const ComplexType & parent_complex, - const Simplex_handle& alpha_parent_adress, - bool is_alpha_blocker = false) { + const Simplex& alpha_parent_adress, + bool is_alpha_blocker = false, + bool only_vertices = false) { assert(is_alpha_blocker || parent_complex.contains(alpha_parent_adress)); - compute_link_vertices(parent_complex, alpha_parent_adress, - only_superior_vertices_); - compute_link_edges(parent_complex, alpha_parent_adress, is_alpha_blocker); - compute_link_blockers(parent_complex, alpha_parent_adress, - is_alpha_blocker); + compute_link_vertices(parent_complex, alpha_parent_adress, only_superior_vertices_); + if(!only_vertices) { + compute_link_edges(parent_complex, alpha_parent_adress, is_alpha_blocker); + compute_link_blockers(parent_complex, alpha_parent_adress, is_alpha_blocker); + } } /** @@ -284,7 +281,7 @@ class Skeleton_blocker_link_complex : public Skeleton_blocker_sub_complex< * removed from the blockers of the complex. */ friend void build_link_of_blocker(const ComplexType & parent_complex, - Simplex_handle& blocker, + Simplex& blocker, Skeleton_blocker_link_complex & result) { assert(blocker.dimension() >= 2); assert(parent_complex.contains_blocker(blocker)); diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h index 17a237a7..49a1ea8b 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h @@ -133,7 +133,7 @@ void Skeleton_blocker_complex::remove_all_popable_blockers(Ve template void Skeleton_blocker_complex::remove_star(Vertex_handle v) { // we remove the blockers that are not consistent anymore - update_blockers_after_remove_star_of_vertex_or_edge(Simplex_handle(v)); + update_blockers_after_remove_star_of_vertex_or_edge(Simplex(v)); while (this->degree(v) > 0) { Vertex_handle w(* (adjacent_vertices(v.vertex, this->skeleton).first)); this->remove_edge(v, w); @@ -148,7 +148,7 @@ void Skeleton_blocker_complex::remove_star(Vertex_handle v) { */ template void Skeleton_blocker_complex::update_blockers_after_remove_star_of_vertex_or_edge( - const Simplex_handle& simplex_to_be_removed) { + const Simplex& simplex_to_be_removed) { std::list blockers_to_update; if (simplex_to_be_removed.empty()) return; @@ -159,7 +159,7 @@ void Skeleton_blocker_complex::update_blockers_after_remove_s } for (auto blocker_to_update : blockers_to_update) { - Simplex_handle sub_blocker_to_be_added; + Simplex sub_blocker_to_be_added; bool sub_blocker_need_to_be_added = (blocker_to_update->dimension() - simplex_to_be_removed.dimension()) >= 2; if (sub_blocker_need_to_be_added) { @@ -178,7 +178,7 @@ void Skeleton_blocker_complex::update_blockers_after_remove_s */ template void Skeleton_blocker_complex::remove_star(Vertex_handle a, Vertex_handle b) { - update_blockers_after_remove_star_of_vertex_or_edge(Simplex_handle(a, b)); + update_blockers_after_remove_star_of_vertex_or_edge(Simplex(a, b)); // we remove the edge this->remove_edge(a, b); } @@ -195,7 +195,7 @@ void Skeleton_blocker_complex::remove_star(Edge_handle e) { * Remove the star of the simplex 'sigma' which needs to belong to the complex */ template -void Skeleton_blocker_complex::remove_star(const Simplex_handle& sigma) { +void Skeleton_blocker_complex::remove_star(const Simplex& sigma) { assert(this->contains(sigma)); if (sigma.dimension() == 0) { remove_star(sigma.first_vertex()); @@ -207,34 +207,36 @@ void Skeleton_blocker_complex::remove_star(const Simplex_hand } } -/** - * @brief add a maximal simplex plus all its cofaces. All vertices lower than the higher vertex of - * sigma must already be present. - * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge). - */ template -void Skeleton_blocker_complex::add_simplex(const Simplex_handle& sigma) { +void Skeleton_blocker_complex::add_simplex(const Simplex& sigma, bool insert_edges_of_sigma) { + // to add a simplex s, all blockers included in s are first removed + // and then all simplex in the coboundary of s are added as blockers assert(!this->contains(sigma)); assert(sigma.dimension() > 1); + assert(contains_vertices(sigma)); - int num_vertex_to_add = 0; - for (auto v : sigma) - if (!contains_vertex(v)) ++num_vertex_to_add; - while (num_vertex_to_add--) add_vertex(); - - for (auto u_it = sigma.begin(); u_it != sigma.end(); ++u_it) - for (auto v_it = u_it; ++v_it != sigma.end(); /**/) { - // std::cout << "add edge" << *u_it << " " << *v_it << std::endl; - add_edge(*u_it, *v_it); - } + if(insert_edges_of_sigma) + add_edge(sigma); + else + assert(contains_edges(sigma)); remove_blocker_include_in_simplex(sigma); + add_blockers_after_simplex_insertion(sigma); +} + +template +void Skeleton_blocker_complex::add_blockers_after_simplex_insertion(Simplex sigma){ + if(sigma.dimension() < 1) return; + + for(auto s : coboundary_range(sigma)) { + this->add_blocker(s); + } } /** * remove all blockers that contains sigma */ template -void Skeleton_blocker_complex::remove_blocker_containing_simplex(const Simplex_handle& sigma) { +void Skeleton_blocker_complex::remove_blocker_containing_simplex(const Simplex& sigma) { std::vector blockers_to_remove; for (auto blocker : this->blocker_range(sigma.first_vertex())) { if (blocker->contains(sigma)) @@ -248,14 +250,26 @@ void Skeleton_blocker_complex::remove_blocker_containing_simp * remove all blockers that contains sigma */ template -void Skeleton_blocker_complex::remove_blocker_include_in_simplex(const Simplex_handle& sigma) { - std::vector blockers_to_remove; - for (auto blocker : this->blocker_range(sigma.first_vertex())) { - if (sigma.contains(*blocker)) - blockers_to_remove.push_back(blocker); +void Skeleton_blocker_complex::remove_blocker_include_in_simplex(const Simplex& sigma) { + //todo write efficiently by using only superior blockers + //eg for all s, check blockers whose vertices are all greater than s + std::set blockers_to_remove; + for(auto s : sigma) { + for (auto blocker : this->blocker_range(s)) { + if (sigma.contains(*blocker)) + blockers_to_remove.insert(blocker); + } } - for (auto blocker_to_update : blockers_to_remove) + for (auto blocker_to_update : blockers_to_remove) { + auto s = *blocker_to_update; this->delete_blocker(blocker_to_update); + //now if there is a vertex v in the link of s + //and v is not included in sigma then v.s is a blocker + //(all faces of v.s are there since v belongs to the link of s) + for(const auto& b : coboundary_range(s)) + if(!sigma.contains(b)) + this->add_blocker(b); + } } /** @@ -265,21 +279,21 @@ void Skeleton_blocker_complex::remove_blocker_include_in_simp */ template void Skeleton_blocker_complex::tip_blockers(Vertex_handle a, Vertex_handle b, - std::vector & buffer) const { + std::vector & buffer) const { for (auto const & blocker : this->const_blocker_range(a)) { - Simplex_handle beta = (*blocker); + Simplex beta = (*blocker); beta.remove_vertex(a); buffer.push_back(beta); } - Simplex_handle n; + Simplex n; this->add_neighbours(b, n); this->remove_neighbours(a, n); n.remove_vertex(a); for (Vertex_handle y : n) { - Simplex_handle beta; + Simplex beta; beta.add_vertex(y); buffer.push_back(beta); } @@ -296,7 +310,7 @@ void Skeleton_blocker_complex::tip_blockers(Vertex_handle a, template void Skeleton_blocker_complex::swap_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) { - this->add_edge(a, x); + this->add_edge_without_blockers(a, x); if (this->visitor) this->visitor->on_swaped_edge(a, b, x); this->remove_edge(b, x); } @@ -341,13 +355,13 @@ Skeleton_blocker_complex::contract_edge(Vertex_handle a, Vert assert(this->contains_vertex(b)); if (this->contains_edge(a, b)) - this->add_edge(a, b); + this->add_edge_without_blockers(a, b); // if some blockers passes through 'ab', we need to remove them. if (!link_condition(a, b)) delete_blockers_around_edge(a, b); - std::set blockers_to_add; + std::set blockers_to_add; get_blockers_to_be_added_after_contraction(a, b, blockers_to_add); @@ -369,7 +383,7 @@ Skeleton_blocker_complex::contract_edge(Vertex_handle a, Vert template void Skeleton_blocker_complex::get_blockers_to_be_added_after_contraction(Vertex_handle a, Vertex_handle b, - std::set& blockers_to_add) { + std::set& blockers_to_add) { blockers_to_add.clear(); typedef Skeleton_blocker_link_complex > LinkComplexType; @@ -377,19 +391,19 @@ Skeleton_blocker_complex::get_blockers_to_be_added_after_cont LinkComplexType link_a(*this, a); LinkComplexType link_b(*this, b); - std::vector vector_alpha, vector_beta; + std::vector vector_alpha, vector_beta; tip_blockers(a, b, vector_alpha); tip_blockers(b, a, vector_beta); for (auto alpha = vector_alpha.begin(); alpha != vector_alpha.end(); ++alpha) { for (auto beta = vector_beta.begin(); beta != vector_beta.end(); ++beta) { - Simplex_handle sigma = *alpha; + Simplex sigma = *alpha; sigma.union_vertices(*beta); Root_simplex_handle sigma_id = this->get_id(sigma); if (this->contains(sigma) && proper_faces_in_union> (sigma_id, link_a, link_b)) { - // Blocker_handle blocker = new Simplex_handle(sigma); + // Blocker_handle blocker = new Simplex(sigma); sigma.add_vertex(a); blockers_to_add.insert(sigma); } diff --git a/src/Skeleton_blocker/test/TestGeometricComplex.cpp b/src/Skeleton_blocker/test/TestGeometricComplex.cpp index bd7af89b..084e2b6b 100644 --- a/src/Skeleton_blocker/test/TestGeometricComplex.cpp +++ b/src/Skeleton_blocker/test/TestGeometricComplex.cpp @@ -1,24 +1,24 @@ - /* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): David Salinas - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): David Salinas + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include #include @@ -33,8 +33,8 @@ using namespace std; using namespace Gudhi; using namespace skbl; -struct Geometry_trait{ - typedef std::vector Point; +struct Geometry_trait { + typedef std::vector Point; }; typedef Geometry_trait::Point Point; @@ -42,79 +42,77 @@ typedef Skeleton_blocker_simple_geometric_traits Complex_geometr typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex; typedef Complex::Vertex_handle Vertex_handle; +bool test_constructor1() { + Complex complex; + Skeleton_blocker_off_reader off_reader("test2.off", complex); + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file" << std::endl; + return false; + } -bool test_constructor1(){ - Complex complex; - Skeleton_blocker_off_reader off_reader("test2.off",complex); - if(!off_reader.is_valid()){ - std::cerr << "Unable to read file"< off_writer("tmp.off", complex); + Complex same; + Skeleton_blocker_off_reader off_reader2("tmp.off", same); - Skeleton_blocker_off_writer off_writer("tmp.off",complex); - Complex same; - Skeleton_blocker_off_reader off_reader2("tmp.off",same); + std::cout << "\ncomplex:" << complex.to_string() << endl; + std::cout << "\nsame:" << same.to_string() << endl; - std::cout<<"\ncomplex:"< off_reader("test2.off",complex); - if(!off_reader.is_valid()){ - std::cerr << "Unable to read file"< off_reader("test2.off", complex); + if (!off_reader.is_valid()) { + std::cerr << "Unable to read file" << std::endl; + return false; + } + std::cout << "complex has " << + complex.num_vertices() << " vertices, " << + complex.num_blockers() << " blockers, " << + complex.num_edges() << " edges and" << + complex.num_triangles() << " triangles."; - if(complex.num_vertices()!=7 || complex.num_edges()!=12 || complex.num_triangles() !=6) - return false; + if (complex.num_vertices() != 7 || complex.num_edges() != 12 || complex.num_triangles() != 6) + return false; - auto link_0 = complex.abstract_link(Vertex_handle(0)); + auto link_0 = complex.abstract_link(Vertex_handle(0)); - std::cout<<"\n link(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): David Salinas + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include @@ -41,316 +41,382 @@ template class Skeleton_blocker_sub_complex; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; typedef Complex::Root_vertex_handle Root_vertex_handle; -typedef Skeleton_blocker_simplex Simplex_handle; +typedef Skeleton_blocker_simplex Simplex; // true iff v \in complex -bool assert_vertex(Complex &complex,Vertex_handle v){ - Simplex_handle simplex(v); - bool test = complex.contains(simplex); - assert(test); - return test; + +bool assert_vertex(Complex &complex, Vertex_handle v) { + Simplex simplex(v); + bool test = complex.contains(simplex); + assert(test); + return test; } // true iff the blocker (a,b,c) is in complex -bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){ - return complex.contains_blocker(Simplex_handle(*complex.get_address(a),*complex.get_address(b),*complex.get_address(c))); - //return complex.contains_blocker((a),(b),(c)); +bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) { + + return complex.contains_blocker(Simplex(*complex.get_address(a), *complex.get_address(b), *complex.get_address(c))); + //return complex.contains_blocker((a),(b),(c)); } -void build_complete(int n,Complex& complex){ - complex.clear(); - for(int i=0;i(b), static_cast(z)); - complex.add_blocker(Simplex_handle(static_cast(a), static_cast(x), - static_cast(y))); - complex.add_blocker(Simplex_handle(static_cast(b), static_cast(x), - static_cast(y))); - - // Print result - cerr << "complex before complex"<< complex.to_string()<(a),static_cast(b)); - // Print result - cerr << "ContractEdge(0,1)\n"; - PRINT(complex.to_string()); - - // verification - for (int i=0;i<5;i++) - if (i!=1) assert_vertex(complex, static_cast(i)); - bool test1 = !complex.contains_edge(static_cast(a),static_cast(b)); - bool test2 = assert_blocker(complex,Root_vertex_handle(a),Root_vertex_handle(x),Root_vertex_handle(y)); - bool test3 = complex.num_edges()==6; - bool test4 = complex.num_blockers()==1; - Simplex_handle sigma; - sigma.add_vertex(static_cast(a)); - sigma.add_vertex(static_cast(x)); - sigma.add_vertex(static_cast(y)); - sigma.add_vertex(static_cast(z)); - bool test5 = !(complex.contains(sigma)); - return test1&&test2&&test3&&test4&&test5; +bool test_contraction1() { + + enum { + a, b, x, y, z, n + }; + Complex complex(n); + build_complete(n, complex); + complex.remove_edge(static_cast (b), static_cast (z)); + complex.add_blocker(Simplex(static_cast (a), static_cast (x), + static_cast (y))); + complex.add_blocker(Simplex(static_cast (b), static_cast (x), + static_cast (y))); + + // Print result + cerr << "complex before complex" << complex.to_string() << endl; + + cerr << endl << endl; + complex.contract_edge(static_cast (a), static_cast (b)); + // Print result + cerr << "ContractEdge(0,1)\n"; + PRINT(complex.to_string()); + + // verification + for (int i = 0; i < 5; i++) + if (i != 1) assert_vertex(complex, static_cast (i)); + bool test1 = !complex.contains_edge(static_cast (a), static_cast (b)); + bool test2 = assert_blocker(complex, Root_vertex_handle(a), Root_vertex_handle(x), Root_vertex_handle(y)); + bool test3 = complex.num_edges() == 6; + bool test4 = complex.num_blockers() == 1; + Simplex sigma; + sigma.add_vertex(static_cast (a)); + sigma.add_vertex(static_cast (x)); + sigma.add_vertex(static_cast (y)); + sigma.add_vertex(static_cast (z)); + bool test5 = !(complex.contains(sigma)); + return test1 && test2 && test3 && test4&&test5; } +bool test_contraction2() { -bool test_contraction2(){ - enum { a, b, x, y, z, n }; - Complex complex(n); - build_complete(n,complex); - complex.remove_edge(static_cast(b),static_cast(x)); - Simplex_handle blocker; - blocker.add_vertex(static_cast(a)); - blocker.add_vertex(static_cast(y)); - blocker.add_vertex(static_cast(z)); + enum { + a, b, x, y, z, n + }; + Complex complex(n); + build_complete(n, complex); + complex.remove_edge(static_cast (b), static_cast (x)); + Simplex blocker; + blocker.add_vertex(static_cast (a)); + blocker.add_vertex(static_cast (y)); + blocker.add_vertex(static_cast (z)); - complex.add_blocker(blocker); + complex.add_blocker(blocker); - // Print result - cerr << "complex complex"<< complex.to_string(); - cerr <(a),static_cast(b)); + // Print result + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + complex.contract_edge(static_cast (a), static_cast (b)); - cerr << "complex.ContractEdge(a,b)"<< complex.to_string(); + cerr << "complex.ContractEdge(a,b)" << complex.to_string(); - cerr <(a), static_cast(x), - static_cast(y),static_cast(z))); - test = test && complex.num_blockers()==1; - return test; + // there should be one blocker (a,c,d,e) in the complex + bool test; + test = complex.contains_blocker(Simplex(static_cast (a), static_cast (x), + static_cast (y), static_cast (z))); + test = test && complex.num_blockers() == 1; + return test; } -bool test_link_condition1(){ +bool test_link_condition1() { - Complex complex(0); - // Build the complexes - build_complete(4,complex); - complex.add_blocker(Simplex_handle(static_cast(0), static_cast(1), static_cast(2))); + Complex complex(0); + // Build the complexes + build_complete(4, complex); + complex.add_blocker(Simplex(static_cast (0), static_cast (1), static_cast (2))); - // Print result - cerr << "complex complex"<< complex.to_string(); - cerr <(2), static_cast(4)); - complex.add_edge(static_cast(3), static_cast(4)); - // Print result - cerr << "initial complex :\n"<< complex.to_string(); - cerr <(1), static_cast(2), static_cast(3)); - complex.remove_star(simplex_123); - cerr << "complex.remove_star(1,2,3):\n"<< complex.to_string(); - cerr < Ocomplex \n"; - return blocker123_here; +bool test_collapse0() { + Complex complex(5); + build_complete(4, complex); + complex.add_vertex(); + complex.add_edge_without_blockers(static_cast (2), static_cast (4)); + complex.add_edge_without_blockers(static_cast (3), static_cast (4)); + // Print result + cerr << "initial complex :\n" << complex.to_string(); + cerr << endl << endl; + + Simplex simplex_123(static_cast (1), static_cast (2), static_cast (3)); + complex.remove_star(simplex_123); + cerr << "complex.remove_star(1,2,3):\n" << complex.to_string(); + cerr << endl << endl; + + // verification + bool blocker123_here = complex.contains_blocker(simplex_123); + cerr << "----> Ocomplex \n"; + return blocker123_here; } - -bool test_collapse1(){ - Complex complex(5); - build_complete(4,complex); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3))); - // Print result - cerr << "initial complex :\n"<< complex.to_string(); - cerr < Ocomplex \n"; - return res; +bool test_collapse1() { + Complex complex(5); + build_complete(4, complex); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); + // Print result + cerr << "initial complex :\n" << complex.to_string(); + cerr << endl << endl; + + Simplex simplex_123(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); + complex.remove_star(simplex_123); + cerr << "complex.remove_star(1,2,3):\n" << complex.to_string(); + cerr << endl << endl; + + // verification + bool res = complex.contains_blocker(simplex_123); + res = res && complex.num_blockers() == 1; + cerr << "----> Ocomplex \n"; + return res; } -bool test_collapse2(){ - Complex complex(5); - build_complete(4,complex); - complex.add_vertex(); - complex.add_edge(Vertex_handle(1),Vertex_handle(4)); - complex.add_edge(Vertex_handle(2),Vertex_handle(4)); - complex.add_edge(Vertex_handle(3),Vertex_handle(4)); - complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4))); - // Print result - cerr << "initial complex :\n"<< complex.to_string(); - cerr <(2)); - cerr << "complex after remove star of 2:\n"<< complex.to_string(); - - bool blocker134_here = complex.contains_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(3),Vertex_handle(4))); - bool blocker1234_here = complex.contains_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4))); - return blocker134_here && !blocker1234_here; +bool test_collapse3() { + Complex complex(5); + build_complete(4, complex); + complex.add_vertex(); + complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4)); + complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4))); + // Print result + cerr << "initial complex:\n" << complex.to_string(); + cerr << endl << endl; + + complex.remove_star(static_cast (2)); + cerr << "complex after remove star of 2:\n" << complex.to_string(); + + bool blocker134_here = complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(3), Vertex_handle(4))); + bool blocker1234_here = complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3), Vertex_handle(4))); + return blocker134_here && !blocker1234_here; } -bool test_add_simplex(){ - Complex complex(5); - build_complete(4,complex); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); - // Print result - cerr << "initial complex:\n"<< complex.to_string(); - cerr < simplices(complex.simplex_range().begin(),complex.simplex_range().end()); - sort(simplices.begin(),simplices.end(),[&](const Simplex_handle& s1,const Simplex_handle& s2){ - return s1.dimension()1) - copy.add_simplex(simplex); - } + std::vector simplices(complex.complex_simplex_range().begin(), complex.complex_simplex_range().end()); + sort(simplices.begin(), simplices.end(), [&](const Simplex& s1, const Simplex & s2) { + return s1.dimension() < s2.dimension(); + }); + for (const auto & simplex : simplices) { + if (!copy.contains(simplex) && simplex.dimension() == 1) + copy.add_edge_without_blockers(simplex.first_vertex(), simplex.last_vertex()); + if (!copy.contains(simplex) && simplex.dimension() > 1) + copy.add_simplex(simplex); + } - cerr << "complex after add_simplex:\n"<< copy.to_string(); + cerr << "complex after add_simplex:\n" << copy.to_string(); - return complex.num_blockers()==copy.num_blockers() && - complex.num_edges()==copy.num_edges() && - complex.num_vertices()==copy.num_vertices(); + return complex.num_blockers() == copy.num_blockers() && + complex.num_edges() == copy.num_edges() && + complex.num_vertices() == copy.num_vertices(); } +bool test_add_simplex3() { + Complex complex(5); + build_complete(5, complex); + complex.remove_edge(Vertex_handle(3), Vertex_handle(4)); + Simplex sigma(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)); + complex.add_blocker(sigma); + // Print result + cerr << "initial complex:\n" << complex.to_string(); + cerr << endl << endl; + complex.add_simplex(sigma); + //should create two blockers 0123 and 0124 + cerr << "complex after adding simplex 012:\n" << complex.to_string(); + return complex.num_blockers() == 2 + && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))) + && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(4))); +} - -bool test_remove_popable_blockers(){ - Complex complex; - build_complete(4,complex); - complex.add_vertex(); - complex.add_edge(Vertex_handle(3),Vertex_handle(4)); - complex.add_edge(Vertex_handle(2),Vertex_handle(4)); - Simplex_handle sigma1=Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)); - Simplex_handle sigma2=Simplex_handle(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)); - - complex.add_blocker(sigma1); - complex.add_blocker(sigma2); - cerr << "complex complex"<< complex.to_string(); - cerr < 0) + return false; + if (i >= 2 && complex.num_blockers() != 1) { + Simplex b; + for (int k = 0; k < i; k++) + b.add_vertex(Vertex_handle(i)); + if (!complex.contains_blocker(b)) + return false; + } + TESTVALUE(complex.blockers_to_string()); + } + Simplex s; + for (int k = 0; k < n; k++) + s.add_vertex(Vertex_handle(k)); + return complex.num_blockers() == 1 && complex.contains_blocker(s); } +bool test_add_edge() { + Complex complex(4); + for (unsigned i = 0u; i < 4; i++) + complex.add_edge(Vertex_handle(i), Vertex_handle((i + 1) % 4)); + + // Print result + cerr << "initial complex:\n" << complex.to_string(); + cerr << endl << endl; + complex.add_edge(Vertex_handle(1), Vertex_handle(3)); + //should create two blockers 013 and 012 + cerr << "complex after adding edge 13:\n" << complex.to_string(); + return complex.num_blockers() == 2 + && complex.contains_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(3))) + && complex.contains_blocker(Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); +} +bool test_remove_popable_blockers() { + Complex complex; + build_complete(4, complex); + complex.add_vertex(); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4)); + Simplex sigma1 = Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); + Simplex sigma2 = Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)); + + complex.add_blocker(sigma1); + complex.add_blocker(sigma2); + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + cerr << "complex.RemovePopableBlockers();" << endl; + complex.remove_popable_blockers(); + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + + bool test1 = (complex.num_blockers() == 1); + + + // test 2 + complex.clear(); + build_complete(4, complex); + complex.add_vertex(); + complex.add_vertex(); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(5)); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(5)); + complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(5)); + sigma1 = Simplex(Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); + sigma2 = Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4)); + + complex.add_blocker(sigma1); + complex.add_blocker(sigma2); + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + cerr << "complex.RemovePopableBlockers();" << endl; + complex.remove_popable_blockers(); + cerr << "complex complex" << complex.to_string(); + + cerr << endl << endl; + bool test2 = (complex.num_blockers() == 0); + return test1&&test2; +} -int main (int argc, char *argv[]) -{ - Tests tests_simplifiable_complex; - tests_simplifiable_complex.add("Test contraction 1",test_contraction1); - tests_simplifiable_complex.add("Test contraction 2",test_contraction2); - tests_simplifiable_complex.add("Test Link condition 1",test_link_condition1); - tests_simplifiable_complex.add("Test remove popable blockers",test_remove_popable_blockers); +int main(int argc, char *argv[]) { + Tests tests_simplifiable_complex; + tests_simplifiable_complex.add("Test contraction 1", test_contraction1); + tests_simplifiable_complex.add("Test contraction 2", test_contraction2); + tests_simplifiable_complex.add("Test Link condition 1", test_link_condition1); + tests_simplifiable_complex.add("Test remove popable blockers", test_remove_popable_blockers); - tests_simplifiable_complex.add("Test collapse 0",test_collapse0); - tests_simplifiable_complex.add("Test collapse 1",test_collapse1); - tests_simplifiable_complex.add("Test collapse 2",test_collapse2); - tests_simplifiable_complex.add("Test collapse 3",test_collapse3); + tests_simplifiable_complex.add("Test collapse 0", test_collapse0); + tests_simplifiable_complex.add("Test collapse 1", test_collapse1); + tests_simplifiable_complex.add("Test collapse 2", test_collapse2); + tests_simplifiable_complex.add("Test collapse 3", test_collapse3); - tests_simplifiable_complex.add("Test add simplex",test_add_simplex); - tests_simplifiable_complex.add("Test add simplex2",test_add_simplex2); + tests_simplifiable_complex.add("Test add edge",test_add_edge); + tests_simplifiable_complex.add("Test add simplex", test_add_simplex); + tests_simplifiable_complex.add("Test add simplex2", test_add_simplex2); + tests_simplifiable_complex.add("Test add simplex3",test_add_simplex3); + tests_simplifiable_complex.add("Test add simplex4",test_add_simplex4); - tests_simplifiable_complex.run(); + tests_simplifiable_complex.run(); - if(tests_simplifiable_complex.run()) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; + if (tests_simplifiable_complex.run()) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; } diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp index 319e3c43..418638e8 100644 --- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp +++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp @@ -42,911 +42,893 @@ using namespace skbl; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; typedef Complex::Root_vertex_handle Root_vertex_handle; -typedef Complex::Simplex_handle Simplex_handle; +typedef Complex::Simplex Simplex; typedef Complex::Root_simplex_handle Root_simplex_handle; -typedef Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator; +typedef Simplex::Simplex_vertex_const_iterator Simplex_vertex_const_iterator; typedef Complex::Edge_handle Edge_handle; // true if v in complex -bool assert_vertex(Complex &complex,Vertex_handle v){ - //assert(complex.contains(v)); - return complex.contains(static_cast(v)); -} - -bool assert_simplex(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){ - return true; - // AddressSimplex simplex((a),(b),(c)); - // return complex.contains(&simplex); -} -// true iff the blocker (a,b,c) is in complex -bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c){ - return true; - //return complex.contains_blocker((a),(b),(c)); +bool assert_vertex(Complex &complex, Vertex_handle v) { + //assert(complex.contains(v)); + return complex.contains(static_cast (v)); } -// true iff the blocker (a,b,c,d) is in complex -bool assert_blocker(Complex &complex,Root_vertex_handle a,Root_vertex_handle b,Root_vertex_handle c,Root_vertex_handle d){ - return true; - //Simplex blocker (a,b,c,d); - //return complex.contains_blocker(&blocker); -} - - - -void build_complete(int n,Complex& complex){ - complex.clear(); - for(int i=0;i=0;i--) - // for(int j=i-1;j>=0;j--) - // complex.add_edge(Vertex_handle(i),Vertex_handle(j)); - - for(int i=0;i expected_num_simplices; - - expected_num_simplices[Vertex_handle(0)] = 4; - expected_num_simplices[Vertex_handle(1)] = 6; - expected_num_simplices[Vertex_handle(2)] = 11; - expected_num_simplices[Vertex_handle(3)] = 9; - expected_num_simplices[Vertex_handle(4)] = 7; - expected_num_simplices[Vertex_handle(5)] = 7; - - for(auto pair : expected_num_simplices){ - unsigned num_simplices_around = 0; - for(const auto& simplex : complex.simplex_range(pair.first)){ - simplex.dimension(); - DBGVALUE(simplex); - ++num_simplices_around; - } - - correct_number_simplices = correct_number_simplices && (num_simplices_around == pair.second); - - DBGMSG("current vertex:",pair.first); - DBGMSG("expected_num_simplices:",pair.second); - DBGMSG("found:",num_simplices_around); - } - return correct_number_simplices; +bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) { + return true; + //return complex.contains_blocker((a),(b),(c)); } +// true iff the blocker (a,b,c,d) is in complex - -bool test_iterator_simplices2(){ - Complex complex(2); - complex.add_edge(Vertex_handle(0),Vertex_handle(1)); - - for(const auto& s:complex.triangle_range()){ - s.dimension(); - return false; // there are no triangles - } - - unsigned num_simplices = 0 ; - - - DBGVALUE(complex.to_string()); - - for(const auto& simplex : complex.simplex_range(Vertex_handle(0))){ - simplex.dimension(); - DBGVALUE(simplex); - } - - - for(const auto& simplex : complex.simplex_range()){ - DBGVALUE(simplex); - simplex.dimension(); - ++num_simplices; - } - bool correct_number_simplices = (num_simplices == 3); - return correct_number_simplices; +bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c, Root_vertex_handle d) { + return true; + //Simplex blocker (a,b,c,d); + //return complex.contains_blocker(&blocker); +} + +void build_complete(int n, Complex& complex) { + complex.clear(); + for (int i = 0; i < n; i++) + complex.add_vertex(); + + // for(int i=n-1;i>=0;i--) + // for(int j=i-1;j>=0;j--) + // complex.add_edge_without_blockers(Vertex_handle(i),Vertex_handle(j)); + + for (int i = 0; i < n; i++) + for (int j = 0; j < i; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); +} + +bool test_simplex() { + // PRINT("test simplex"); + Simplex simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); + for (auto i = simplex.begin(); i != simplex.end(); ++i) { + PRINT(*i); + auto j = i; + for (++j; + j != simplex.end(); + ++j) { + PRINT(*j); + } + } + return simplex.dimension() == 3; +} + +bool test_iterator_vertices1() { + int n = 10; + Complex complex(10); + cerr << "complex.num_vertices():" << complex.num_vertices() << endl; + int num_vertex_seen = 0; + for (auto vi : complex.vertex_range()) { + cerr << "vertex:" << vi << endl; + ++num_vertex_seen; + } + return num_vertex_seen == n; +} + +bool test_iterator_vertices2() { + int n = 10; + Complex complex(10); + build_complete(10, complex); + cerr << "complex.num_vertices():" << complex.num_vertices() << endl; + cerr << "complex.num_edges():" << complex.num_edges() << endl; + int num_vertex_seen = 0; + for (auto vi : complex.vertex_range(Vertex_handle(2))) { + cerr << "vertex:" << vi << endl; + ++num_vertex_seen; + } + std::cerr << "num_vertex_seen:" << num_vertex_seen << std::endl; + return num_vertex_seen == (n - 1); +} + +bool test_iterator_edge() { + const int n = 10; + Complex complex(n); + for (int i = 0; i < n; i++) + for (int j = 0; j < i; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); + complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); + cerr << "complex.num_edges():" << complex.num_edges() << endl; + int num_edges_seen = 0; + for (auto edge : complex.edge_range()) { + cerr << "edge :" << complex[edge] << endl; + ++num_edges_seen; + } + + return num_edges_seen == n * (n - 1) / 2 - 2; +} + +bool test_iterator_edge2() { + const int n = 10; + Complex complex(n); + for (int i = 0; i < n; i++) + for (int j = 0; j < i; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); + complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); + cerr << "complex.num_edges():" << complex.num_edges() << endl; + int num_neigbors_seen = 0; + for (auto neighbor : complex.vertex_range(Vertex_handle(2))) { + cerr << "neighbor" << neighbor << endl; + ++num_neigbors_seen; + } + return num_neigbors_seen == 8; +} + +bool test_iterator_edge3() { + const int n = 10; + Complex complex(n); + for (int i = 0; i < n; i++) + for (int j = 0; j < i; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); + complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); + cerr << "complex.num_edges():" << complex.num_edges() << endl; + int num_neigbors_seen = 0; + for (auto edge : complex.edge_range(Vertex_handle(2))) { + std::cerr << edge << std::endl; + ++num_neigbors_seen; + } + return num_neigbors_seen == 8; +} + +bool test_iterator_triangles() { + const int n = 7; + Complex complex(n); + //create a "ring" around '0' + for (int i = 1; i < n; i++) + complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(i)); + for (int i = 1; i < n - 1; i++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(i + 1)); + complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(6)); + + PRINT(complex.to_string()); + + int num_triangles_seen = 0; + //for (auto t : complex.triangle_range(5)){ + TEST("triangles around 5 (should be 2 of them):"); + for (auto t : complex.triangle_range(Vertex_handle(5))) { + PRINT(t); + ++num_triangles_seen; + } + bool test = (num_triangles_seen == 2); + + num_triangles_seen = 0; + TEST("triangles around 0 (should be 6 of them):"); + for (auto t : complex.triangle_range(Vertex_handle(0))) { + PRINT(t); + ++num_triangles_seen; + } + test = test && (num_triangles_seen == 6); + + // we now add another triangle + complex.add_vertex(); + complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(7)); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(7)); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(6))); + num_triangles_seen = 0; + + TEST("triangles (should be 6 of them):"); + num_triangles_seen = 0; + for (auto t : complex.triangle_range()) { + PRINT(t); + ++num_triangles_seen; + } + test = test && (num_triangles_seen == 6); + PRINT(num_triangles_seen); + + return test; } -bool test_iterator_simplices3(){ - Complex complex(3); - complex.add_edge(Vertex_handle(0),Vertex_handle(1)); - complex.add_edge(Vertex_handle(1),Vertex_handle(2)); - complex.add_edge(Vertex_handle(2),Vertex_handle(0)); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); - - unsigned num_simplices = 0 ; - - for(const auto& simplex : complex.simplex_range(Vertex_handle(0))){ - simplex.dimension(); - DBGVALUE(simplex); - } - +//#include "combinatorics/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h" - for(const auto& simplex : complex.simplex_range()){ - DBGVALUE(simplex); - simplex.dimension(); - ++num_simplices; - } - bool correct_number_simplices = (num_simplices == 6); - return correct_number_simplices; +bool test_iterator_simplices() { + Complex complex(6); + complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); + complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0)); + complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(3)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(3)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(5)); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(5)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4)); + complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(5)); + complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4)); + + complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4), Vertex_handle(5))); + + bool correct_number_simplices = true; + + std::map expected_num_simplices; + + expected_num_simplices[Vertex_handle(0)] = 4; + expected_num_simplices[Vertex_handle(1)] = 6; + expected_num_simplices[Vertex_handle(2)] = 11; + expected_num_simplices[Vertex_handle(3)] = 9; + expected_num_simplices[Vertex_handle(4)] = 7; + expected_num_simplices[Vertex_handle(5)] = 7; + + for (auto pair : expected_num_simplices) { + unsigned num_simplices_around = 0; + for (const auto& simplex : complex.star_simplex_range(pair.first)) { + simplex.dimension(); + DBGVALUE(simplex); + ++num_simplices_around; + } + + correct_number_simplices = correct_number_simplices && (num_simplices_around == pair.second); + + DBGMSG("current vertex:", pair.first); + DBGMSG("expected_num_simplices:", pair.second); + DBGMSG("found:", num_simplices_around); + } + return correct_number_simplices; +} + +bool test_iterator_simplices2() { + Complex complex(2); + complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); + + for (const auto& s : complex.triangle_range()) { + s.dimension(); + return false; // there are no triangles + } + + unsigned num_simplices = 0; + + + DBGVALUE(complex.to_string()); + + for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) { + simplex.dimension(); + DBGVALUE(simplex); + } + + + for (const auto& simplex : complex.complex_simplex_range()) { + DBGVALUE(simplex); + simplex.dimension(); + ++num_simplices; + } + bool correct_number_simplices = (num_simplices == 3); + return correct_number_simplices; +} + +bool test_iterator_simplices3() { + Complex complex(3); + complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); + complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2)); + complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0)); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); + + unsigned num_simplices = 0; + + for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) { + simplex.dimension(); + DBGVALUE(simplex); + } + + + for (const auto& simplex : complex.complex_simplex_range()) { + DBGVALUE(simplex); + simplex.dimension(); + ++num_simplices; + } + bool correct_number_simplices = (num_simplices == 6); + return correct_number_simplices; +} + +bool test_iterator_simplices4() { + Complex empty_complex; + for (auto v : empty_complex.vertex_range()) { + (void) v; + } + for (auto e : empty_complex.edge_range()) { + empty_complex[e]; + } + for (auto t : empty_complex.triangle_range()) { + t.dimension(); + } + for (auto s : empty_complex.complex_simplex_range()) { + s.dimension(); + } + return true; } -bool test_iterator_simplices4(){ - Complex empty_complex; - for(auto v : empty_complex.vertex_range()){ - (void) v; - } - for(auto e : empty_complex.edge_range()){ - empty_complex[e]; - } - for(auto t : empty_complex.triangle_range()){ - t.dimension(); - } - for(auto s : empty_complex.simplex_range()){ - s.dimension(); - } - return true; +bool test_iterator_coboundary() { + Complex c(4); + build_complete(4, c); + c.remove_edge(Vertex_handle(0), Vertex_handle(2)); + PRINT(c.to_string()); + Simplex s02(Vertex_handle(0), Vertex_handle(2)); + int n = 0; + std::set expected; + expected.insert(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); + expected.insert(Simplex(Vertex_handle(0), Vertex_handle(2), Vertex_handle(3))); + for (const auto & s : c.coboundary_range(s02)) { + PRINT(s); + if (expected.find(s) == expected.end()) + return false; + ++n; + } + return n == 2; } - template -auto blocker_range(Map map) -> decltype( map | boost::adaptors::map_values){ - return map| boost::adaptors::map_values ; -} - - -bool test_iterator_blockers(){ - Complex complex; - Simplex_handle alpha; - Simplex_handle vertex_set_expected; - // Build the complexes - for (int i=0;i<20;i++){ - complex.add_vertex(); - } - for (int i=10;i<15;i++){ - for (int j=i+1;j<15;j++) - complex.add_edge(Vertex_handle(i),Vertex_handle(j)); - } - - complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12))); - complex.add_blocker(Simplex_handle(Vertex_handle(2),Vertex_handle(1),Vertex_handle(10))); - complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(9),Vertex_handle(15))); - complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(9),Vertex_handle(8))); - - // Print result - int num_blockers=0; - for(auto blockers : complex.blocker_range(Vertex_handle(10))){ - TESTVALUE(*blockers) ; - num_blockers++; - } - bool test = (num_blockers==3); - - num_blockers=0; - for (auto blockers : complex.blocker_range()){ - TESTVALUE(*blockers) ; - num_blockers++; - } - test = test && (num_blockers==4) ; - - return test; -} - - -bool test_link0(){ - - enum { a, b, c, d, n }; - Complex complex(n); - complex.add_edge(Vertex_handle(b),Vertex_handle(c));complex.add_edge(Vertex_handle(c),Vertex_handle(d)); - Simplex_handle alpha = Simplex_handle(Vertex_handle(c)); - Skeleton_blocker_link_complex L(complex,alpha); - - auto L2 = complex.link(alpha); - if(L!=L2) return false; - - PRINT(L.num_vertices()); - PRINT(L.to_string()); - - bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(b))); - bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(d))); - bool test3 = L.num_edges()==0; - bool test4 = L.num_blockers()==0; - return test1&&test2&&test3&&test4; - -} - -bool test_link1(){ - Complex complex; - - - // Build the complexes - for (int i=0;i<20;i++){ - complex.add_vertex(); - } - for (int i=10;i<15;i++){ - for (int j=i+1;j<15;j++) - complex.add_edge(Vertex_handle(i),Vertex_handle(j)); - } - Simplex_handle alpha(Vertex_handle(12),Vertex_handle(14)); - Skeleton_blocker_link_complex L(complex,alpha); - // Complexes built - - auto L2 = complex.link(alpha); - if(L!=L2) return false; - - // verification - bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); - bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); - bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); - bool test4 = L.num_edges()==3; - bool test5 = L.num_blockers()==0; - Root_simplex_handle simplex; - simplex.add_vertex(Root_vertex_handle(10)); - simplex.add_vertex(Root_vertex_handle(11)); - simplex.add_vertex(Root_vertex_handle(13)); - bool test6(L.get_simplex_address(simplex)); - bool test7 = L.contains(*(L.get_simplex_address(simplex))); - cerr <<"----> Ocomplex \n"; - return test1&&test2&&test3&&test4&&test5&&test6&&test7 ; - -} - - -bool test_link2(){ - Complex complex; - - Simplex_handle alpha; - Simplex_handle vertex_set_expected; - // Build the complexes - for (int i=0;i<20;i++){ - complex.add_vertex(); - } - for (int i=10;i<15;i++){ - for (int j=i+1;j<15;j++) - complex.add_edge(Vertex_handle(i),Vertex_handle(j)); - } - complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(13))); - alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14)); - Skeleton_blocker_link_complex L(complex,alpha); - // Complexes built - - // Print result - cerr << "complex complex"<< complex.to_string(); - cerr < Ocomplex \n"; - return test1&&test2&&test3&&test4&&test5&&test6 ; -} - -bool test_link3(){ - Complex complex; - - Simplex_handle alpha; - Simplex_handle vertex_set_expected; - // Build the complexes - for (int i=0;i<20;i++){ - complex.add_vertex(); - } - for (int i=10;i<15;i++){ - for (int j=i+1;j<15;j++) - complex.add_edge(Vertex_handle(i),Vertex_handle(j)); - } - complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12))); - alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14)); - Skeleton_blocker_link_complex L(complex,alpha); - // Complexes built - - // Print result - cerr << "complex complex"<< complex.to_string(); - cerr < L(complex,alpha); - // Complexes built - - // verification - bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); - bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); - bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); - bool test4 = L.num_edges()==3; - bool test5 = L.num_blockers()==1; - Root_simplex_handle simplex; - simplex.add_vertex(Root_vertex_handle(10)); - simplex.add_vertex(Root_vertex_handle(11)); - simplex.add_vertex(Root_vertex_handle(13)); - bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex))); - cerr <<"----> Ocomplex \n"; - return test1&&test2&&test3&&test4&&test5&&test6 ; - -} - -bool test_link5(){ - Complex complex(0,new Print_complex_visitor()); - // Build the complexes - build_complete(4,complex); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3))); +auto blocker_range(Map map) -> decltype(map | boost::adaptors::map_values) { + return map | boost::adaptors::map_values; +} + +bool test_iterator_blockers() { + Complex complex; + Simplex alpha; + Simplex vertex_set_expected; + // Build the complexes + for (int i = 0; i < 20; i++) { + complex.add_vertex(); + } + for (int i = 10; i < 15; i++) { + for (int j = i + 1; j < 15; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + } + + complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12))); + complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(1), Vertex_handle(10))); + complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(9), Vertex_handle(15))); + complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(9), Vertex_handle(8))); + + // Print result + int num_blockers = 0; + for (auto blockers : complex.blocker_range(Vertex_handle(10))) { + TESTVALUE(*blockers); + num_blockers++; + } + bool test = (num_blockers == 3); + + num_blockers = 0; + for (auto blockers : complex.blocker_range()) { + TESTVALUE(*blockers); + num_blockers++; + } + test = test && (num_blockers == 4); + + return test; +} + +bool test_link0() { + + enum { + a, b, c, d, n + }; + Complex complex(n); + complex.add_edge_without_blockers(Vertex_handle(b), Vertex_handle(c)); + complex.add_edge_without_blockers(Vertex_handle(c), Vertex_handle(d)); + Simplex alpha = Simplex(Vertex_handle(c)); + Skeleton_blocker_link_complex L(complex, alpha); + + auto L2 = complex.link(alpha); + if (L != L2) return false; + + PRINT(L.num_vertices()); + PRINT(L.to_string()); + + bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(b))); + bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(d))); + bool test3 = L.num_edges() == 0; + bool test4 = L.num_blockers() == 0; + return test1 && test2 && test3&&test4; + +} + +bool test_link1() { + Complex complex; + + + // Build the complexes + for (int i = 0; i < 20; i++) { + complex.add_vertex(); + } + for (int i = 10; i < 15; i++) { + for (int j = i + 1; j < 15; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + } + Simplex alpha(Vertex_handle(12), Vertex_handle(14)); + Skeleton_blocker_link_complex L(complex, alpha); + // Complexes built + + auto L2 = complex.link(alpha); + if (L != L2) return false; + + // verification + bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); + bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); + bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); + bool test4 = L.num_edges() == 3; + bool test5 = L.num_blockers() == 0; + Root_simplex_handle simplex; + simplex.add_vertex(Root_vertex_handle(10)); + simplex.add_vertex(Root_vertex_handle(11)); + simplex.add_vertex(Root_vertex_handle(13)); + bool test6(L.get_simplex_address(simplex)); + bool test7 = L.contains(*(L.get_simplex_address(simplex))); + cerr << "----> Ocomplex \n"; + return test1 && test2 && test3 && test4 && test5 && test6&&test7; + +} + +bool test_link2() { + Complex complex; + + Simplex alpha; + Simplex vertex_set_expected; + // Build the complexes + for (int i = 0; i < 20; i++) { + complex.add_vertex(); + } + for (int i = 10; i < 15; i++) { + for (int j = i + 1; j < 15; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + } + complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(13))); + alpha = Simplex(Vertex_handle(12), Vertex_handle(14)); + Skeleton_blocker_link_complex L(complex, alpha); + // Complexes built + + // Print result + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string(); + + auto L2 = complex.link(alpha); + if (L != L2) return false; + + + // verification + bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); + bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); + bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); + bool test4 = L.num_edges() == 3; + bool test5 = L.num_blockers() == 1; + Root_simplex_handle simplex; + simplex.add_vertex(Root_vertex_handle(10)); + simplex.add_vertex(Root_vertex_handle(11)); + simplex.add_vertex(Root_vertex_handle(13)); + bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex))); + cerr << "----> Ocomplex \n"; + return test1 && test2 && test3 && test4 && test5&&test6; +} + +bool test_link3() { + Complex complex; + + Simplex alpha; + Simplex vertex_set_expected; + // Build the complexes + for (int i = 0; i < 20; i++) { + complex.add_vertex(); + } + for (int i = 10; i < 15; i++) { + for (int j = i + 1; j < 15; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + } + complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12))); + alpha = Simplex(Vertex_handle(12), Vertex_handle(14)); + Skeleton_blocker_link_complex L(complex, alpha); + // Complexes built + + // Print result + cerr << "complex complex" << complex.to_string(); + cerr << endl << endl; + cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string(); + + auto L2 = complex.link(alpha); + if (L != L2) return false; + + + // verification + bool test = assert_vertex(L, *L.get_address(Root_vertex_handle(10))); + test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(11))); + test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(13))); + test = test && L.num_edges() == 2; + test = test && L.contains_edge(*L.get_address(Root_vertex_handle(10)), *L.get_address(Root_vertex_handle(13))); + test = test && L.contains_edge(*L.get_address(Root_vertex_handle(13)), *L.get_address(Root_vertex_handle(11))); + test = test && L.num_blockers() == 0; + return test; +} + +bool test_link4() { + Complex complex; + + // Build the complexes + for (int i = 0; i < 20; i++) { + complex.add_vertex(); + } + for (int i = 10; i < 15; i++) { + for (int j = i + 1; j < 15; j++) + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); + } + complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12), Vertex_handle(13))); + Simplex alpha(Vertex_handle(12), Vertex_handle(14)); + Skeleton_blocker_link_complex L(complex, alpha); + // Complexes built + + // verification + bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); + bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); + bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); + bool test4 = L.num_edges() == 3; + bool test5 = L.num_blockers() == 1; + Root_simplex_handle simplex; + simplex.add_vertex(Root_vertex_handle(10)); + simplex.add_vertex(Root_vertex_handle(11)); + simplex.add_vertex(Root_vertex_handle(13)); + bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex))); + cerr << "----> Ocomplex \n"; + return test1 && test2 && test3 && test4 && test5&&test6; + +} + +bool test_link5() { + Complex complex(0, new Print_complex_visitor()); + // Build the complexes + build_complete(4, complex); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); + + Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)); + + + Skeleton_blocker_link_complex L(complex, alpha); // Complexes built + + // Print result + PRINT(complex.to_string()); + cerr << endl << endl; + PRINT(L.to_string()); + + // verification + return L.num_vertices() == 0; +} + +bool test_link6() { + Complex complex(0, new Print_complex_visitor()); + // Build the complexes + build_complete(4, complex); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); - Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); + Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)); + Skeleton_blocker_link_complex link_blocker_alpha; - Skeleton_blocker_link_complex L(complex,alpha); // Complexes built + build_link_of_blocker(complex, alpha, link_blocker_alpha); + + // Print result + PRINT(complex.to_string()); + cerr << endl << endl; + PRINT(link_blocker_alpha.to_string()); - // Print result - PRINT(complex.to_string()); - cerr <()); - // Build the complexes - build_complete(4,complex); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); - - Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); - - Skeleton_blocker_link_complex link_blocker_alpha; +bool test_link7() { + Complex complex(0, new Print_complex_visitor()); + // Build the complexes + build_complete(6, complex); + complex.add_vertex(); + complex.add_vertex(); + for (int i = 3; i < 6; ++i) { + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(6)); + complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(7)); + } + complex.add_edge_without_blockers(Vertex_handle(6), Vertex_handle(7)); + complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); + complex.add_blocker(Simplex(Vertex_handle(3), Vertex_handle(4), Vertex_handle(5))); - build_link_of_blocker(complex,alpha,link_blocker_alpha); - - // Print result - PRINT(complex.to_string()); - cerr < link_blocker_alpha; -bool test_link7(){ - Complex complex(0,new Print_complex_visitor()); - // Build the complexes - build_complete(6,complex); - complex.add_vertex(); - complex.add_vertex(); - for(int i = 3; i<6; ++i){ - complex.add_edge(Vertex_handle(i),Vertex_handle(6)); - complex.add_edge(Vertex_handle(i),Vertex_handle(7)); - } - complex.add_edge(Vertex_handle(6),Vertex_handle(7)); - complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); - complex.add_blocker(Simplex_handle(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5))); + build_link_of_blocker(complex, alpha, link_blocker_alpha); - Simplex_handle alpha(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)); + //the result should be the edge {6,7} plus the blocker {0,1,2} - Skeleton_blocker_link_complex link_blocker_alpha; + // Print result + PRINT(complex.to_string()); + cerr << endl << endl; + DBGVALUE(link_blocker_alpha.to_string()); - build_link_of_blocker(complex,alpha,link_blocker_alpha); + Skeleton_blocker_link_complex link_blocker_alpha_cpy = link_blocker_alpha; - //the result should be the edge {6,7} plus the blocker {0,1,2} + DBGVALUE(link_blocker_alpha_cpy.to_string()); - // Print result - PRINT(complex.to_string()); - cerr < link_blocker_alpha_cpy = link_blocker_alpha; + DBGVALUE(equal_complexes); - DBGVALUE(link_blocker_alpha_cpy.to_string()); - - bool equal_complexes = - (link_blocker_alpha.num_vertices() == link_blocker_alpha_cpy.num_vertices()) - &&(link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers()) - &&(link_blocker_alpha.num_edges() == link_blocker_alpha_cpy.num_edges()) - ; - DBGVALUE((link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers())); - DBGVALUE((link_blocker_alpha.num_blockers() )); - DBGVALUE(( link_blocker_alpha_cpy.num_blockers())); - - DBGVALUE(equal_complexes); - - // verification - return link_blocker_alpha.num_vertices()==5 && link_blocker_alpha.num_edges()==4 && link_blocker_alpha.num_blockers()==1 && equal_complexes; + // verification + return link_blocker_alpha.num_vertices() == 5 && link_blocker_alpha.num_edges() == 4 && link_blocker_alpha.num_blockers() == 1 && equal_complexes; } - - - - - - - template -void add_triangle_edges(int a,int b,int c,list& simplices){ - typedef SimplexHandle Simplex_handle; - typedef typename SimplexHandle::Vertex_handle Vertex_handle; +void add_triangle_edges(int a, int b, int c, list& simplices) { + typedef SimplexHandle Simplex; + typedef typename SimplexHandle::Vertex_handle Vertex_handle; - simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b) )); - simplices.push_back(Simplex_handle(Vertex_handle(b),Vertex_handle(c) )); - simplices.push_back(Simplex_handle(Vertex_handle(c),Vertex_handle(a) )); + simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b))); + simplices.push_back(Simplex(Vertex_handle(b), Vertex_handle(c))); + simplices.push_back(Simplex(Vertex_handle(c), Vertex_handle(a))); } template -void add_triangle(int a,int b,int c,list& simplices){ - typedef SimplexHandle Simplex_handle; - typedef typename SimplexHandle::Vertex_handle Vertex_handle; - simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b),Vertex_handle(c))); +void add_triangle(int a, int b, int c, list& simplices) { + typedef SimplexHandle Simplex; + typedef typename SimplexHandle::Vertex_handle Vertex_handle; + simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b), Vertex_handle(c))); } -bool test_constructor(){ - list simplices; - - simplices.push_back(Simplex_handle(Vertex_handle(0))); - simplices.push_back(Simplex_handle(Vertex_handle(1))); - simplices.push_back(Simplex_handle(Vertex_handle(2))); - simplices.push_back(Simplex_handle(Vertex_handle(3))); - simplices.push_back(Simplex_handle(Vertex_handle(4))); - simplices.push_back(Simplex_handle(Vertex_handle(5))); +bool test_constructor() { + list simplices; - simplices.push_back(Simplex_handle(Vertex_handle(3),Vertex_handle(5) )); + simplices.push_back(Simplex(Vertex_handle(0))); + simplices.push_back(Simplex(Vertex_handle(1))); + simplices.push_back(Simplex(Vertex_handle(2))); + simplices.push_back(Simplex(Vertex_handle(3))); + simplices.push_back(Simplex(Vertex_handle(4))); + simplices.push_back(Simplex(Vertex_handle(5))); - add_triangle_edges(0,1,5,simplices); - add_triangle_edges(1,2,3,simplices); - add_triangle_edges(2,3,4,simplices); - add_triangle_edges(1,3,4,simplices); - add_triangle_edges(1,2,4,simplices); - - - add_triangle(0,1,5,simplices); - add_triangle(1,2,3,simplices); - add_triangle(1,3,4,simplices); - add_triangle(1,2,4,simplices); - add_triangle(2,3,4,simplices); - - Complex complex(simplices.begin(),simplices.end()); - - PRINT(complex.to_string()); - - return ( complex.num_vertices()==6&&complex.num_edges()==10&& complex.num_blockers()==2); -} - - -list subfaces(Simplex_handle top_face){ - list res; - if(top_face.dimension()==-1) return res; - if(top_face.dimension()==0) { - res.push_back(top_face); - return res; - } - else{ - Vertex_handle first_vertex = top_face.first_vertex(); - top_face.remove_vertex(first_vertex); - res = subfaces(top_face); - list copy = res; - for(auto& simplex : copy){ - simplex.add_vertex(first_vertex); - } - res.push_back(Simplex_handle(first_vertex)); - res.splice(res.end(),copy); - return res; - } -} - - -bool test_constructor2(){ - Simplex_handle simplex; - for(int i =0 ; i < 5;++i) - simplex.add_vertex(static_cast(i)); - - list simplices(subfaces(simplex)); - simplices.remove(simplex); - - Complex complex(simplices.begin(),simplices.end()); - - PRINT(complex.to_string()); - - for(auto b : complex.const_blocker_range()){ - cout << "b:"< simplices; - auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2)))); - subf.pop_back(); //remove max face -> now a blocker 012 - simplices.insert(simplices.begin(),subf.begin(),subf.end()); - DBGCONT(simplices); - Complex complex(simplices.begin(),simplices.end()); - DBGVALUE(complex.to_string()); + add_triangle(0, 1, 5, simplices); + add_triangle(1, 2, 3, simplices); + add_triangle(1, 3, 4, simplices); + add_triangle(1, 2, 4, simplices); + add_triangle(2, 3, 4, simplices); - if(complex.num_blockers()!=1) return false; - Sh expected_blocker(Vh(0),Vh(1),Vh(2)); - for(auto b : complex.const_blocker_range()) - if(*b!=expected_blocker) return false; + Complex complex(simplices.begin(), simplices.end()); + PRINT(complex.to_string()); - return complex.num_vertices()==3 && complex.num_blockers()==1; + return ( complex.num_vertices() == 6 && complex.num_edges() == 10 && complex.num_blockers() == 2); } -bool test_constructor4(){ - typedef Vertex_handle Vh; - typedef Simplex_handle Sh; - std::vector simplices; - auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2),Vh(3)))); - simplices.insert(simplices.begin(),subf.begin(),subf.end()); - - simplices.push_back(Sh(Vh(4))); - simplices.push_back(Sh(Vh(4),Vh(1))); - simplices.push_back(Sh(Vh(4),Vh(0))); - - DBGCONT(simplices); - Complex complex(simplices.begin(),simplices.end()); - - DBGVALUE(complex.to_string()); - if(complex.num_blockers()!=1) return false; - Sh expected_blocker(Vh(0),Vh(1),Vh(4)); - for(auto b : complex.const_blocker_range()) - if(*b!=expected_blocker) return false; - - return complex.num_vertices()==5 && complex.num_blockers()==1 && complex.num_edges()==8; +list subfaces(Simplex top_face) { + list res; + if (top_face.dimension() == -1) return res; + if (top_face.dimension() == 0) { + res.push_back(top_face); + return res; + } else { + Vertex_handle first_vertex = top_face.first_vertex(); + top_face.remove_vertex(first_vertex); + res = subfaces(top_face); + list copy = res; + for (auto& simplex : copy) { + simplex.add_vertex(first_vertex); + } + res.push_back(Simplex(first_vertex)); + res.splice(res.end(), copy); + return res; + } } +bool test_constructor2() { + Simplex simplex; + for (int i = 0; i < 5; ++i) + simplex.add_vertex(static_cast (i)); + list simplices(subfaces(simplex)); + simplices.remove(simplex); -bool test_constructor5(){ - typedef Vertex_handle Vh; - typedef Simplex_handle Sh; - std::vector simplices; - auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2)))); - simplices.insert(simplices.begin(),subf.begin(),subf.end()); - - simplices.push_back(Sh(Vh(3))); - simplices.push_back(Sh(Vh(3),Vh(1))); - simplices.push_back(Sh(Vh(3),Vh(2))); - simplices.push_back(Sh(Vh(4))); - simplices.push_back(Sh(Vh(4),Vh(1))); - simplices.push_back(Sh(Vh(4),Vh(0))); - simplices.push_back(Sh(Vh(5))); - simplices.push_back(Sh(Vh(5),Vh(2))); - simplices.push_back(Sh(Vh(5),Vh(0))); - - DBGCONT(simplices); - Complex complex(simplices.begin(),simplices.end()); + Complex complex(simplices.begin(), simplices.end()); - DBGVALUE(complex.to_string()); + PRINT(complex.to_string()); - return complex.num_vertices()==6 && complex.num_blockers()==3 && complex.num_edges()==9; -} - - -bool test_constructor6(){ - typedef Vertex_handle Vh; - typedef Simplex_handle Sh; - std::vector simplices; - auto subf(subfaces(Sh(Vh(0),Vh(1),Vh(2),Vh(3)))); - for(auto s:subf){ - Sh s1(Vh(0),Vh(1),Vh(2),Vh(3)); - Sh s2(Vh(1),Vh(2),Vh(3)); - if(s!=s1 && s!=s2) simplices.push_back(s); - } + for (auto b : complex.const_blocker_range()) { + cout << "b:" << b << endl; + } - DBGCONT(simplices); - Complex complex(simplices.begin(),simplices.end()); - - DBGVALUE(complex.to_string()); - - if(complex.num_blockers()!=1) return false; - Sh expected_blocker(Vh(1),Vh(2),Vh(3)); - for(auto b : complex.const_blocker_range()) - if(*b!=expected_blocker) return false; - return complex.num_vertices()==4 && complex.num_blockers()==1 && complex.num_edges()==6; + return ( complex.num_vertices() == 5 && complex.num_edges() == 10 && complex.num_blockers() == 1); } +bool test_constructor3() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2)))); + subf.pop_back(); //remove max face -> now a blocker 012 + simplices.insert(simplices.begin(), subf.begin(), subf.end()); + DBGCONT(simplices); + Complex complex(simplices.begin(), simplices.end()); -bool test_constructor7(){ - typedef Vertex_handle Vh; - typedef Simplex_handle Sh; - std::vector simplices; - simplices.push_back(Sh(Vh(0),Vh(1),Vh(2))); - simplices.push_back(Sh(Vh(1),Vh(2),Vh(3))); - simplices.push_back(Sh(Vh(3),Vh(0),Vh(2))); - simplices.push_back(Sh(Vh(3),Vh(0),Vh(1))); + DBGVALUE(complex.to_string()); - //get complex from top faces - Complex complex(make_complex_from_top_faces(simplices.begin(),simplices.end())); + if (complex.num_blockers() != 1) return false; + Sh expected_blocker(Vh(0), Vh(1), Vh(2)); + for (auto b : complex.const_blocker_range()) + if (*b != expected_blocker) return false; - DBGVALUE(complex.to_string()); - if(complex.num_blockers()!=1) return false; - Sh expected_blocker(Vh(0),Vh(1),Vh(2),Vh(3)); - for(auto b : complex.const_blocker_range()) - if(*b!=expected_blocker) return false; - return complex.num_vertices()==4 && complex.num_blockers()==1 && complex.num_edges()==6; + return complex.num_vertices() == 3 && complex.num_blockers() == 1; } +bool test_constructor4() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3)))); + simplices.insert(simplices.begin(), subf.begin(), subf.end()); -bool test_constructor8(){ - typedef Vertex_handle Vh; - typedef Simplex_handle Sh; - std::vector simplices; - simplices.push_back(Sh(Vh(0),Vh(1))); - simplices.push_back(Sh(Vh(2),Vh(1))); - simplices.push_back(Sh(Vh(0),Vh(2))); - simplices.push_back(Sh(Vh(3),Vh(1))); - simplices.push_back(Sh(Vh(2),Vh(3))); + simplices.push_back(Sh(Vh(4))); + simplices.push_back(Sh(Vh(4), Vh(1))); + simplices.push_back(Sh(Vh(4), Vh(0))); - //get complex from top faces - Complex complex(make_complex_from_top_faces(simplices.begin(),simplices.end())); + DBGCONT(simplices); + Complex complex(simplices.begin(), simplices.end()); - DBGVALUE(complex.to_string()); + DBGVALUE(complex.to_string()); + if (complex.num_blockers() != 1) return false; + Sh expected_blocker(Vh(0), Vh(1), Vh(4)); + for (auto b : complex.const_blocker_range()) + if (*b != expected_blocker) return false; - return complex.num_vertices()==4 && complex.num_blockers()==2 && complex.num_edges()==5; + return complex.num_vertices() == 5 && complex.num_blockers() == 1 && complex.num_edges() == 8; } - - - - -int main (int argc, char *argv[]) -{ - Tests tests_complex; - tests_complex.add("test simplex",test_simplex); - tests_complex.add("test_link0",test_link0); - tests_complex.add("test_link1",test_link1); - tests_complex.add("test_link2",test_link2); - tests_complex.add("test_link3",test_link3); - tests_complex.add("test_link4",test_link4); - tests_complex.add("test_link5",test_link5); - tests_complex.add("test_link6",test_link6); - tests_complex.add("test_link7",test_link7); - - tests_complex.add("test iterator vertices 1",test_iterator_vertices1); - tests_complex.add("test iterator vertices 2",test_iterator_vertices2); - tests_complex.add("test iterator edges",test_iterator_edge); - tests_complex.add("test iterator edges 2",test_iterator_edge2); - tests_complex.add("test iterator edges 3",test_iterator_edge3); - - tests_complex.add("test iterator simplices",test_iterator_simplices); - tests_complex.add("test iterator simplices2",test_iterator_simplices2); - tests_complex.add("test iterator simplices3",test_iterator_simplices3); - tests_complex.add("test iterator simplices4",test_iterator_simplices4); - - - tests_complex.add("test iterator blockers",test_iterator_blockers); - tests_complex.add("test_iterator_triangles",test_iterator_triangles); - - tests_complex.add("test_constructor_list_simplices",test_constructor); - tests_complex.add("test_constructor_list_simplices2",test_constructor2); - tests_complex.add("test_constructor_list_simplices3",test_constructor3); - tests_complex.add("test_constructor_list_simplices4",test_constructor4); - tests_complex.add("test_constructor_list_simplices5",test_constructor5); - tests_complex.add("test_constructor_list_simplices6",test_constructor6); - tests_complex.add("test_constructor_list_simplices7",test_constructor7); - tests_complex.add("test_constructor_list_simplices8",test_constructor8); - - - if(tests_complex.run()){ - return EXIT_SUCCESS; - } - else{ - return EXIT_FAILURE; - } - - // test_iterator_simplices(); +bool test_constructor5() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2)))); + simplices.insert(simplices.begin(), subf.begin(), subf.end()); + + simplices.push_back(Sh(Vh(3))); + simplices.push_back(Sh(Vh(3), Vh(1))); + simplices.push_back(Sh(Vh(3), Vh(2))); + simplices.push_back(Sh(Vh(4))); + simplices.push_back(Sh(Vh(4), Vh(1))); + simplices.push_back(Sh(Vh(4), Vh(0))); + simplices.push_back(Sh(Vh(5))); + simplices.push_back(Sh(Vh(5), Vh(2))); + simplices.push_back(Sh(Vh(5), Vh(0))); + + DBGCONT(simplices); + Complex complex(simplices.begin(), simplices.end()); + + DBGVALUE(complex.to_string()); + + return complex.num_vertices() == 6 && complex.num_blockers() == 3 && complex.num_edges() == 9; +} + +bool test_constructor6() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3)))); + for (auto s : subf) { + Sh s1(Vh(0), Vh(1), Vh(2), Vh(3)); + Sh s2(Vh(1), Vh(2), Vh(3)); + if (s != s1 && s != s2) simplices.push_back(s); + } + + DBGCONT(simplices); + Complex complex(simplices.begin(), simplices.end()); + + DBGVALUE(complex.to_string()); + + if (complex.num_blockers() != 1) return false; + Sh expected_blocker(Vh(1), Vh(2), Vh(3)); + for (auto b : complex.const_blocker_range()) + if (*b != expected_blocker) return false; + return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6; +} + +bool test_constructor7() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + simplices.push_back(Sh(Vh(0), Vh(1), Vh(2))); + simplices.push_back(Sh(Vh(1), Vh(2), Vh(3))); + simplices.push_back(Sh(Vh(3), Vh(0), Vh(2))); + simplices.push_back(Sh(Vh(3), Vh(0), Vh(1))); + + //get complex from top faces + Complex complex(make_complex_from_top_faces(simplices.begin(), simplices.end())); + + DBGVALUE(complex.to_string()); + + if (complex.num_blockers() != 1) return false; + Sh expected_blocker(Vh(0), Vh(1), Vh(2), Vh(3)); + for (auto b : complex.const_blocker_range()) + if (*b != expected_blocker) return false; + return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6; +} + +bool test_constructor8() { + typedef Vertex_handle Vh; + typedef Simplex Sh; + std::vector simplices; + simplices.push_back(Sh(Vh(0), Vh(1))); + simplices.push_back(Sh(Vh(2), Vh(1))); + simplices.push_back(Sh(Vh(0), Vh(2))); + simplices.push_back(Sh(Vh(3), Vh(1))); + simplices.push_back(Sh(Vh(2), Vh(3))); + + //get complex from top faces + Complex complex(make_complex_from_top_faces(simplices.begin(), simplices.end())); + + DBGVALUE(complex.to_string()); + + return complex.num_vertices() == 4 && complex.num_blockers() == 2 && complex.num_edges() == 5; +} + +int main(int argc, char *argv[]) { + Tests tests_complex; + tests_complex.add("test simplex", test_simplex); + tests_complex.add("test_link0", test_link0); + tests_complex.add("test_link1", test_link1); + tests_complex.add("test_link2", test_link2); + tests_complex.add("test_link3", test_link3); + tests_complex.add("test_link4", test_link4); + tests_complex.add("test_link5", test_link5); + tests_complex.add("test_link6", test_link6); + tests_complex.add("test_link7", test_link7); + + tests_complex.add("test_constructor_list_simplices", test_constructor); + tests_complex.add("test_constructor_list_simplices2", test_constructor2); + tests_complex.add("test_constructor_list_simplices3", test_constructor3); + tests_complex.add("test_constructor_list_simplices4", test_constructor4); + tests_complex.add("test_constructor_list_simplices5", test_constructor5); + tests_complex.add("test_constructor_list_simplices6", test_constructor6); + tests_complex.add("test_constructor_list_simplices7", test_constructor7); + tests_complex.add("test_constructor_list_simplices8", test_constructor8); + + tests_complex.add("test iterator vertices 1", test_iterator_vertices1); + tests_complex.add("test iterator vertices 2", test_iterator_vertices2); + tests_complex.add("test iterator edges", test_iterator_edge); + tests_complex.add("test iterator edges 2", test_iterator_edge2); + tests_complex.add("test iterator edges 3", test_iterator_edge3); + tests_complex.add("test iterator blockers", test_iterator_blockers); + tests_complex.add("test_iterator_triangles", test_iterator_triangles); + tests_complex.add("test iterator simplices", test_iterator_simplices); + tests_complex.add("test iterator simplices2", test_iterator_simplices2); + tests_complex.add("test iterator simplices3", test_iterator_simplices3); + tests_complex.add("test iterator simplices4", test_iterator_simplices4); + tests_complex.add("test iterator coboundary", test_iterator_coboundary); + + if (tests_complex.run()) { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } + + // test_iterator_simplices(); } -- cgit v1.2.3 From 52dbe195ea62ca333c7e6834d9b92e4d9e5557ea Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 16 Oct 2015 15:25:35 +0000 Subject: Sort in parallel in initialize_filtration using TBB. No build machinery support for now. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@858 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 94071e9da20993dff60743ac75125f26ad62e55e --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 4c6a95e8..edb1d7c9 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -35,6 +35,10 @@ #include #include +#ifdef GUDHI_USE_TBB +#include +#endif + #include #include #include @@ -788,8 +792,12 @@ class Simplex_tree { * heuristic consists in inserting the cofaces of a simplex as soon as * possible. */ +#ifdef GUDHI_USE_TBB + tbb::parallel_sort(filtration_vect_, is_before_in_filtration(this)); +#else std::stable_sort(filtration_vect_.begin(), filtration_vect_.end(), is_before_in_filtration(this)); +#endif } private: -- cgit v1.2.3 From b6c3298ce211935f65cc174cc86c0c6a5073035f Mon Sep 17 00:00:00 2001 From: glisse Date: Sat, 17 Oct 2015 18:55:35 +0000 Subject: Simplify operator== for the boundary iterator. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@862 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 48228705e9f310ed842e214c5d8849e8f1e0c670 --- .../include/gudhi/Simplex_tree/Simplex_tree_iterators.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h index f77bac15..c5027f22 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h @@ -99,8 +99,7 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< // any end() iterator explicit Simplex_tree_boundary_simplex_iterator(SimplexTree * st) - : last_(st->null_vertex()), - sib_(NULL) { + : sh_(st->null_simplex()) { } Simplex_tree_boundary_simplex_iterator(SimplexTree * st, Simplex_handle sh) @@ -113,7 +112,7 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< if (sib_ != NULL) { sh_ = sib_->find(next_); } else { - last_ = st->null_vertex(); + sh_ = st->null_simplex(); } // vertex: == end() } @@ -121,16 +120,17 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< friend class boost::iterator_core_access; // valid when iterating along the SAME boundary. bool equal(Simplex_tree_boundary_simplex_iterator const& other) const { - return (sib_ == other.sib_ && last_ == other.last_); + return sh_ == other.sh_; } Simplex_handle const& dereference() const { + assert(sh_ != st_->null_simplex()); return sh_; } void increment() { if (sib_ == NULL) { - last_ = st_->null_vertex(); + sh_ = st_->null_simplex(); return; } -- cgit v1.2.3 From 20cb0d7a919005ba20d0a76cca38a73d3a119480 Mon Sep 17 00:00:00 2001 From: salinasd Date: Sun, 18 Oct 2015 10:44:55 +0000 Subject: GH: dim3 restriction, skbl: num_simplices methods git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/skb_simplex_insertion_merge@865 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e7f9d48c4e6af222b6f158e906a3a592027d39b8 --- src/Contraction/example/Garland_heckbert.cpp | 23 ++++++++++------ .../include/gudhi/Skeleton_blocker_complex.h | 31 ++++++++++++++++++---- .../gudhi/Skeleton_blocker_simplifiable_complex.h | 4 +-- .../test/TestSkeletonBlockerComplex.cpp | 22 +++++++++++++-- 4 files changed, 62 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Contraction/example/Garland_heckbert.cpp b/src/Contraction/example/Garland_heckbert.cpp index 70f29b6a..681426e0 100644 --- a/src/Contraction/example/Garland_heckbert.cpp +++ b/src/Contraction/example/Garland_heckbert.cpp @@ -145,13 +145,13 @@ class GH_visitor : public Gudhi::contraction::Contraction_visitor { int main(int argc, char *argv[]) { if (argc != 4) { - std::cerr << "Usage " << argv[0] << " input.off output.off N to load the file input.off, contract N edges and save " - << "the result to output.off.\n"; + std::cerr << "Usage " << argv[0] << " input.off output.off N to load the file input.off, contract N edges and save the result to output.off.\n"; return EXIT_FAILURE; } Complex complex; - + typedef typename Complex::Vertex_handle Vertex_handle; + // load the points Skeleton_blocker_off_reader off_reader(argv[1], complex); if (!off_reader.is_valid()) { @@ -159,8 +159,12 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - std::cout << "Load complex with " << complex.num_vertices() << " vertices" << std::endl; + if(!complex.empty() && !complex.point(Vertex_handle(0)).dimension()==3) { + std::cerr << "Only points of dimension 3 are supported." << std::endl; + return EXIT_FAILURE; + } + std::cout << "Load complex with " << complex.num_vertices() << " vertices" << std::endl; int num_contractions = atoi(argv[3]); @@ -171,22 +175,25 @@ int main(int argc, char *argv[]) { new GH_cost(complex), new GH_placement(complex), contraction::make_link_valid_contraction(), - new GH_visitor(complex)); + new GH_visitor(complex) + ); std::cout << "Contract " << num_contractions << " edges" << std::endl; contractor.contract_edges(num_contractions); std::cout << "Final complex has " << complex.num_vertices() << " vertices, " << - complex.num_edges() << " edges and" << + complex.num_edges() << " edges and " << complex.num_triangles() << " triangles." << std::endl; - // write simplified complex + //write simplified complex Skeleton_blocker_off_writer off_writer(argv[2], complex); return EXIT_SUCCESS; } +#endif // GARLAND_HECKBERT_H_ + + -#endif // GARLAND_HECKBERT_H_ diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index 78384abf..b1995783 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -134,8 +134,8 @@ class Skeleton_blocker_complex { typedef typename std::multimap::const_iterator BlockerMapConstIterator; protected: - int num_vertices_; - int num_blockers_; + size_t num_vertices_; + size_t num_blockers_; typedef Skeleton_blocker_complex_visitor Visitor; // typedef Visitor* Visitor_ptr; @@ -164,10 +164,10 @@ class Skeleton_blocker_complex { /** *@brief constructs a simplicial complex with a given number of vertices and a visitor. */ - explicit Skeleton_blocker_complex(int num_vertices_ = 0, Visitor* visitor_ = NULL) + explicit Skeleton_blocker_complex(size_t num_vertices_ = 0, Visitor* visitor_ = NULL) : visitor(visitor_) { clear(); - for (int i = 0; i < num_vertices_; ++i) { + for (size_t i = 0; i < num_vertices_; ++i) { add_vertex(); } } @@ -998,10 +998,31 @@ class Skeleton_blocker_complex { return std::distance(triangles.begin(), triangles.end()); } + + /* + * @brief returns the number of simplices of a given dimension in the complex. + */ + size_t num_simplices() const { + auto simplices = complex_simplex_range(); + return std::distance(simplices.begin(), simplices.end()); + } + + /* + * @brief returns the number of simplices of a given dimension in the complex. + */ + size_t num_simplices(unsigned dimension) const { + //todo iterator on k-simplices + size_t res = 0; + for(const auto& s: complex_simplex_range()) + if(s.dimension() == dimension) + ++res; + return res; + } + /* * @brief returns the number of blockers in the complex. */ - int num_blockers() const { + size_t num_blockers() const { return num_blockers_; } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h index 49a1ea8b..79a7ed79 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h @@ -45,9 +45,7 @@ bool Skeleton_blocker_complex::is_popable_blocker(Blocker_han assert(this->contains_blocker(*sigma)); Skeleton_blocker_link_complex link_blocker_sigma; build_link_of_blocker(*this, *sigma, link_blocker_sigma); - - bool res = link_blocker_sigma.is_contractible() == CONTRACTIBLE; - return res; + return link_blocker_sigma.is_contractible() == CONTRACTIBLE; } /** diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp index 418638e8..69abd279 100644 --- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp +++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp @@ -104,6 +104,23 @@ bool test_simplex() { return simplex.dimension() == 3; } +bool test_num_simplices() { + int n = 4; + Complex complex; + build_complete(n, complex); + size_t sum = 0; + for (int i = 0; i < n; i++) { + PRINT(complex.num_simplices(i)); + sum += complex.num_simplices(i); + } + return + complex.num_vertices() == n && + complex.num_edges() == 6 && + sum == 15 && + complex.num_simplices() == 15; +} + + bool test_iterator_vertices1() { int n = 10; Complex complex(10); @@ -118,7 +135,7 @@ bool test_iterator_vertices1() { bool test_iterator_vertices2() { int n = 10; - Complex complex(10); + Complex complex; build_complete(10, complex); cerr << "complex.num_vertices():" << complex.num_vertices() << endl; cerr << "complex.num_edges():" << complex.num_edges() << endl; @@ -348,7 +365,7 @@ bool test_iterator_simplices4() { } bool test_iterator_coboundary() { - Complex c(4); + Complex c; build_complete(4, c); c.remove_edge(Vertex_handle(0), Vertex_handle(2)); PRINT(c.to_string()); @@ -892,6 +909,7 @@ bool test_constructor8() { int main(int argc, char *argv[]) { Tests tests_complex; tests_complex.add("test simplex", test_simplex); + tests_complex.add("test_num_simplices", test_num_simplices); tests_complex.add("test_link0", test_link0); tests_complex.add("test_link1", test_link1); tests_complex.add("test_link2", test_link2); -- cgit v1.2.3 From 91a2adbaeec76b4ee172123a5a833065f910f5ab Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 18 Oct 2015 20:31:25 +0000 Subject: Also use TBB to build Hasse_complex in parallel. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@870 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6633f9b8261cfb2acfb62d1f4748df73375086bd --- src/Hasse_complex/include/gudhi/Hasse_complex.h | 30 +++++++++----- src/common/include/gudhi/allocator.h | 55 +++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 src/common/include/gudhi/allocator.h (limited to 'src') diff --git a/src/Hasse_complex/include/gudhi/Hasse_complex.h b/src/Hasse_complex/include/gudhi/Hasse_complex.h index 67079687..af9ae5e9 100644 --- a/src/Hasse_complex/include/gudhi/Hasse_complex.h +++ b/src/Hasse_complex/include/gudhi/Hasse_complex.h @@ -29,6 +29,12 @@ #include // for pair #include +#include + +#ifdef GUDHI_USE_TBB +#include +#endif + namespace Gudhi { template < class HasseCpx > @@ -97,20 +103,24 @@ class Hasse_complex { template < class Complex_ds > Hasse_complex(Complex_ds & cpx) - : complex_() + : complex_(cpx.num_simplices()) , vertices_() , threshold_(cpx.filtration()) , num_vertices_() , dim_max_(cpx.dimension()) { - complex_.reserve(cpx.num_simplices()); - int idx = 0; - for (auto cpx_sh : cpx.filtration_simplex_range()) { - complex_.push_back(Hasse_simp(cpx, cpx_sh)); - if (dimension(idx) == 0) { + int size = complex_.size(); +#ifdef GUDHI_USE_TBB + tbb::parallel_for(0,size,[&](int idx){new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));}); + for (int idx=0; idx complex_; + std::vector< Hasse_simp, Gudhi::no_init_allocator > complex_; std::vector vertices_; Filtration_value threshold_; size_t num_vertices_; @@ -218,7 +228,7 @@ std::istream& operator>>(std::istream & is // read all simplices in the file as a list of vertices while (read_hasse_simplex(is, boundary, fil)) { // insert every simplex in the simplex tree - hcpx.complex_.push_back(Hasse_simplex< Hasse_complex >(key, fil, boundary)); + hcpx.complex_.emplace_back(key, fil, boundary); if (max_dim < hcpx.dimension(key)) { max_dim = hcpx.dimension(key); diff --git a/src/common/include/gudhi/allocator.h b/src/common/include/gudhi/allocator.h new file mode 100644 index 00000000..b825173b --- /dev/null +++ b/src/common/include/gudhi/allocator.h @@ -0,0 +1,55 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Marc Glisse + * + * Copyright (C) 2015 INRIA Saclay - Ile de France + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_ALLOCATOR_H_ +#define GUDHI_ALLOCATOR_H_ + +#include +#include + +namespace Gudhi { + +/** \private + * An allocator that can be used to build an uninitialized vector. + */ +template > +struct no_init_allocator : Base { + typedef std::allocator_traits Base_traits; + template struct rebind { + typedef no_init_allocator> other; + }; + + // Inherit constructors. + using Base::Base; + + // Do nothing: that's the whole point! + template + void construct(P*)noexcept{} + + template void construct(P*p, U&&...u){ + Base_traits::construct(*(Base*)this, p, std::forward(u)...); + } +}; + +} // namespace Gudhi + +#endif // GUDHI_ALLOCATOR_H_ -- cgit v1.2.3 From 2814e25cbc70160e57f426ec708f6d99180ef5fd Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 25 Oct 2015 21:41:01 +0000 Subject: Example to compute persistence of a Rips filtration "in parallel". On a machine with a gazillion cores, it gains a factor >2 at the expense of some memory. At this point, construction of the Rips graph and expansion are not negligible anymore and could use some parallelism. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@875 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 53d6a74338f1346bd7d1ca018ec15dd1ee8287e8 --- src/Hasse_complex/include/gudhi/Hasse_complex.h | 14 +- .../example/parallel_rips_persistence.cpp | 180 +++++++++++++++++++++ 2 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 src/Persistent_cohomology/example/parallel_rips_persistence.cpp (limited to 'src') diff --git a/src/Hasse_complex/include/gudhi/Hasse_complex.h b/src/Hasse_complex/include/gudhi/Hasse_complex.h index af9ae5e9..38887264 100644 --- a/src/Hasse_complex/include/gudhi/Hasse_complex.h +++ b/src/Hasse_complex/include/gudhi/Hasse_complex.h @@ -44,8 +44,7 @@ struct Hasse_simplex { template< class Complex_ds > Hasse_simplex(Complex_ds & cpx , typename Complex_ds::Simplex_handle sh) - : key_(cpx.key(sh)) - , filtration_(cpx.filtration(sh)) + : filtration_(cpx.filtration(sh)) , boundary_() { boundary_.reserve(cpx.dimension(sh) + 1); for (auto b_sh : cpx.boundary_simplex_range(sh)) { @@ -55,7 +54,7 @@ struct Hasse_simplex { Hasse_simplex(typename HasseCpx::Simplex_key key , typename HasseCpx::Filtration_value fil - , std::vector boundary) + , std::vector const& boundary) : key_(key) , filtration_(fil) , boundary_(boundary) { } @@ -197,11 +196,12 @@ class Hasse_complex { } void initialize_filtration() { + // Setting the keys is done by pcoh, Simplex_tree doesn't do it either. +#if 0 Simplex_key key = 0; - for (auto & h_simp : complex_) { - h_simp.key_ = key; - ++key; - } + for (auto & h_simp : complex_) + h_simp.key_ = key++; +#endif } std::vector< Hasse_simp, Gudhi::no_init_allocator > complex_; diff --git a/src/Persistent_cohomology/example/parallel_rips_persistence.cpp b/src/Persistent_cohomology/example/parallel_rips_persistence.cpp new file mode 100644 index 00000000..425a5b2c --- /dev/null +++ b/src/Persistent_cohomology/example/parallel_rips_persistence.cpp @@ -0,0 +1,180 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Clément Maria, Marc Glisse + * + * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France), + * 2015 INRIA Saclay Île de France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include "gudhi/Hasse_complex.h" + +#include + +#ifdef GUDHI_USE_TBB +#include +#endif + +#include +#include + +//////////////////////////////////////////////////////////////// +// // +// WARNING: persistence computation itself is not parallel, // +// and this uses more memory than rips_persistence. // +// // +//////////////////////////////////////////////////////////////// + +using namespace Gudhi; +using namespace Gudhi::persistent_cohomology; + +typedef int Vertex_handle; +typedef double Filtration_value; + +void program_options(int argc, char * argv[] + , std::string & filepoints + , std::string & filediag + , Filtration_value & threshold + , int & dim_max + , int & p + , Filtration_value & min_persistence); + +int main(int argc, char * argv[]) { + std::string filepoints; + std::string filediag; + Filtration_value threshold; + int dim_max; + int p; + Filtration_value min_persistence; + + program_options(argc, argv, filepoints, filediag, threshold, dim_max, p, min_persistence); + + // Extract the points from the file filepoints + typedef std::vector Point_t; + std::vector< Point_t > points; + read_points(filepoints, points); + + // Compute the proximity graph of the points + Graph_t prox_graph = compute_proximity_graph(points, threshold + , euclidean_distance); + + // Construct the Rips complex in a Simplex Tree + Simplex_tree<>& st = *new Simplex_tree<>; + // insert the proximity graph in the simplex tree + st.insert_graph(prox_graph); + // expand the graph until dimension dim_max + st.expansion(dim_max); + + std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; + std::cout << " and has dimension " << st.dimension() << " \n"; + +#ifdef GUDHI_USE_TBB + // Unnecessary, but clarifies which operations are parallel. + tbb::task_scheduler_init ts; +#endif + + // Sort the simplices in the order of the filtration + st.initialize_filtration(); + int count = 0; + for (auto sh : st.filtration_simplex_range()) + st.assign_key(sh, count++); + + // Convert to a more convenient representation. + Hasse_complex<> hcpx(st); + +#ifdef GUDHI_USE_TBB + ts.terminate(); +#endif + + // Free some space. + delete &st; + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Hasse_complex<>, Field_Zp > pcoh(hcpx); + // initializes the coefficient field for homology + pcoh.init_coefficients(p); + + pcoh.compute_persistent_cohomology(min_persistence); + + // Output the diagram in filediag + if (filediag.empty()) { + pcoh.output_diagram(); + } else { + std::ofstream out(filediag); + pcoh.output_diagram(out); + out.close(); + } +} + +void program_options(int argc, char * argv[] + , std::string & filepoints + , std::string & filediag + , Filtration_value & threshold + , int & dim_max + , int & p + , Filtration_value & min_persistence) { + namespace po = boost::program_options; + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value(&filepoints), + "Name of file containing a point set. Format is one point per line: X1 ... Xd "); + + po::options_description visible("Allowed options", 100); + visible.add_options() + ("help,h", "produce help message") + ("output-file,o", po::value(&filediag)->default_value(std::string()), + "Name of file in which the persistence diagram is written. Default print in std::cout") + ("max-edge-length,r", po::value(&threshold)->default_value(0), + "Maximal length of an edge for the Rips complex construction.") + ("cpx-dimension,d", po::value(&dim_max)->default_value(1), + "Maximal dimension of the Rips complex we want to compute.") + ("field-charac,p", po::value(&p)->default_value(11), + "Characteristic p of the coefficient field Z/pZ for computing homology.") + ("min-persistence,m", po::value(&min_persistence), + "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals"); + + po::positional_options_description pos; + pos.add("input-file", 1); + + po::options_description all; + all.add(visible).add(hidden); + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv). + options(all).positional(pos).run(), vm); + po::notify(vm); + + if (vm.count("help") || !vm.count("input-file")) { + std::cout << std::endl; + std::cout << "Compute the persistent homology with coefficient field Z/pZ \n"; + std::cout << "of a Rips complex defined on a set of input points.\n \n"; + std::cout << "The output diagram contains one bar per line, written with the convention: \n"; + std::cout << " p dim b d \n"; + std::cout << "where dim is the dimension of the homological feature,\n"; + std::cout << "b and d are respectively the birth and death of the feature and \n"; + std::cout << "p is the characteristic of the field Z/pZ used for homology coefficients." << std::endl << std::endl; + + std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl; + std::cout << visible << std::endl; + std::abort(); + } +} -- cgit v1.2.3 From a57e87727ea3cbf73ac8e4ce0fe65a19de1fe2d9 Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 9 Nov 2015 16:54:45 +0000 Subject: New Simplex_tree_options_fast_persistence, while Simplex_tree_options_full_featured switches to the safe default of allowing non-contiguous vertices. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@896 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 60bc11a90027ed17233903d22a6494198f30eeb1 --- .../example/performance_rips_persistence.cpp | 2 +- .../example/rips_multifield_persistence.cpp | 5 +-- .../example/rips_persistence.cpp | 5 +-- src/Simplex_tree/include/gudhi/Simplex_tree.h | 36 ++++++++++++++++------ src/Simplex_tree/test/simplex_tree_unit_test.cpp | 2 +- 5 files changed, 34 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/example/performance_rips_persistence.cpp b/src/Persistent_cohomology/example/performance_rips_persistence.cpp index 0e912d57..b0366c6c 100644 --- a/src/Persistent_cohomology/example/performance_rips_persistence.cpp +++ b/src/Persistent_cohomology/example/performance_rips_persistence.cpp @@ -85,7 +85,7 @@ int main(int argc, char * argv[]) { std::cout << "Compute Rips graph in " << enlapsed_sec << " sec.\n"; // Construct the Rips complex in a Simplex Tree - Simplex_tree<> st; + Simplex_tree st; start = std::chrono::system_clock::now(); // insert the proximity graph in the simplex tree diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp index 5277bf7a..c5cd775d 100644 --- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp @@ -68,7 +68,8 @@ int main(int argc, char * argv[]) { , euclidean_distance); // Construct the Rips complex in a Simplex Tree - Simplex_tree<> st; + typedef Simplex_tree ST; + ST st; // insert the proximity graph in the simplex tree st.insert_graph(prox_graph); // expand the graph until dimension dim_max @@ -78,7 +79,7 @@ int main(int argc, char * argv[]) { st.initialize_filtration(); // Compute the persistence diagram of the complex - Persistent_cohomology< Simplex_tree<>, Multi_field > pcoh(st); + Persistent_cohomology pcoh(st); // initializes the coefficient field for homology pcoh.init_coefficients(min_p, max_p); // compute persistent homology, disgarding persistent features of life shorter than min_persistence diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp index 9b1ef42f..2d926a0d 100644 --- a/src/Persistent_cohomology/example/rips_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_persistence.cpp @@ -65,7 +65,8 @@ int main(int argc, char * argv[]) { , euclidean_distance); // Construct the Rips complex in a Simplex Tree - Simplex_tree<> st; + typedef Simplex_tree ST; + ST st; // insert the proximity graph in the simplex tree st.insert_graph(prox_graph); // expand the graph until dimension dim_max @@ -78,7 +79,7 @@ int main(int argc, char * argv[]) { st.initialize_filtration(); // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(st); + persistent_cohomology::Persistent_cohomology pcoh(st); // initializes the coefficient field for homology pcoh.init_coefficients(p); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 74ae1713..b9c2a245 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -77,16 +77,7 @@ namespace Gudhi { * @{ */ -/// Model of SimplexTreeOptions. -struct Simplex_tree_options_full_featured { - typedef linear_indexing_tag Indexing_tag; - typedef int Vertex_handle; - typedef double Filtration_value; - typedef int Simplex_key; - static const bool store_key = true; - static const bool store_filtration = true; - static const bool contiguous_vertices = true; -}; +struct Simplex_tree_options_full_featured; /** * \brief Simplex Tree data structure for representing simplicial complexes. @@ -1159,6 +1150,31 @@ std::istream& operator>>(std::istream & is, Simplex_tree & st) { return is; } + +/// Model of SimplexTreeOptions. +struct Simplex_tree_options_full_featured { + typedef linear_indexing_tag Indexing_tag; + typedef int Vertex_handle; + typedef double Filtration_value; + typedef int Simplex_key; + static const bool store_key = true; + static const bool store_filtration = true; + static const bool contiguous_vertices = false; +}; + +/** Model of SimplexTreeOptions, faster than + `Simplex_tree_options_full_featured` but note the unsafe + `contiguous_vertices` option. */ +struct Simplex_tree_options_fast_persistence { + typedef linear_indexing_tag Indexing_tag; + typedef int Vertex_handle; + typedef float Filtration_value; + typedef int Simplex_key; + static const bool store_key = true; + static const bool store_filtration = true; + static const bool contiguous_vertices = true; +}; + /** @} */ // end defgroup simplex_tree } // namespace Gudhi diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index fff00d77..c2e214c0 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Find in the simplex_tree // ------------------------------------------------------------------------------------------------------------------ typeVectorVertex simpleSimplexVector{1}; - Simplex_tree<>::Simplex_handle simplexFound = st.find(simpleSimplexVector); + typeST::Simplex_handle simplexFound = st.find(simpleSimplexVector); std::cout << "**************IS THE SIMPLEX {1} IN THE SIMPLEX TREE ?\n"; if (simplexFound != st.null_simplex()) std::cout << "***+ YES IT IS!\n"; -- cgit v1.2.3 From 50351a117c7f2622ce2eb5d1d08f561cb9baaa89 Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 9 Nov 2015 18:28:26 +0000 Subject: Change SimplexTreeUT so it can test several versions of Simplex_tree. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@897 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 55d2cf5d87323a54675fe787df3e76dc31a2d684 --- src/Simplex_tree/test/simplex_tree_unit_test.cpp | 99 ++++++++++++++---------- 1 file changed, 57 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index c2e214c0..beb3dc11 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -4,10 +4,12 @@ #include // std::pair, std::make_pair #include // float comparison #include +#include // greater #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "simplex_tree" #include +#include // ^ // /!\ Nothing else from Simplex_tree shall be included to test includes are well defined. @@ -15,26 +17,25 @@ using namespace Gudhi; -typedef Simplex_tree<> typeST; -typedef std::pair typePairSimplexBool; -typedef std::vector typeVectorVertex; -typedef std::pair typeSimplex; +typedef boost::mpl::list, Simplex_tree> list_of_tested_variants; const Vertex_handle DEFAULT_VERTEX_HANDLE = (const Vertex_handle) - 1; const Filtration_value DEFAULT_FILTRATION_VALUE = (const Filtration_value) 0.0; +template void test_empty_simplex_tree(typeST& tst) { BOOST_CHECK(tst.null_vertex() == DEFAULT_VERTEX_HANDLE); BOOST_CHECK(tst.filtration() == DEFAULT_FILTRATION_VALUE); BOOST_CHECK(tst.num_vertices() == (size_t) 0); BOOST_CHECK(tst.num_simplices() == (size_t) 0); - typeST::Siblings* STRoot = tst.root(); - BOOST_CHECK(STRoot != NULL); - BOOST_CHECK(STRoot->oncles() == NULL); + typename typeST::Siblings* STRoot = tst.root(); + BOOST_CHECK(STRoot != nullptr); + BOOST_CHECK(STRoot->oncles() == nullptr); BOOST_CHECK(STRoot->parent() == DEFAULT_VERTEX_HANDLE); BOOST_CHECK(tst.dimension() == -1); } +template void test_iterators_on_empty_simplex_tree(typeST& tst) { std::cout << "Iterator on vertices: " << std::endl; for (auto vertex : tst.complex_vertex_range()) { @@ -56,8 +57,9 @@ void test_iterators_on_empty_simplex_tree(typeST& tst) { } } -BOOST_AUTO_TEST_CASE(simplex_tree_when_empty) { - const Filtration_value DEFAULT_FILTRATION_VALUE = 0; +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_when_empty, typeST, list_of_tested_variants) { + typedef std::pair typePairSimplexBool; + typedef std::vector typeVectorVertex; std::cout << "********************************************************************" << std::endl; std::cout << "TEST OF DEFAULT CONSTRUCTOR" << std::endl; @@ -72,7 +74,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_when_empty) { BOOST_CHECK(simplexVectorEmpty.empty() == true); typePairSimplexBool returnEmptyValue = st.insert_simplex(simplexVectorEmpty, DEFAULT_FILTRATION_VALUE); - BOOST_CHECK(returnEmptyValue.first == typeST::Simplex_handle(NULL)); + BOOST_CHECK(returnEmptyValue.first == typename typeST::Simplex_handle(nullptr)); BOOST_CHECK(returnEmptyValue.second == true); test_empty_simplex_tree(st); @@ -84,7 +86,7 @@ bool AreAlmostTheSame(float a, float b) { return std::fabs(a - b) < std::numeric_limits::epsilon(); } -BOOST_AUTO_TEST_CASE(simplex_tree_from_file) { +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_from_file, typeST, list_of_tested_variants) { // TEST OF INSERTION std::cout << "********************************************************************" << std::endl; std::cout << "TEST OF SIMPLEX TREE FROM A FILE" << std::endl; @@ -101,7 +103,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_from_file) { // Check BOOST_CHECK(st.num_simplices() == 143353); BOOST_CHECK(st.dimension() == 3); - BOOST_CHECK(st.filtration() == 0.4); + BOOST_CHECK(AreAlmostTheSame(st.filtration(), 0.4)); int previous_size = 0; for (auto f_simplex : st.filtration_simplex_range()) { @@ -119,6 +121,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_from_file) { simplex_tree_stream.close(); } +template void test_simplex_tree_contains(typeST& simplexTree, typeSimplex& simplex, int pos) { auto f_simplex = simplexTree.filtration_simplex_range().begin() + pos; @@ -135,16 +138,18 @@ void test_simplex_tree_contains(typeST& simplexTree, typeSimplex& simplex, int p } } +template void test_simplex_tree_insert_returns_true(const typePairSimplexBool& returnValue) { BOOST_CHECK(returnValue.second == true); - typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator - BOOST_CHECK(shReturned != typeST::Simplex_handle(NULL)); + typename typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator + BOOST_CHECK(shReturned != typename typeST::Simplex_handle(nullptr)); } // Global variables Filtration_value max_fil = DEFAULT_FILTRATION_VALUE; int dim_max = -1; +template void set_and_test_simplex_tree_dim_fil(typeST& simplexTree, int vectorSize, const Filtration_value& fil) { if (vectorSize > dim_max + 1) { dim_max = vectorSize - 1; @@ -173,11 +178,17 @@ void set_and_test_simplex_tree_dim_fil(typeST& simplexTree, int vectorSize, cons BOOST_CHECK(simplexTree.num_simplices() == num_simp); } -BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { +BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_variants) { + typedef std::pair typePairSimplexBool; + typedef std::vector typeVectorVertex; + typedef std::pair typeSimplex; const Filtration_value FIRST_FILTRATION_VALUE = 0.1; const Filtration_value SECOND_FILTRATION_VALUE = 0.2; const Filtration_value THIRD_FILTRATION_VALUE = 0.3; const Filtration_value FOURTH_FILTRATION_VALUE = 0.4; + // reset since we run the test several times + dim_max = -1; + max_fil = DEFAULT_FILTRATION_VALUE; // TEST OF INSERTION std::cout << "********************************************************************" << std::endl; @@ -191,7 +202,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex firstSimplex = std::make_pair(firstSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE)); typePairSimplexBool returnValue = st.insert_simplex(firstSimplex.first, firstSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, firstSimplexVector.size(), firstSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 1); @@ -202,7 +213,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex secondSimplex = std::make_pair(secondSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE)); returnValue = st.insert_simplex(secondSimplex.first, secondSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, secondSimplexVector.size(), secondSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 2); @@ -213,7 +224,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex thirdSimplex = std::make_pair(thirdSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE)); returnValue = st.insert_simplex(thirdSimplex.first, thirdSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, thirdSimplexVector.size(), thirdSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 2); // Not incremented !! @@ -224,7 +235,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex fourthSimplex = std::make_pair(fourthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE)); returnValue = st.insert_simplex(fourthSimplex.first, fourthSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, fourthSimplexVector.size(), fourthSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 3); @@ -235,7 +246,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex fifthSimplex = std::make_pair(fifthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE)); returnValue = st.insert_simplex(fifthSimplex.first, fifthSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, fifthSimplexVector.size(), fifthSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !! @@ -246,7 +257,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex sixthSimplex = std::make_pair(sixthSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE)); returnValue = st.insert_simplex(sixthSimplex.first, sixthSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, sixthSimplexVector.size(), sixthSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !! @@ -257,7 +268,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex seventhSimplex = std::make_pair(seventhSimplexVector, Filtration_value(THIRD_FILTRATION_VALUE)); returnValue = st.insert_simplex(seventhSimplex.first, seventhSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, seventhSimplexVector.size(), seventhSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 3); // Not incremented !! @@ -268,7 +279,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex eighthSimplex = std::make_pair(eighthSimplexVector, Filtration_value(FIRST_FILTRATION_VALUE)); returnValue = st.insert_simplex(eighthSimplex.first, eighthSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, eighthSimplexVector.size(), eighthSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 4); @@ -279,7 +290,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { typeSimplex ninethSimplex = std::make_pair(ninethSimplexVector, Filtration_value(SECOND_FILTRATION_VALUE)); returnValue = st.insert_simplex(ninethSimplex.first, ninethSimplex.second); - test_simplex_tree_insert_returns_true(returnValue); + test_simplex_tree_insert_returns_true(returnValue); set_and_test_simplex_tree_dim_fil(st, ninethSimplexVector.size(), ninethSimplex.second); BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! @@ -292,8 +303,8 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { returnValue = st.insert_simplex(tenthSimplex.first, tenthSimplex.second); BOOST_CHECK(returnValue.second == false); - typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator - BOOST_CHECK(shReturned == typeST::Simplex_handle(NULL)); + typename typeST::Simplex_handle shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator + BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr)); BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! BOOST_CHECK(st.dimension() == dim_max); BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil)); @@ -307,7 +318,7 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { BOOST_CHECK(returnValue.second == false); shReturned = returnValue.first; // Simplex_handle = boost::container::flat_map< Vertex_handle, Node >::iterator - BOOST_CHECK(shReturned == typeST::Simplex_handle(NULL)); + BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr)); BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !! BOOST_CHECK(st.dimension() == dim_max); BOOST_CHECK(AreAlmostTheSame(st.filtration(), max_fil)); @@ -362,9 +373,10 @@ BOOST_AUTO_TEST_CASE(simplex_tree_insertion) { } -bool sort_in_decr_order (Vertex_handle i,Vertex_handle j) { return (i>j); } - -BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { +BOOST_AUTO_TEST_CASE_TEMPLATE(NSimplexAndSubfaces_tree_insertion, typeST, list_of_tested_variants) { + typedef std::pair typePairSimplexBool; + typedef std::vector typeVectorVertex; + typedef std::pair typeSimplex; std::cout << "********************************************************************" << std::endl; std::cout << "TEST OF RECURSIVE INSERTION" << std::endl; typeST st; @@ -382,7 +394,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Check it is well inserted BOOST_CHECK(true == returnValue.second); position = 0; - std::sort(SimplexVector1.begin(), SimplexVector1.end(), sort_in_decr_order); + std::sort(SimplexVector1.begin(), SimplexVector1.end(), std::greater()); for (auto vertex : st.simplex_vertex_range(returnValue.first)) { // Check returned Simplex_handle std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector1[position] << std::endl; @@ -401,7 +413,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Check it is well inserted BOOST_CHECK(true == returnValue.second); position = 0; - std::sort(SimplexVector2.begin(), SimplexVector2.end(), sort_in_decr_order); + std::sort(SimplexVector2.begin(), SimplexVector2.end(), std::greater()); for (auto vertex : st.simplex_vertex_range(returnValue.first)) { // Check returned Simplex_handle std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector2[position] << std::endl; @@ -420,7 +432,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Check it is well inserted BOOST_CHECK(true == returnValue.second); position = 0; - std::sort(SimplexVector3.begin(), SimplexVector3.end(), sort_in_decr_order); + std::sort(SimplexVector3.begin(), SimplexVector3.end(), std::greater()); for (auto vertex : st.simplex_vertex_range(returnValue.first)) { // Check returned Simplex_handle std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector3[position] << std::endl; @@ -450,7 +462,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Check it is well inserted BOOST_CHECK(true == returnValue.second); position = 0; - std::sort(SimplexVector5.begin(), SimplexVector5.end(), sort_in_decr_order); + std::sort(SimplexVector5.begin(), SimplexVector5.end(), std::greater()); for (auto vertex : st.simplex_vertex_range(returnValue.first)) { // Check returned Simplex_handle std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector5[position] << std::endl; @@ -469,7 +481,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Check it is well inserted BOOST_CHECK(true == returnValue.second); position = 0; - std::sort(SimplexVector6.begin(), SimplexVector6.end(), sort_in_decr_order); + std::sort(SimplexVector6.begin(), SimplexVector6.end(), std::greater()); for (auto vertex : st.simplex_vertex_range(returnValue.first)) { // Check returned Simplex_handle std::cout << "vertex = " << vertex << " | vector[" << position << "] = " << SimplexVector6[position] << std::endl; @@ -509,7 +521,7 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { // Find in the simplex_tree // ------------------------------------------------------------------------------------------------------------------ typeVectorVertex simpleSimplexVector{1}; - typeST::Simplex_handle simplexFound = st.find(simpleSimplexVector); + typename typeST::Simplex_handle simplexFound = st.find(simpleSimplexVector); std::cout << "**************IS THE SIMPLEX {1} IN THE SIMPLEX TREE ?\n"; if (simplexFound != st.null_simplex()) std::cout << "***+ YES IT IS!\n"; @@ -570,14 +582,15 @@ BOOST_AUTO_TEST_CASE(NSimplexAndSubfaces_tree_insertion) { } } -void test_cofaces(typeST& st, std::vector expected, int dim, std::vector res) { - typeST::Cofaces_simplex_range cofaces; +template +void test_cofaces(typeST& st, const std::vector& expected, int dim, const std::vector& res) { + typename typeST::Cofaces_simplex_range cofaces; if (dim == 0) cofaces = st.star_simplex_range(st.find(expected)); else cofaces = st.cofaces_simplex_range(st.find(expected), dim); for (auto simplex = cofaces.begin(); simplex != cofaces.end(); ++simplex) { - typeST::Simplex_vertex_range rg = st.simplex_vertex_range(*simplex); + typename typeST::Simplex_vertex_range rg = st.simplex_vertex_range(*simplex); for (auto vertex = rg.begin(); vertex != rg.end(); ++vertex) { std::cout << "(" << *vertex << ")"; } @@ -586,7 +599,8 @@ void test_cofaces(typeST& st, std::vector expected, int dim, std: } } -BOOST_AUTO_TEST_CASE(coface_on_simplex_tree) { +BOOST_AUTO_TEST_CASE_TEMPLATE(coface_on_simplex_tree, typeST, list_of_tested_variants) { + typedef std::vector typeVectorVertex; std::cout << "********************************************************************" << std::endl; std::cout << "TEST COFACE ALGORITHM" << std::endl; typeST st; @@ -616,7 +630,7 @@ BOOST_AUTO_TEST_CASE(coface_on_simplex_tree) { st.set_dimension(3); std::vector simplex_result; - std::vector result; + std::vector result; std::cout << "First test - Star of (3):" << std::endl; simplex_result = {3}; @@ -684,7 +698,8 @@ BOOST_AUTO_TEST_CASE(coface_on_simplex_tree) { } -BOOST_AUTO_TEST_CASE(copy_move_on_simplex_tree) { +BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_variants) { + typedef std::vector typeVectorVertex; std::cout << "********************************************************************" << std::endl; std::cout << "TEST COPY MOVE CONSTRUCTORS" << std::endl; typeST st; -- cgit v1.2.3 From eecc6eef3ca893894c885eed6e7fb5861cea074b Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 9 Nov 2015 20:02:44 +0000 Subject: Specific test for non-contiguous vertices. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@898 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5295613117e6a66147dec38327b437bcf5b253c3 --- src/Simplex_tree/test/simplex_tree_unit_test.cpp | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src') diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp index beb3dc11..874c3363 100644 --- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp +++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp @@ -759,3 +759,39 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_ std::cout << "Printing st once again- address = " << &st << std::endl; } + +template +void test_simplex_is_vertex(typeST& st, typename typeST::Simplex_handle sh, typename typeST::Vertex_handle v) { + BOOST_CHECK(st.dimension(sh) == 0); + auto&& r = st.simplex_vertex_range(sh); + auto i = std::begin(r); + BOOST_CHECK(*i == v); + BOOST_CHECK(++i == std::end(r)); +} + +BOOST_AUTO_TEST_CASE(non_contiguous) { + typedef Simplex_tree<> typeST; + typedef typeST::Vertex_handle Vertex_handle; + typedef typeST::Simplex_handle Simplex_handle; + std::cout << "********************************************************************" << std::endl; + std::cout << "TEST NON-CONTIGUOUS VERTICES" << std::endl; + typeST st; + Vertex_handle e[] = {3,-7}; + std::cout << "Insert" << std::endl; + st.insert_simplex_and_subfaces(e); + BOOST_CHECK(st.num_vertices() == 2); + BOOST_CHECK(st.num_simplices() == 3); + std::cout << "Find" << std::endl; + Simplex_handle sh = st.find(e); + BOOST_CHECK(sh != st.null_simplex()); + std::cout << "Endpoints" << std::endl; + auto p = st.endpoints(sh); + test_simplex_is_vertex(st, p.first, 3); + test_simplex_is_vertex(st, p.second, -7); + std::cout << "Boundary" << std::endl; + auto&& b = st.boundary_simplex_range(sh); + auto i = std::begin(b); + test_simplex_is_vertex(st, *i, -7); + test_simplex_is_vertex(st, *++i, 3); + BOOST_CHECK(++i == std::end(b)); +} -- cgit v1.2.3 From 416b251a88afb83d05d4fb891863e8b99afdab2b Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 10 Nov 2015 16:30:43 +0000 Subject: Use Simplex_tree_options_fast_persistence in one more place. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/contiguous_vertices@899 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b22785182c0140dd36d1a4876c240aa4deabef75 --- src/Persistent_cohomology/example/alpha_shapes_persistence.cpp | 7 ++++--- src/Persistent_cohomology/example/persistence_from_file.cpp | 2 +- src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp b/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp index 6d5eebcf..92c0b065 100644 --- a/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp +++ b/src/Persistent_cohomology/example/alpha_shapes_persistence.cpp @@ -66,7 +66,8 @@ typedef Alpha_shape_3::Edge Edge_3; typedef std::list Vertex_list; // gudhi type definition -typedef Simplex_tree<>::Vertex_handle Simplex_tree_vertex; +typedef Simplex_tree ST; +typedef ST::Vertex_handle Simplex_tree_vertex; typedef std::map Alpha_shape_simplex_tree_map; typedef std::pair Alpha_shape_simplex_tree_pair; typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex; @@ -184,7 +185,7 @@ int main(int argc, char * const argv[]) { // Loop on objects vector Vertex_list vertex_list; - Simplex_tree<> simplex_tree; + ST simplex_tree; Alpha_shape_simplex_tree_map map_cgal_simplex_tree; std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); int dim_max = 0; @@ -281,7 +282,7 @@ int main(int argc, char * const argv[]) { std::cout << "Simplex_tree dim: " << simplex_tree.dimension() << std::endl; // Compute the persistence diagram of the complex - Persistent_cohomology< Simplex_tree<>, Field_Zp > pcoh(simplex_tree); + Persistent_cohomology< ST, Field_Zp > pcoh(simplex_tree); // initializes the coefficient field for homology pcoh.init_coefficients(coeff_field_characteristic); diff --git a/src/Persistent_cohomology/example/persistence_from_file.cpp b/src/Persistent_cohomology/example/persistence_from_file.cpp index 8eb8d0f3..67235467 100644 --- a/src/Persistent_cohomology/example/persistence_from_file.cpp +++ b/src/Persistent_cohomology/example/persistence_from_file.cpp @@ -54,7 +54,7 @@ int main(int argc, char * argv[]) { << std::endl; std::cout << " - p=" << p << " - min_persistence=" << min_persistence << std::endl; - // Construct the Rips complex in a Simplex Tree + // Read the list of simplices from a file. Simplex_tree<> simplex_tree; std::ifstream simplex_tree_stream(simplex_tree_file); diff --git a/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp b/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp index 45efe3ed..49d358ab 100644 --- a/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp +++ b/src/Simplex_tree/example/simplex_tree_from_alpha_shapes_3.cpp @@ -62,7 +62,8 @@ typedef Alpha_shape_3::Edge Edge; typedef std::list Vertex_list; // gudhi type definition -typedef Gudhi::Simplex_tree<>::Vertex_handle Simplex_tree_vertex; +typedef Gudhi::Simplex_tree<> Simplex_tree; +typedef Simplex_tree::Vertex_handle Simplex_tree_vertex; typedef std::map Alpha_shape_simplex_tree_map; typedef std::pair Alpha_shape_simplex_tree_pair; typedef std::vector< Simplex_tree_vertex > Simplex_tree_vector_vertex; @@ -161,7 +162,7 @@ int main(int argc, char * const argv[]) { // Loop on objects vector Vertex_list vertex_list; - Gudhi::Simplex_tree<> simplex_tree; + Simplex_tree simplex_tree; Alpha_shape_simplex_tree_map map_cgal_simplex_tree; std::vector::iterator the_alpha_value_iterator = the_alpha_values.begin(); for (auto object_iterator : the_objects) { -- cgit v1.2.3 From 6f73317041162da6dcc8bc5f52ca62a560b12ec4 Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 10 Nov 2015 16:37:17 +0000 Subject: Update a comment in plain_homology. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@901 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9a04cd581e4b4a2ea26c474ec0928a67b990dc98 --- src/Persistent_cohomology/example/plain_homology.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp index e293e013..0a692717 100644 --- a/src/Persistent_cohomology/example/plain_homology.cpp +++ b/src/Persistent_cohomology/example/plain_homology.cpp @@ -27,6 +27,10 @@ using namespace Gudhi; +/* We could perfectly well use the default Simplex_tree<> (which uses + * Simplex_tree_options_full_featured), the following simply demonstrates + * how to save on storage by not storing a filtration value. */ + struct MyOptions : Simplex_tree_options_full_featured { // Implicitly use 0 as filtration value for all simplices static const bool store_filtration = false; -- cgit v1.2.3 From e8941294bae84a6185860425177ba8237068dcf4 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 11 Nov 2015 17:00:19 +0000 Subject: Allow st.find({1,2,3}) on good compilers. That includes VS 2015 but not 2013, however I believe it will just ignore the change so it should not hurt. (I'll revert otherwise) git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@904 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8f29072c7f5bfa24de5033ada6b377deaf0c8689 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 4c6a95e8..ea61fa2e 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -39,6 +39,7 @@ #include #include #include // for greater<> +#include namespace Gudhi { @@ -531,7 +532,7 @@ class Simplex_tree { * The type InputVertexRange must be a range of Vertex_handle * on which we can call std::begin() function */ - template + template> Simplex_handle find(const InputVertexRange & s) { auto first = std::begin(s); auto last = std::end(s); @@ -625,7 +626,7 @@ class Simplex_tree { * * The type InputVertexRange must be a range for which .begin() and * .end() return input iterators, with 'value_type' Vertex_handle. */ - template + template> std::pair insert_simplex(const InputVertexRange & simplex, Filtration_value filtration = 0) { auto first = std::begin(simplex); @@ -654,7 +655,7 @@ class Simplex_tree { * output pair to the Simplex_handle of the simplex. Otherwise, we set the Simplex_handle part to * null_simplex. */ - template + template> std::pair insert_simplex_and_subfaces(const InputVertexRange& Nsimplex, Filtration_value filtration = 0) { auto first = std::begin(Nsimplex); -- cgit v1.2.3 From 340944d185b9c02f93400e2ff6bf764a5c027e91 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 11 Nov 2015 21:20:28 +0000 Subject: Make annotations_in_boundary a vector, sorted once after construction, with entries sharing the same annotation accumulated as we go. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@907 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 68351e5d61b1e3eb0b2d6c3623d7d213da9371d4 --- .../include/gudhi/Persistent_cohomology.h | 33 ++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index d096792f..3875afc6 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -431,9 +431,13 @@ class Persistent_cohomology { std::map & map_a_ds, Simplex_handle sigma, int dim_sigma) { // traverses the boundary of sigma, keeps track of the annotation vectors, - // with multiplicity, in a map. - std::map annotations_in_boundary; - std::pair::iterator, bool> result_insert_bound; + // with multiplicity. +#if 0 + std::vector> annotations_in_boundary; +#else + static std::vector> annotations_in_boundary; + annotations_in_boundary.clear(); +#endif int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the // alternate sum in the boundary. Simplex_key key; @@ -445,22 +449,29 @@ class Persistent_cohomology { // Find its annotation vector curr_col = ds_repr_[dsets_.find_set(key)]; if (curr_col != NULL) { // and insert it in annotations_in_boundary with multyiplicative factor "sign". - result_insert_bound = annotations_in_boundary.insert(std::pair(curr_col, sign)); - if (!(result_insert_bound.second)) { - result_insert_bound.first->second += sign; - } + annotations_in_boundary.emplace_back(curr_col, sign); } } sign = -sign; } + std::sort(annotations_in_boundary.begin(),annotations_in_boundary.end(),[](auto&a,auto&b){return a.first // to represent a sparse vector. std::pair::iterator, bool> result_insert_a_ds; - for (auto ann_ref : annotations_in_boundary) { - if (ann_ref.second != coeff_field_.additive_identity()) { // For all columns in the boundary, - for (auto cell_ref : ann_ref.first->col_) { // insert every cell in map_a_ds with multiplicity - Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, ann_ref.second); // coefficient * multiplicity + auto ann_it = annotations_in_boundary.begin(); + while (ann_it != annotations_in_boundary.end()) { + auto col = ann_it->first; + int coef = ann_it->second; + for (;;) { + if (++ann_it == annotations_in_boundary.end() || ann_it->first != col) + break; + coef += ann_it->second; + } + // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0. + if (coef != coeff_field_.additive_identity()) { // For all columns in the boundary, + for (auto cell_ref : col->col_) { // insert every cell in map_a_ds with multiplicity + Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, coef); // coefficient * multiplicity if (w_y != coeff_field_.additive_identity()) { // if != 0 result_insert_a_ds = map_a_ds.insert(std::pair(cell_ref.key_, w_y)); -- cgit v1.2.3 From 484f3f7f57946d0a82b18c78f954a836dc4e1d57 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 11 Nov 2015 21:24:18 +0000 Subject: Revert the last commit, this was supposed to go to a branch. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@908 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 66d468165b97b852fbe897bea212c85ac9fb0e14 --- .../include/gudhi/Persistent_cohomology.h | 33 ++++++++-------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 3875afc6..d096792f 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -431,13 +431,9 @@ class Persistent_cohomology { std::map & map_a_ds, Simplex_handle sigma, int dim_sigma) { // traverses the boundary of sigma, keeps track of the annotation vectors, - // with multiplicity. -#if 0 - std::vector> annotations_in_boundary; -#else - static std::vector> annotations_in_boundary; - annotations_in_boundary.clear(); -#endif + // with multiplicity, in a map. + std::map annotations_in_boundary; + std::pair::iterator, bool> result_insert_bound; int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the // alternate sum in the boundary. Simplex_key key; @@ -449,29 +445,22 @@ class Persistent_cohomology { // Find its annotation vector curr_col = ds_repr_[dsets_.find_set(key)]; if (curr_col != NULL) { // and insert it in annotations_in_boundary with multyiplicative factor "sign". - annotations_in_boundary.emplace_back(curr_col, sign); + result_insert_bound = annotations_in_boundary.insert(std::pair(curr_col, sign)); + if (!(result_insert_bound.second)) { + result_insert_bound.first->second += sign; + } } } sign = -sign; } - std::sort(annotations_in_boundary.begin(),annotations_in_boundary.end(),[](auto&a,auto&b){return a.first // to represent a sparse vector. std::pair::iterator, bool> result_insert_a_ds; - auto ann_it = annotations_in_boundary.begin(); - while (ann_it != annotations_in_boundary.end()) { - auto col = ann_it->first; - int coef = ann_it->second; - for (;;) { - if (++ann_it == annotations_in_boundary.end() || ann_it->first != col) - break; - coef += ann_it->second; - } - // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0. - if (coef != coeff_field_.additive_identity()) { // For all columns in the boundary, - for (auto cell_ref : col->col_) { // insert every cell in map_a_ds with multiplicity - Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, coef); // coefficient * multiplicity + for (auto ann_ref : annotations_in_boundary) { + if (ann_ref.second != coeff_field_.additive_identity()) { // For all columns in the boundary, + for (auto cell_ref : ann_ref.first->col_) { // insert every cell in map_a_ds with multiplicity + Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, ann_ref.second); // coefficient * multiplicity if (w_y != coeff_field_.additive_identity()) { // if != 0 result_insert_a_ds = map_a_ds.insert(std::pair(cell_ref.key_, w_y)); -- cgit v1.2.3 From fc91de9f736c13f38d096fc1da78c688e7992fe7 Mon Sep 17 00:00:00 2001 From: glisse Date: Wed, 11 Nov 2015 21:25:38 +0000 Subject: Make annotations_in_boundary a vector, sorted once after construction, with entries sharing the same annotation accumulated as we go. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/annotations_in_boundary@909 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 34b2ae74dc017c18a90e08caee6f707b6b0d4cc2 --- .../include/gudhi/Persistent_cohomology.h | 33 ++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index d096792f..3875afc6 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -431,9 +431,13 @@ class Persistent_cohomology { std::map & map_a_ds, Simplex_handle sigma, int dim_sigma) { // traverses the boundary of sigma, keeps track of the annotation vectors, - // with multiplicity, in a map. - std::map annotations_in_boundary; - std::pair::iterator, bool> result_insert_bound; + // with multiplicity. +#if 0 + std::vector> annotations_in_boundary; +#else + static std::vector> annotations_in_boundary; + annotations_in_boundary.clear(); +#endif int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the // alternate sum in the boundary. Simplex_key key; @@ -445,22 +449,29 @@ class Persistent_cohomology { // Find its annotation vector curr_col = ds_repr_[dsets_.find_set(key)]; if (curr_col != NULL) { // and insert it in annotations_in_boundary with multyiplicative factor "sign". - result_insert_bound = annotations_in_boundary.insert(std::pair(curr_col, sign)); - if (!(result_insert_bound.second)) { - result_insert_bound.first->second += sign; - } + annotations_in_boundary.emplace_back(curr_col, sign); } } sign = -sign; } + std::sort(annotations_in_boundary.begin(),annotations_in_boundary.end(),[](auto&a,auto&b){return a.first // to represent a sparse vector. std::pair::iterator, bool> result_insert_a_ds; - for (auto ann_ref : annotations_in_boundary) { - if (ann_ref.second != coeff_field_.additive_identity()) { // For all columns in the boundary, - for (auto cell_ref : ann_ref.first->col_) { // insert every cell in map_a_ds with multiplicity - Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, ann_ref.second); // coefficient * multiplicity + auto ann_it = annotations_in_boundary.begin(); + while (ann_it != annotations_in_boundary.end()) { + auto col = ann_it->first; + int coef = ann_it->second; + for (;;) { + if (++ann_it == annotations_in_boundary.end() || ann_it->first != col) + break; + coef += ann_it->second; + } + // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0. + if (coef != coeff_field_.additive_identity()) { // For all columns in the boundary, + for (auto cell_ref : col->col_) { // insert every cell in map_a_ds with multiplicity + Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, coef); // coefficient * multiplicity if (w_y != coeff_field_.additive_identity()) { // if != 0 result_insert_a_ds = map_a_ds.insert(std::pair(cell_ref.key_, w_y)); -- cgit v1.2.3 From ccf7f9e5b8840f57c68dec83e2153c3cc5804b61 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 13 Nov 2015 20:07:20 +0000 Subject: Clean-up. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/annotations_in_boundary@912 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f5652acf2ed5eb6f11428d2907963b5d1a1359be --- .../include/gudhi/Persistent_cohomology.h | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 3875afc6..2d6a85c1 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -431,13 +431,14 @@ class Persistent_cohomology { std::map & map_a_ds, Simplex_handle sigma, int dim_sigma) { // traverses the boundary of sigma, keeps track of the annotation vectors, - // with multiplicity. -#if 0 - std::vector> annotations_in_boundary; -#else - static std::vector> annotations_in_boundary; - annotations_in_boundary.clear(); -#endif + // with multiplicity. We used to sum the coefficients directly in + // annotations_in_boundary by using a map, we now do it later. + typedef std::pair annotation_t; + std::vector annotations_in_boundary; + /* A small speed boost is possible with the following non-thread-safe: + static std::vector> annotations_in_boundary; + annotations_in_boundary.clear(); + */ int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the // alternate sum in the boundary. Simplex_key key; @@ -454,18 +455,18 @@ class Persistent_cohomology { } sign = -sign; } - std::sort(annotations_in_boundary.begin(),annotations_in_boundary.end(),[](auto&a,auto&b){return a.first // to represent a sparse vector. std::pair::iterator, bool> result_insert_a_ds; - auto ann_it = annotations_in_boundary.begin(); - while (ann_it != annotations_in_boundary.end()) { - auto col = ann_it->first; + for (auto ann_it = annotations_in_boundary.begin(); ann_it != annotations_in_boundary.end(); /**/) { + Column* col = ann_it->first; int coef = ann_it->second; - for (;;) { - if (++ann_it == annotations_in_boundary.end() || ann_it->first != col) - break; + while (++ann_it != annotations_in_boundary.end() && ann_it->first == col) { coef += ann_it->second; } // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0. -- cgit v1.2.3 From 32a6d46672102e17f7ae09fe130382aa7e487884 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 13 Nov 2015 20:14:03 +0000 Subject: Rename variable. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/annotations_in_boundary@913 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0afbcbee5739c1649d1c9b968d9f0748c7d1d219 --- src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 2d6a85c1..1d8c2ca2 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -465,14 +465,14 @@ class Persistent_cohomology { for (auto ann_it = annotations_in_boundary.begin(); ann_it != annotations_in_boundary.end(); /**/) { Column* col = ann_it->first; - int coef = ann_it->second; + int mult = ann_it->second; while (++ann_it != annotations_in_boundary.end() && ann_it->first == col) { - coef += ann_it->second; + mult += ann_it->second; } // The following test is just a heuristic, it is not required, and it is fine that is misses p == 0. - if (coef != coeff_field_.additive_identity()) { // For all columns in the boundary, + if (mult != coeff_field_.additive_identity()) { // For all columns in the boundary, for (auto cell_ref : col->col_) { // insert every cell in map_a_ds with multiplicity - Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, coef); // coefficient * multiplicity + Arith_element w_y = coeff_field_.times(cell_ref.coefficient_, mult); // coefficient * multiplicity if (w_y != coeff_field_.additive_identity()) { // if != 0 result_insert_a_ds = map_a_ds.insert(std::pair(cell_ref.key_, w_y)); -- cgit v1.2.3 From bdb1e5517822d935da93d83c8950cbbd11560698 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 13 Nov 2015 20:27:56 +0000 Subject: Using a static variable really helps. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/annotations_in_boundary@914 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 695a6f642399c2646e5a26fac20173fbd57fe160 --- src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 1d8c2ca2..609f40a2 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -434,11 +434,9 @@ class Persistent_cohomology { // with multiplicity. We used to sum the coefficients directly in // annotations_in_boundary by using a map, we now do it later. typedef std::pair annotation_t; - std::vector annotations_in_boundary; - /* A small speed boost is possible with the following non-thread-safe: - static std::vector> annotations_in_boundary; - annotations_in_boundary.clear(); - */ + // Danger: not thread-safe! + static std::vector annotations_in_boundary; + annotations_in_boundary.clear(); int sign = 1 - 2 * (dim_sigma % 2); // \in {-1,1} provides the sign in the // alternate sum in the boundary. Simplex_key key; -- cgit v1.2.3 From fe40846f6cbdf355a2b7c1f2624c5c0e023fa8bb Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 13 Nov 2015 20:47:42 +0000 Subject: Unobfuscate a multiplication. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@915 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 771fd96e47209ceee8ffa05519134f0c8069b1cf --- .../include/gudhi/Persistent_cohomology/Multi_field.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h index 0591fc95..38bc08d1 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Multi_field.h @@ -81,8 +81,7 @@ class Multi_field { // set m to primorial(bound_prime) prod_characteristics_ = 1; for (auto p : primes_) { - mpz_mul_ui(prod_characteristics_.get_mpz_t(), - prod_characteristics_.get_mpz_t(), p); + prod_characteristics_ *= p; } // Uvect_ -- cgit v1.2.3 From 0e156a914ecfa1e8d71a8bee49400ed66a191637 Mon Sep 17 00:00:00 2001 From: salinasd Date: Sat, 14 Nov 2015 15:21:34 +0000 Subject: skbl: correct typo in test and small renamings git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/skb_simplex_insertion_merge@918 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 543ae94051051e1a79f95192db24fcd411dbea28 --- .../example/Skeleton_blocker_link.cpp | 7 ++- .../Skeleton_blocker/Skeleton_blocker_simplex.h | 4 +- .../include/gudhi/Skeleton_blocker_complex.h | 58 +++++++++++----------- .../gudhi/Skeleton_blocker_simplifiable_complex.h | 15 ++++-- src/Skeleton_blocker/test/TestSimplifiable.cpp | 2 +- .../test/TestSkeletonBlockerComplex.cpp | 2 +- 6 files changed, 48 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp index 5c717938..5e429728 100644 --- a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp +++ b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp @@ -39,9 +39,12 @@ typedef Complex::Simplex Simplex; int main(int argc, char *argv[]) { // build a full complex with 4 vertices and 2^4-1 simplices - // Initial vertices are (0,1,2,3,4) - Simplex tetrahedron(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); + + // Create a complex with four vertices (0,1,2,3) Complex complex; + + // Add a tetrahedron to this complex + Simplex tetrahedron(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); complex.add_simplex(tetrahedron); cout << "complex:" << complex.to_string() << endl; diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h index 0d838d50..714bf23c 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simplex.h @@ -218,7 +218,7 @@ class Skeleton_blocker_simplex { } /** - * Returns the first vertex of the (oriented) simplex. + * Returns the first and smallest vertex of the simplex. * * Be careful : assumes the simplex is non-empty. */ @@ -228,7 +228,7 @@ class Skeleton_blocker_simplex { } /** - * Returns the last vertex of the (oriented) simplex. + * Returns the last and greatest vertex of the simplex. * * Be careful : assumes the simplex is non-empty. */ diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index b1995783..cf156a58 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -23,16 +23,26 @@ #ifndef SKELETON_BLOCKER_COMPLEX_H_ #define SKELETON_BLOCKER_COMPLEX_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include #include #include - #include #include #include - #include #include @@ -40,18 +50,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - namespace Gudhi { namespace skbl { @@ -182,25 +180,28 @@ class Skeleton_blocker_complex { * @details is_flag_complex indicates if the complex is a flag complex or not (to know if blockers have to be computed or not). */ template - Skeleton_blocker_complex(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end, + Skeleton_blocker_complex(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end, bool is_flag_complex = false, Visitor* visitor_ = NULL) : num_vertices_(0), num_blockers_(0), visitor(visitor_) { - add_vertex_and_edges(simplex_begin, simplex_end); + add_vertices_and_edges(simplices_begin, simplices_end); if (!is_flag_complex) // need to compute blockers - add_blockers(simplex_begin, simplex_end); + add_blockers(simplices_begin, simplices_end); } private: + /** + * Add vertices and edges of a simplex in one pass + */ template - void add_vertex_and_edges(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) { + void add_vertices_and_edges(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end) { std::vector> edges; // first pass to add vertices and edges int num_vertex = -1; - for (auto s_it = simplex_begin; s_it != simplex_end; ++s_it) { + for (auto s_it = simplices_begin; s_it != simplices_end; ++s_it) { if (s_it->dimension() == 0) num_vertex = (std::max)(num_vertex, s_it->first_vertex().vertex); if (s_it->dimension() == 1) edges.emplace_back(s_it->first_vertex(), s_it->last_vertex()); } @@ -210,9 +211,10 @@ class Skeleton_blocker_complex { add_edge_without_blockers(e.first, e.second); } + template - void add_blockers(SimpleHandleOutputIterator simplex_begin, SimpleHandleOutputIterator simplex_end) { - Tries tries(num_vertices(), simplex_begin, simplex_end); + void add_blockers(SimpleHandleOutputIterator simplices_begin, SimpleHandleOutputIterator simplices_end) { + Tries tries(num_vertices(), simplices_begin, simplices_end); tries.init_next_dimension(); auto simplices(tries.next_dimension_simplices()); @@ -378,6 +380,7 @@ class Skeleton_blocker_complex { /** * @brief Adds a vertex to the simplicial complex and returns its Vertex_handle. + * @remark Vertex representation is contiguous. */ Vertex_handle add_vertex() { Vertex_handle address(boost::add_vertex(skeleton)); @@ -1128,13 +1131,10 @@ class Skeleton_blocker_complex { void remove_star(const Simplex& sigma); /** - * @brief add a simplex. - * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge_without_blockers). - * and all vertices lower than the higher vertex of sigma must already be in the complex. - * if some edges of sigma are not in the complex, then insert_edges_of_sigma flag must be - * set to true. + * @brief add a simplex and all its faces. + * @details the simplex must have dimension greater than one (otherwise use add_vertex or add_edge_without_blockers). */ - void add_simplex(const Simplex& sigma, bool insert_edges_of_sigma = false); + void add_simplex(const Simplex& sigma); private: void add_blockers_after_simplex_insertion(Simplex s); @@ -1583,12 +1583,12 @@ class Skeleton_blocker_complex { * return the total number of simplices */ template -Complex make_complex_from_top_faces(SimplexHandleIterator simplex_begin, SimplexHandleIterator simplex_end, +Complex make_complex_from_top_faces(SimplexHandleIterator simplices_begin, SimplexHandleIterator simplices_end, bool is_flag_complex = false) { //todo use add_simplex instead! should be more efficient and more elegant :) typedef typename Complex::Simplex Simplex; std::vector simplices; - for (auto top_face = simplex_begin; top_face != simplex_end; ++top_face) { + for (auto top_face = simplices_begin; top_face != simplices_end; ++top_face) { auto subfaces_topface = subfaces(*top_face); simplices.insert(simplices.end(), subfaces_topface.begin(), subfaces_topface.end()); } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h index 79a7ed79..1b7d58ff 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h @@ -206,21 +206,26 @@ void Skeleton_blocker_complex::remove_star(const Simplex& sig } template -void Skeleton_blocker_complex::add_simplex(const Simplex& sigma, bool insert_edges_of_sigma) { +void Skeleton_blocker_complex::add_simplex(const Simplex& sigma) { // to add a simplex s, all blockers included in s are first removed // and then all simplex in the coboundary of s are added as blockers assert(!this->contains(sigma)); assert(sigma.dimension() > 1); + if (!contains_vertices(sigma)) { + std::cerr << "add_simplex: Some vertices were not present in the complex, adding them" << std::endl; + size_t num_vertices_to_add = sigma.last_vertex() - this->num_vertices() + 1; + for (size_t i = 0; i < num_vertices_to_add; ++i) + this->add_vertex(); + } assert(contains_vertices(sigma)); - - if(insert_edges_of_sigma) + if(!contains_edges(sigma)) add_edge(sigma); - else - assert(contains_edges(sigma)); remove_blocker_include_in_simplex(sigma); add_blockers_after_simplex_insertion(sigma); } + + template void Skeleton_blocker_complex::add_blockers_after_simplex_insertion(Simplex sigma){ if(sigma.dimension() < 1) return; diff --git a/src/Skeleton_blocker/test/TestSimplifiable.cpp b/src/Skeleton_blocker/test/TestSimplifiable.cpp index 76d5ba89..b0855ce9 100644 --- a/src/Skeleton_blocker/test/TestSimplifiable.cpp +++ b/src/Skeleton_blocker/test/TestSimplifiable.cpp @@ -310,7 +310,7 @@ bool test_add_simplex4() { for (int k = 0; k < n; k++) s.add_vertex(Vertex_handle(k)); s.remove_vertex(Vertex_handle(i)); - complex.add_simplex(s, true); + complex.add_simplex(s); //at step i there is only blocker 0..i if (i < 2 && complex.num_blockers() > 0) diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp index 69abd279..42482e23 100644 --- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp +++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp @@ -367,7 +367,7 @@ bool test_iterator_simplices4() { bool test_iterator_coboundary() { Complex c; build_complete(4, c); - c.remove_edge(Vertex_handle(0), Vertex_handle(2)); + c.remove_edge(Vertex_handle(1), Vertex_handle(3)); PRINT(c.to_string()); Simplex s02(Vertex_handle(0), Vertex_handle(2)); int n = 0; -- cgit v1.2.3 From b15b9c7f6f5dd232dee897c96d65f5f77e215314 Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 15 Nov 2015 10:04:32 +0000 Subject: Fix for older libstdc++. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@922 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d370bbf81488ef6b07a17d63ad43ba2b813e2210 --- src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 609f40a2..2a405830 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -455,7 +455,7 @@ class Persistent_cohomology { } // Place identical annotations consecutively so we can easily sum their multiplicities. std::sort(annotations_in_boundary.begin(), annotations_in_boundary.end(), - [](annotation_t& a, annotation_t& b) { return a.first < b.first; }); + [](annotation_t const& a, annotation_t const& b) { return a.first < b.first; }); // Sum the annotations with multiplicity, using a map // to represent a sparse vector. -- cgit v1.2.3 From c6c91153dde643af2c5b9c78a1b1b9b65349c292 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 16 Nov 2015 10:09:38 +0000 Subject: cpplint fixes before merge git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/skb_simplex_insertion_merge@923 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: de9fc0770d273730de876a6ed54646847362bc7d --- src/Contraction/example/Garland_heckbert.cpp | 14 +++--- .../example/Skeleton_blocker_link.cpp | 5 +- .../include/gudhi/Skeleton_blocker_complex.h | 58 +++++++++++----------- .../gudhi/Skeleton_blocker_simplifiable_complex.h | 29 ++++++----- 4 files changed, 53 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/Contraction/example/Garland_heckbert.cpp b/src/Contraction/example/Garland_heckbert.cpp index 681426e0..3ba9501b 100644 --- a/src/Contraction/example/Garland_heckbert.cpp +++ b/src/Contraction/example/Garland_heckbert.cpp @@ -145,13 +145,14 @@ class GH_visitor : public Gudhi::contraction::Contraction_visitor { int main(int argc, char *argv[]) { if (argc != 4) { - std::cerr << "Usage " << argv[0] << " input.off output.off N to load the file input.off, contract N edges and save the result to output.off.\n"; + std::cerr << "Usage " << argv[0] << + " input.off output.off N to load the file input.off, contract N edges and save the result to output.off.\n"; return EXIT_FAILURE; } Complex complex; typedef typename Complex::Vertex_handle Vertex_handle; - + // load the points Skeleton_blocker_off_reader off_reader(argv[1], complex); if (!off_reader.is_valid()) { @@ -159,9 +160,9 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - if(!complex.empty() && !complex.point(Vertex_handle(0)).dimension()==3) { + if (!complex.empty() && !(complex.point(Vertex_handle(0)).dimension() == 3)) { std::cerr << "Only points of dimension 3 are supported." << std::endl; - return EXIT_FAILURE; + return EXIT_FAILURE; } std::cout << "Load complex with " << complex.num_vertices() << " vertices" << std::endl; @@ -175,8 +176,7 @@ int main(int argc, char *argv[]) { new GH_cost(complex), new GH_placement(complex), contraction::make_link_valid_contraction(), - new GH_visitor(complex) - ); + new GH_visitor(complex)); std::cout << "Contract " << num_contractions << " edges" << std::endl; contractor.contract_edges(num_contractions); @@ -186,7 +186,7 @@ int main(int argc, char *argv[]) { complex.num_edges() << " edges and " << complex.num_triangles() << " triangles." << std::endl; - //write simplified complex + // write simplified complex Skeleton_blocker_off_writer off_writer(argv[2], complex); return EXIT_SUCCESS; diff --git a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp index 5e429728..698a8106 100644 --- a/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp +++ b/src/Skeleton_blocker/example/Skeleton_blocker_link.cpp @@ -39,7 +39,7 @@ typedef Complex::Simplex Simplex; int main(int argc, char *argv[]) { // build a full complex with 4 vertices and 2^4-1 simplices - + // Create a complex with four vertices (0,1,2,3) Complex complex; @@ -64,7 +64,8 @@ int main(int argc, char *argv[]) { // To access to the initial vertices eg (0,1,2,3,4), Root_vertex_handle must be used. // For instance, to test if the link contains the vertex that was labeled i: for (int i = 0; i < 5; ++i) - cout << "link.contains_vertex(Root_vertex_handle(" << i << ")):" << link.contains_vertex(Root_vertex_handle(i)) << endl; + cout << "link.contains_vertex(Root_vertex_handle(" << i << ")):" << + link.contains_vertex(Root_vertex_handle(i)) << endl; return EXIT_SUCCESS; } diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index cf156a58..6612722e 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -23,18 +23,6 @@ #ifndef SKELETON_BLOCKER_COMPLEX_H_ #define SKELETON_BLOCKER_COMPLEX_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -50,6 +38,18 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + namespace Gudhi { namespace skbl { @@ -550,13 +550,13 @@ class Skeleton_blocker_complex { * the edges 01, 12, 20 but not the triangle 012 (and hence this complex * will contains a blocker 012). */ - Edge_handle add_edge(Vertex_handle a, Vertex_handle b) { - //if the edge is already there we musnt go further - //as we may add blockers that should not be here - if(contains_edge(a,b)) - return *((*this)[std::make_pair(a,b)]); - auto res = add_edge_without_blockers(a,b); - add_blockers_after_simplex_insertion(Simplex(a,b)); + Edge_handle add_edge(Vertex_handle a, Vertex_handle b) { + // if the edge is already there we musnt go further + // as we may add blockers that should not be here + if (contains_edge(a, b)) + return *((*this)[std::make_pair(a, b)]); + auto res = add_edge_without_blockers(a, b); + add_blockers_after_simplex_insertion(Simplex(a, b)); return res; } @@ -564,9 +564,9 @@ class Skeleton_blocker_complex { * @brief Adds all edges of s in the complex. */ void add_edge(const Simplex& s) { - for(auto i = s.begin(); i != s.end(); ++i) - for(auto j = i; ++j != s.end(); /**/) - add_edge(*i,*j); + for (auto i = s.begin(); i != s.end(); ++i) + for (auto j = i; ++j != s.end(); /**/) + add_edge(*i, *j); } /** @@ -596,9 +596,9 @@ class Skeleton_blocker_complex { * @brief Adds all edges of s in the complex without adding blockers. */ void add_edge_without_blockers(Simplex s) { - for(auto i = s.begin(); i != s.end(); ++i){ - for(auto j = i; ++j != s.end(); /**/) - add_edge_without_blockers(*i,*j); + for (auto i = s.begin(); i != s.end(); ++i) { + for (auto j = i; ++j != s.end(); /**/) + add_edge_without_blockers(*i, *j); } } @@ -1014,10 +1014,10 @@ class Skeleton_blocker_complex { * @brief returns the number of simplices of a given dimension in the complex. */ size_t num_simplices(unsigned dimension) const { - //todo iterator on k-simplices + // TODO(DS): iterator on k-simplices size_t res = 0; - for(const auto& s: complex_simplex_range()) - if(s.dimension() == dimension) + for (const auto& s : complex_simplex_range()) + if (s.dimension() == dimension) ++res; return res; } @@ -1585,7 +1585,7 @@ class Skeleton_blocker_complex { template Complex make_complex_from_top_faces(SimplexHandleIterator simplices_begin, SimplexHandleIterator simplices_end, bool is_flag_complex = false) { - //todo use add_simplex instead! should be more efficient and more elegant :) + // TODO(DS): use add_simplex instead! should be more efficient and more elegant :) typedef typename Complex::Simplex Simplex; std::vector simplices; for (auto top_face = simplices_begin; top_face != simplices_end; ++top_face) { diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h index 1b7d58ff..94a125c1 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h @@ -218,7 +218,7 @@ void Skeleton_blocker_complex::add_simplex(const Simplex& sig this->add_vertex(); } assert(contains_vertices(sigma)); - if(!contains_edges(sigma)) + if (!contains_edges(sigma)) add_edge(sigma); remove_blocker_include_in_simplex(sigma); add_blockers_after_simplex_insertion(sigma); @@ -227,10 +227,10 @@ void Skeleton_blocker_complex::add_simplex(const Simplex& sig template -void Skeleton_blocker_complex::add_blockers_after_simplex_insertion(Simplex sigma){ - if(sigma.dimension() < 1) return; +void Skeleton_blocker_complex::add_blockers_after_simplex_insertion(Simplex sigma) { + if (sigma.dimension() < 1) return; - for(auto s : coboundary_range(sigma)) { + for (auto s : coboundary_range(sigma)) { this->add_blocker(s); } } @@ -254,10 +254,10 @@ void Skeleton_blocker_complex::remove_blocker_containing_simp */ template void Skeleton_blocker_complex::remove_blocker_include_in_simplex(const Simplex& sigma) { - //todo write efficiently by using only superior blockers - //eg for all s, check blockers whose vertices are all greater than s + // TODO(DS): write efficiently by using only superior blockers + // eg for all s, check blockers whose vertices are all greater than s std::set blockers_to_remove; - for(auto s : sigma) { + for (auto s : sigma) { for (auto blocker : this->blocker_range(s)) { if (sigma.contains(*blocker)) blockers_to_remove.insert(blocker); @@ -266,11 +266,11 @@ void Skeleton_blocker_complex::remove_blocker_include_in_simp for (auto blocker_to_update : blockers_to_remove) { auto s = *blocker_to_update; this->delete_blocker(blocker_to_update); - //now if there is a vertex v in the link of s - //and v is not included in sigma then v.s is a blocker - //(all faces of v.s are there since v belongs to the link of s) - for(const auto& b : coboundary_range(s)) - if(!sigma.contains(b)) + // now if there is a vertex v in the link of s + // and v is not included in sigma then v.s is a blocker + // (all faces of v.s are there since v belongs to the link of s) + for (const auto& b : coboundary_range(s)) + if (!sigma.contains(b)) this->add_blocker(b); } } @@ -384,9 +384,8 @@ Skeleton_blocker_complex::contract_edge(Vertex_handle a, Vert } template -void -Skeleton_blocker_complex::get_blockers_to_be_added_after_contraction(Vertex_handle a, Vertex_handle b, - std::set& blockers_to_add) { +void Skeleton_blocker_complex::get_blockers_to_be_added_after_contraction(Vertex_handle a, + Vertex_handle b, std::set& blockers_to_add) { blockers_to_add.clear(); typedef Skeleton_blocker_link_complex > LinkComplexType; -- cgit v1.2.3 From 91213bb50dbb53ec0257665da9a2e76ecabde2a2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 16 Nov 2015 10:40:34 +0000 Subject: Visual 2013 fix about typename not allowed. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/skb_simplex_insertion_merge@924 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 641ead33dd7c9a97dd84e085e2d131d05c6ce8fb --- src/Contraction/example/Garland_heckbert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Contraction/example/Garland_heckbert.cpp b/src/Contraction/example/Garland_heckbert.cpp index 3ba9501b..b545a066 100644 --- a/src/Contraction/example/Garland_heckbert.cpp +++ b/src/Contraction/example/Garland_heckbert.cpp @@ -151,7 +151,7 @@ int main(int argc, char *argv[]) { } Complex complex; - typedef typename Complex::Vertex_handle Vertex_handle; + typedef Complex::Vertex_handle Vertex_handle; // load the points Skeleton_blocker_off_reader off_reader(argv[1], complex); -- cgit v1.2.3 From 061e43a2a48525bc5a69482a1ea80f20ff505e55 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 20 Nov 2015 16:13:33 +0000 Subject: Bug on gudhi installation doc page git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@928 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7fb83a82e11210bce9842a80779455681d6508f3 --- src/common/doc/main_page.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index 689e7a4d..41b8ba1e 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -56,6 +56,7 @@ * The following example requires the GNU Multiple Precision Arithmetic * Library (GMP) and will not be built if GMP is not installed: * \li Persistent_cohomology/rips_multifield_persistence + * * Having GMP version 4.2 or higher installed is recommended. * * \subsection cgal CGAL: @@ -72,19 +73,15 @@ * * \subsection demos Demos and examples * To build the demos and libraries, run the following commands in a terminal: - * \verbatim - * cd /path-to-gudhi/ - * mkdir build - * cd build/ - * cmake .. - * make - * \endverbatim +\verbatim cd /path-to-gudhi/ +mkdir build +cd build/ +cmake .. +make \endverbatim * * \subsection testsuites Test suites * To test your build, run the following command in a terminal: - * \verbatim - * make test - * \endverbatim + * \verbatim make test \endverbatim * * \section Contributions Bug reports and contributions * Please help us improving the quality of the GUDHI library. You may report bugs or suggestions to: -- cgit v1.2.3 From f70e386fc98f1dbd8287d1cb7cc715710a8f751b Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 7 Dec 2015 14:35:31 +0000 Subject: Merged with trunk and removed stuff git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@933 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d417402ca5874b490f3a28f3c9b6deb4565f55fe --- src/Witness_complex/example/CMakeLists.txt | 90 ---------------------- .../example/simple_witness_complex.cpp | 2 - 2 files changed, 92 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index ff372d16..83f9c71c 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -9,93 +9,3 @@ project(GUDHIWitnessComplex) #target_link_libraries(witness_complex_from_file ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable( witness_complex_from_off witness_complex_from_off.cpp ) - - add_executable( witness_complex_from_wl_matrix witness_complex_from_wl_matrix.cpp ) - - -# An example with Simplex-tree using CGAL alpha_shapes_3 - -#find_package(Eigen3 3.1.0) -#if(GMP_FOUND AND CGAL_FOUND) -# message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") -# message("GMP_LIBRARIES = ${GMP_LIBRARIES}") -# message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") -# #message("EIGEN3_LIBRARIES = ${EIGEN3_LIBRARIES}") -# INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS}) -# INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) -# INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) -# add_executable (witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) -# target_link_libraries(witness_complex_knn_landmarks ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) -# add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) -#endif() - -# need CGAL 4.6 -# cmake -DCGAL_DIR=~/workspace/CGAL-4.6-beta1 ../../.. -if(CGAL_FOUND) - if (NOT CGAL_VERSION VERSION_LESS 4.6.0) - message(STATUS "CGAL version: ${CGAL_VERSION}.") - - include( ${CGAL_USE_FILE} ) - - find_package(Eigen3 3.1.0) - if (EIGEN3_FOUND) - message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") - include( ${EIGEN3_USE_FILE} ) - message(STATUS "Eigen3 use file: ${EIGEN3_USE_FILE}.") - include_directories (BEFORE "../../include") - - add_executable ( witness_complex_knn_landmarks witness_complex_knn_landmarks.cpp ) - target_link_libraries(witness_complex_knn_landmarks ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_knn_landmarks ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_knn_landmarks ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - #add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) - #target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - #add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - else() - message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") - endif() - else() - message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") - endif () -endif() -if(CGAL_FOUND) - if (NOT CGAL_VERSION VERSION_LESS 4.6.0) - message(STATUS "CGAL version: ${CGAL_VERSION}.") - - include( ${CGAL_USE_FILE} ) - - find_package(Eigen3 3.1.0) - if (EIGEN3_FOUND) - message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") - include( ${EIGEN3_USE_FILE} ) - include_directories (BEFORE "../../include") - add_executable ( witness_complex_perturbations witness_complex_perturbations.cpp ) - target_link_libraries(witness_complex_perturbations ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_perturbations ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_perturbations ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_flat_torus witness_complex_flat_torus.cpp ) - target_link_libraries(witness_complex_flat_torus ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_flat_torus ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_flat_torus ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_sphere witness_complex_sphere.cpp ) - target_link_libraries(witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( relaxed_witness_complex_sphere relaxed_witness_complex_sphere.cpp ) - add_test(witness_complex_sphere ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_sphere ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_protected_delaunay witness_complex_protected_delaunay.cpp ) - target_link_libraries(witness_complex_protected_delaunay ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_protected_delaunay ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_protected_delaunay ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_cubic_systems witness_complex_cubic_systems.cpp ) - target_link_libraries(witness_complex_cubic_systems ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_cubic_systems ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_cubic_systems ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_cube witness_complex_cube.cpp ) - target_link_libraries(witness_complex_cube ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_cube ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_cube ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - add_executable ( witness_complex_epsilon witness_complex_epsilon.cpp ) - target_link_libraries(witness_complex_epsilon ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) - add_test(witness_complex_epsilon ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_epsilon ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - else() - message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") - endif() - else() - message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") - endif () -endif() diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 43921c4e..e95f67a8 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -48,7 +48,5 @@ int main (int argc, char * const argv[]) typeVectorVertex witness10 = {5,0,1,3,6,2,4}; KNN.push_back(witness10); typeVectorVertex witness11 = {5,6,1,0,2,3,4}; KNN.push_back(witness11); typeVectorVertex witness12 = {1,6,0,5,2,3,4}; KNN.push_back(witness12); - std::cout << "Let the carnage begin!\n"; witnessComplex.witness_complex(KNN); - std::cout << "Howdy world!\n"; } -- cgit v1.2.3 From 9325765e94b1bd43600fe345a033216bce55873f Mon Sep 17 00:00:00 2001 From: skachano Date: Mon, 7 Dec 2015 15:00:41 +0000 Subject: Removed things from Witness_complex.h git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@935 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 00450ae8c849a35d5adc9baa3f35ef8fae1b664a --- .../include/gudhi/Witness_complex.h | 632 +-------------------- 1 file changed, 3 insertions(+), 629 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 201d6525..8316fe3e 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -39,12 +39,6 @@ #include #include -// Needed for nearest neighbours -//#include -//#include -//#include -//#include - // Needed for the adjacency graph in bad link search #include #include @@ -53,8 +47,7 @@ namespace Gudhi { - /** \addtogroup simplex_tree - * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: + /** Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. @@ -107,12 +100,8 @@ namespace Gudhi { typedef std::list< Vertex_handle > ActiveWitnessList; private: - /** Number of landmarks - */ - int nbL; - /** Desired density - */ - double density; + int nbL; // Number of landmarks + double density; // Desired density public: @@ -142,7 +131,6 @@ namespace Gudhi { std::cout << "**Start the procedure witness_complex" << std::endl; //Construction of the active witness list int nbW = knn.size(); - //int nbL = knn.at(0).size(); typeVectorVertex vv; typeSimplex simplex; typePairSimplexBool returnValue; @@ -160,60 +148,13 @@ namespace Gudhi { /* TODO Error if not inserted : normally no need here though*/ } int k=1; /* current dimension in iterative construction */ - //std::cout << "Successfully added landmarks" << std::endl; - // PRINT2 - //print_sc(root()); std::cout << std::endl; - /* - int u,v; // two extremities of an edge - int count = 0; - if (nbL > 1) // if the supposed dimension of the complex is >0 - { - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - vv = {u,v}; - returnValue = this->insert_simplex(vv,Filtration_value(0.0)); - if (returnValue.second) - count++; - //print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; - } - std::cout << "The number of edges = " << count << std::endl; - count = 0; - //print_sc(root()); - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - if ( u > v) - { - u = v; - v = knn[i][0]; - knn[i][0] = knn[i][1]; - knn[i][1] = v; - } - Simplex_handle sh; - vv = {u,v}; - //if (u==v) std::cout << "Bazzinga!\n"; - sh = (root()->find(u))->second.children()->find(v); - active_w.push_back(i); - } - } - */ for (int i=0; i != nbW; ++i) active_w.push_back(i); std::cout << "k=0, active witnesses: " << active_w.size() << std::endl; //std::cout << "Successfully added edges" << std::endl; - count_good = {0}; - count_bad = {0}; int D = knn[0].size(); while (!active_w.empty() && k < D ) { - count_good.push_back(0); - count_bad.push_back(0); //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) @@ -232,23 +173,9 @@ namespace Gudhi { active_w.erase(it++); //First increase the iterator and then erase the previous element } std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; - //std::cout << "** k=" << k << ", num_simplices: " < > WL; - // landmark_choice_by_random_points(point_vector, point_vector.size(), WL); - // witness_complex(WL); - // } private: @@ -390,9 +317,6 @@ private: template void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) { - //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - //double density = 5.; Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks typeVectorVertex chosen_landmarks; // landmark list @@ -402,7 +326,6 @@ private: double curr_dist; // used to stock the distance from the current point to L double infty = std::numeric_limits::infinity(); // infinity (see next entry) std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points - // double mindist = infty; int curr_max_w=0; // the point currently furthest from L int j; int temp_swap_int; @@ -418,30 +341,18 @@ private: { //curr_max_w at this point is the next landmark chosen_landmarks.push_back(curr_max_w); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; for (auto v: WL) v.push_back(current_number_of_landmarks); for (int i = 0; i < nbP; ++i) { - // iteration on points in W. update of distance vectors - - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - //std::cout << "The problem is not in distance function\n"; wit_land_dist[i].push_back(curr_dist); WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; if (curr_dist < dist_to_L[i]) dist_to_L[i] = curr_dist; j = current_number_of_landmarks; - //std::cout << "First half complete\n"; while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) { - // sort the closest landmark vector for every witness temp_swap_int = WL[i][j]; WL[i][j] = WL[i][j-1]; WL[i][j-1] = temp_swap_int; @@ -450,12 +361,7 @@ private: wit_land_dist[i][j-1] = temp_swap_double; --j; } - //std::cout << "result WL="; print_vvector(WL); - //std::cout << "result WLD="; print_vvector(wit_land_dist); - //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; - //std::cout << "End loop\n"; } - //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; curr_max_dist = 0; for (int i = 0; i < nbP; ++i) { if (dist_to_L[i] > curr_max_dist) @@ -464,76 +370,9 @@ private: curr_max_w = i; } } - //std::cout << "Chose " << curr_max_w << " as new landmark\n"; } - //std::cout << endl; } - /** \brief Landmark choice strategy by taking random vertices for landmarks. - * - */ - - // template - // void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - // { - // std::cout << "Enter landmark_choice_by_random_points "<< std::endl; - // //std::cout << "W="; print_vvector(W); - // std::unordered_set< int > chosen_landmarks; // landmark set - - // Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - - // WL = KNearestNeighbours(nbP,std::vector()); - // int current_number_of_landmarks=0; // counter for landmarks - - // srand(24660); - // int chosen_landmark = rand()%nbP; - // double curr_dist; - - // //int j; - // //int temp_swap_int; - // //double temp_swap_double; - - - // for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - // { - // while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) - // { - // srand((int)clock()); - // chosen_landmark = rand()% nbP; - // //std::cout << chosen_landmark << "\n"; - // } - // chosen_landmarks.insert(chosen_landmark); - // //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - // //std::cout << "WL="; print_vvector(WL); - // //std::cout << "WLD="; print_vvector(wit_land_dist); - // //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - // for (auto v: WL) - // v.push_back(current_number_of_landmarks); - // for (int i = 0; i < nbP; ++i) - // { - // // iteration on points in W. update of distance vectors - - // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - // //std::cout << "The problem is not in distance function\n"; - // wit_land_dist[i].push_back(curr_dist); - // WL[i].push_back(current_number_of_landmarks); - // //std::cout << "Push't back\n"; - // //j = current_number_of_landmarks; - // //std::cout << "First half complete\n"; - // //std::cout << "result WL="; print_vvector(WL); - // //std::cout << "result WLD="; print_vvector(wit_land_dist); - // //std::cout << "End loop\n"; - // } - // } - // for (int i = 0; i < nbP; i++) - // { - // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); - // } - // //std::cout << endl; - // } - /** \brief Landmark choice strategy by taking random vertices for landmarks. * */ @@ -541,59 +380,19 @@ private: // template void landmark_choice_by_random_points(Point_Vector &W, int nbP, std::set &L) { - std::cout << "Enter landmark_choice_by_random_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - //std::unordered_set< int > chosen_landmarks; // landmark set - - //Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - - //WL = KNearestNeighbours(nbP,std::vector()); int current_number_of_landmarks=0; // counter for landmarks srand(24660); int chosen_landmark = rand()%nbP; - //double curr_dist; - //int j; - //int temp_swap_int; - //double temp_swap_double; for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) { while (L.find(chosen_landmark) != L.end()) { srand((int)clock()); chosen_landmark = rand()% nbP; - //std::cout << chosen_landmark << "\n"; } L.insert(chosen_landmark); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - // for (auto v: WL) - // v.push_back(current_number_of_landmarks); - // for (int i = 0; i < nbP; ++i) - // { - // // iteration on points in W. update of distance vectors - - // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - // //std::cout << "The problem is not in distance function\n"; - // wit_land_dist[i].push_back(curr_dist); - // WL[i].push_back(current_number_of_landmarks); - // //std::cout << "Push't back\n"; - // //j = current_number_of_landmarks; - // //std::cout << "First half complete\n"; - // //std::cout << "result WL="; print_vvector(WL); - // //std::cout << "result WLD="; print_vvector(wit_land_dist); - // //std::cout << "End loop\n"; - // } } - // for (int i = 0; i < nbP; i++) - // { - // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); - // } - //std::cout << endl; } @@ -610,7 +409,6 @@ private: typedef bool (*comp)(dist_i,dist_i); for (int W_i = 0; W_i < nbP; W_i++) { - //std::cout << "<<<<<<<<<<<<<<" << W_i <<"\n"; std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); std::set::iterator L_it; int L_i; @@ -623,437 +421,13 @@ private: { dist_i dist = l_heap.top(); WL[W_i].push_back(dist.second); - //WL[W_i].insert(WL[W_i].begin(),dist.second); - //std::cout << dist.first << " " << dist.second << std::endl; l_heap.pop(); } } } - /** \brief Returns true if the link is good - */ - bool has_good_link(Vertex_handle v, std::vector< int >& bad_count, std::vector< int >& good_count) - { - std::vector< Vertex_handle > star_vertices; - // Fill star_vertices - star_vertices.push_back(v); - for (auto u: complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u != v && find(edge) != null_simplex()) - star_vertices.push_back(u); - } - // Find the dimension - typeVectorVertex init_simplex = {star_vertices[0]}; - bool is_pure = true; - std::vector dim_coface(star_vertices.size(), 1); - int d = star_dim(star_vertices, star_vertices.begin()+1, 0, init_simplex, dim_coface.begin()+1) - 1; //link_dim = star_dim - 1 - assert(init_simplex.size() == 1); - if (!is_pure) - std::cout << "Found an impure star around " << v << "\n"; - for (int dc: dim_coface) - is_pure = (dc == dim_coface[0]); - /* - if (d == count_good.size()) - { - std::cout << "Found a star of dimension " << (d+1) << " around " << v << "\nThe star is "; - print_vector(star_vertices); std::cout << std::endl; - } - */ - //if (d == -1) bad_count[0]++; - bool b= (is_pure && link_is_pseudomanifold(star_vertices,d)); - if (d != -1) {if (b) good_count[d]++; else bad_count[d]++;} - if (!is_pure) bad_count[0]++; - return (d != -1 && b && is_pure); - - } - - /** \brief Search and output links around vertices that are not pseudomanifolds - * - */ - /* - void write_bad_links(std::ofstream& out_file) - { - out_file << "Bad links list\n"; - std::cout << "Entered write_bad_links\n"; - for (auto v: complex_vertex_range()) - { - std::cout << "Vertex " << v << ": "; - std::vector< Vertex_handle > link_vertices; - // Fill link_vertices - for (auto u: complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u != v && find(edge) != null_simplex()) - link_vertices.push_back(u); - } - - print_vector(link_vertices); - std::cout << "\n"; - - // Find the dimension - typeVectorVertex empty_simplex = {}; - int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); - if (link_is_pseudomanifold(link_vertices,d)) - count_good[d]++; - } - nc = nbL; - for (unsigned int i = 0; i != count_good.size(); i++) - { - out_file << "count_good[" << i << "] = " << count_good[i] << std::endl; - nc -= count_good[i]; - if (count_good[i] != 0) - std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; - } - for (unsigned int i = 0; i != count_bad.size(); i++) - { - out_file << "count_bad[" << i << "] = " << count_bad[i] << std::endl; - nc -= count_bad[i]; - if (count_bad[i] != 0) - std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; - } - std::cout << "not_connected = " << nc << std::endl; - } - */ - private: - - std::vector count_good; - std::vector count_bad; - int nc; - - int star_dim(std::vector< Vertex_handle >& star_vertices, - typename std::vector< Vertex_handle >::iterator curr_v, - int curr_d, - typeVectorVertex& curr_simplex, - typename std::vector< int >::iterator curr_dc) - { - //std::cout << "Entered star_dim for " << *(curr_v-1) << "\n"; - Simplex_handle sh; - int final_d = curr_d; - typename std::vector< Vertex_handle >::iterator it; - typename std::vector< Vertex_handle >::iterator dc_it; - //std::cout << "Current vertex is " << - for (it = curr_v, dc_it = curr_dc; it != star_vertices.end(); ++it, ++dc_it) - { - curr_simplex.push_back(*it); - typeVectorVertex curr_simplex_copy(curr_simplex); - /* - std::cout << "Searching for "; - print_vector(curr_simplex); - std::cout << " curr_dim " << curr_d << " final_dim " << final_d; - */ - sh = find(curr_simplex_copy); //Need a copy because find sorts the vector and I want star center to be the first - if (sh != null_simplex()) - { - //std::cout << " -> " << *it << "\n"; - int d = star_dim(star_vertices, it+1, curr_d+1, curr_simplex, dc_it); - if (d >= final_d) - { - final_d = d; - //std::cout << d << " "; - //print_vector(curr_simplex); - //std::cout << std::endl; - } - if (d >= *dc_it) - *dc_it = d; - } - /* - else - std::cout << "\n"; - */ - curr_simplex.pop_back(); - } - return final_d; - } - - // color is false is a (d-1)-dim face, true is a d-dim face - //typedef bool Color; - // graph is an adjacency list - typedef typename boost::adjacency_list Adj_graph; - // map that gives to a certain simplex its node in graph and its dimension - //typedef std::pair Reference; - typedef boost::graph_traits::vertex_descriptor Vertex_t; - typedef boost::graph_traits::edge_descriptor Edge_t; - typedef boost::graph_traits::adjacency_iterator Adj_it; - typedef std::pair Out_edge_it; - - typedef boost::container::flat_map Graph_map; - typedef boost::container::flat_map Inv_graph_map; - - /* \brief Verifies if the simplices formed by vertices given by link_vertices - * form a pseudomanifold. - * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional - * faces and edges represent adjacency between them. - */ - bool link_is_pseudomanifold(std::vector< Vertex_handle >& star_vertices, - int dimension) - { - Adj_graph adj_graph; - Graph_map d_map, f_map; // d_map = map for d-dimensional simplices - // f_map = map for its facets - typeVectorVertex init_vector = {}; - add_vertices_to_link_graph(star_vertices, - star_vertices.begin()+1, - adj_graph, - d_map, - f_map, - init_vector, - 0, dimension); - //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; - //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; - add_edges_to_link_graph(adj_graph, d_map, f_map); - for (auto f_map_it : f_map) - { - //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; - if (boost::out_degree(f_map_it.second, adj_graph) != 2) - { - /* - if (boost::out_degree(f_map_it.second, adj_graph) >= 3) - { - std::cout << "This simplex has 3+ cofaces: "; - for(auto v : simplex_vertex_range(f_map_it.first)) - std::cout << v << " "; - std::cout << std::endl; - Adj_it ai, ai_end; - for (std::tie(ai, ai_end) = boost::adjacent_vertices(f_map_it.second, adj_graph); ai != ai_end; ++ai) - { - - } - } - */ - count_bad[dimension]++; - return false; - } - } - // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices - // What is left is to check the connexity - //std::vector components(boost::num_vertices(adj_graph)); - return true; //Forget the connexity - //return (boost::connected_components(adj_graph, &components[0]) == 1); - } - - public: -bool complex_is_pseudomanifold(int dimension) - { - Adj_graph adj_graph; - Graph_map d_map, f_map; // d_map = map for d-dimensional simplices - // f_map = map for its facets - Inv_graph_map inv_d_map; - typeVectorVertex init_vector = {}; - std::vector star_vertices; - for (int v: complex_vertex_range()) - star_vertices.push_back(v); - add_max_simplices_to_graph(star_vertices, - star_vertices.begin(), - adj_graph, - d_map, - f_map, - inv_d_map, - init_vector, - 0, dimension); - std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; - std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; - add_edges_to_link_graph(adj_graph, d_map, f_map); - for (auto f_map_it : f_map) - { - //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; - if (boost::out_degree(f_map_it.second, adj_graph) != 2) - { - if (boost::out_degree(f_map_it.second, adj_graph) >= 3) - { - std::cout << "This simplex has 3+ cofaces: "; - for(auto v : simplex_vertex_range(f_map_it.first)) - std::cout << v << " "; - std::cout << std::endl; - Adj_it ai, ai_end; - for (std::tie(ai, ai_end) = boost::adjacent_vertices(f_map_it.second, adj_graph); ai != ai_end; ++ai) - { - auto it = inv_d_map.find(*ai); - assert (it != inv_d_map.end()); - Simplex_handle sh = it->second; - for(auto v : simplex_vertex_range(sh)) - std::cout << v << " "; - std::cout << std::endl; - } - } - count_bad[dimension]++; - return false; - } - } - // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices - // What is left is to check the connexity - //std::vector components(boost::num_vertices(adj_graph)); - return true; //Forget the connexity - //return (boost::connected_components(adj_graph, &components[0]) == 1); - } - private: - void add_vertices_to_link_graph(typeVectorVertex& star_vertices, - typename typeVectorVertex::iterator curr_v, - Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map, - typeVectorVertex& curr_simplex, - int curr_d, - int link_dimension) - { - Simplex_handle sh; - Vertex_t vert; - typename typeVectorVertex::iterator it; - //std::pair resPair; - //typename Graph_map::iterator resPair; - //Add vertices - //std::cout << "Entered add vertices\n"; - for (it = curr_v; it != star_vertices.end(); ++it) - { - curr_simplex.push_back(*it); //push next vertex in question - curr_simplex.push_back(star_vertices[0]); //push the center of the star - /* - std::cout << "Searching for "; - print_vector(curr_simplex); - std::cout << " curr_dim " << curr_d << " d " << dimension << ""; - */ - typeVectorVertex curr_simplex_copy(curr_simplex); - sh = find(curr_simplex_copy); //a simplex of the star - curr_simplex.pop_back(); //pop the center of the star - curr_simplex_copy = typeVectorVertex(curr_simplex); - if (sh != null_simplex()) - { - //std::cout << " added\n"; - if (curr_d == link_dimension) - { - sh = find(curr_simplex_copy); //a simplex of the link - assert(sh != null_simplex()); //ASSERT! - vert = boost::add_vertex(adj_graph); - d_map.emplace(sh,vert); - } - else - { - - if (curr_d == link_dimension-1) - { - sh = find(curr_simplex_copy); //a simplex of the link - assert(sh != null_simplex()); - vert = boost::add_vertex(adj_graph); - f_map.emplace(sh,vert); - } - - //delete (&curr_simplex_copy); //Just so it doesn't stack - add_vertices_to_link_graph(star_vertices, - it+1, - adj_graph, - d_map, - f_map, - curr_simplex, - curr_d+1, link_dimension); - } - } - /* - else - std::cout << "\n"; - */ - curr_simplex.pop_back(); //pop the vertex in question - } - } - void add_edges_to_link_graph(Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map) - { - Simplex_handle sh; - // Add edges - //std::cout << "Entered add edges:\n"; - typename Graph_map::iterator map_it; - for (auto d_map_pair : d_map) - { - //std::cout << "*"; - sh = d_map_pair.first; - Vertex_t d_vert = d_map_pair.second; - for (auto facet_sh : boundary_simplex_range(sh)) - //for (auto f_map_it : f_map) - { - //std::cout << "'"; - map_it = f_map.find(facet_sh); - //We must have all the facets in the graph at this point - assert(map_it != f_map.end()); - Vertex_t f_vert = map_it->second; - //std::cout << "Added edge " << sh->first << "-" << map_it->first->first << "\n"; - boost::add_edge(d_vert,f_vert,adj_graph); - } - } - } - - void add_max_simplices_to_graph(typeVectorVertex& star_vertices, - typename typeVectorVertex::iterator curr_v, - Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map, - Inv_graph_map& inv_d_map, - typeVectorVertex& curr_simplex, - int curr_d, - int link_dimension) - { - Simplex_handle sh; - Vertex_t vert; - typename typeVectorVertex::iterator it; - //std::pair resPair; - //typename Graph_map::iterator resPair; - //Add vertices - //std::cout << "Entered add vertices\n"; - for (it = curr_v; it != star_vertices.end(); ++it) - { - curr_simplex.push_back(*it); //push next vertex in question - //curr_simplex.push_back(star_vertices[0]); //push the center of the star - /* - std::cout << "Searching for "; - print_vector(curr_simplex); - std::cout << " curr_dim " << curr_d << " d " << dimension << ""; - */ - typeVectorVertex curr_simplex_copy(curr_simplex); - sh = find(curr_simplex_copy); //a simplex of the star - //curr_simplex.pop_back(); //pop the center of the star - curr_simplex_copy = typeVectorVertex(curr_simplex); - if (sh != null_simplex()) - { - //std::cout << " added\n"; - if (curr_d == link_dimension) - { - sh = find(curr_simplex_copy); //a simplex of the link - assert(sh != null_simplex()); //ASSERT! - vert = boost::add_vertex(adj_graph); - d_map.emplace(sh,vert); - inv_d_map.emplace(vert,sh); - } - else - { - - if (curr_d == link_dimension-1) - { - sh = find(curr_simplex_copy); //a simplex of the link - assert(sh != null_simplex()); - vert = boost::add_vertex(adj_graph); - f_map.emplace(sh,vert); - } - - //delete (&curr_simplex_copy); //Just so it doesn't stack - add_max_simplices_to_graph(star_vertices, - it+1, - adj_graph, - d_map, - f_map, - inv_d_map, - curr_simplex, - curr_d+1, link_dimension); - } - } - /* - else - std::cout << "\n"; - */ - curr_simplex.pop_back(); //pop the vertex in question - } - } - public: /** \brief Verification if every simplex in the complex is witnessed */ -- cgit v1.2.3 From 8f54c437e0b895368c6151584811ce7df1575ea0 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 9 Dec 2015 13:03:03 +0000 Subject: Modified Witness_complex.h + more doc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@936 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 771e0a9cbfd0035738aee1a07b5f7c1f56bf13fc --- .../example/simple_witness_complex.cpp | 38 +- .../gudhi/Landmark_choice_by_furthest_point.h | 98 +++ .../gudhi/Landmark_choice_by_random_point.h | 82 ++ .../include/gudhi/Relaxed_witness_complex.h | 886 --------------------- .../include/gudhi/Witness_complex.h | 312 +------- .../include/gudhi/Witness_complex_doc.h | 37 + 6 files changed, 283 insertions(+), 1170 deletions(-) create mode 100644 src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h create mode 100644 src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h delete mode 100644 src/Witness_complex/include/gudhi/Relaxed_witness_complex.h create mode 100644 src/Witness_complex/include/gudhi/Witness_complex_doc.h (limited to 'src') diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index e95f67a8..6731f135 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -23,30 +23,36 @@ #include #include //#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Simplex_tree.h" #include "gudhi/Witness_complex.h" using namespace Gudhi; typedef std::vector< Vertex_handle > typeVectorVertex; +typedef Witness_complex> WitnessComplex; //typedef std::pair typeSimplex; //typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; int main (int argc, char * const argv[]) { - Witness_complex<> witnessComplex = Witness_complex<>(); - std::vector< typeVectorVertex > KNN; - typeVectorVertex witness0 = {1,0,5,2,6,3,4}; KNN.push_back(witness0 ); - typeVectorVertex witness1 = {2,6,4,5,0,1,3}; KNN.push_back(witness1 ); - typeVectorVertex witness2 = {3,4,2,1,5,6,0}; KNN.push_back(witness2 ); - typeVectorVertex witness3 = {4,2,1,3,5,6,0}; KNN.push_back(witness3 ); - typeVectorVertex witness4 = {5,1,6,0,2,3,4}; KNN.push_back(witness4 ); - typeVectorVertex witness5 = {6,0,5,2,1,3,4}; KNN.push_back(witness5 ); - typeVectorVertex witness6 = {0,5,6,1,2,3,4}; KNN.push_back(witness6 ); - typeVectorVertex witness7 = {2,6,4,5,3,1,0}; KNN.push_back(witness7 ); - typeVectorVertex witness8 = {1,2,5,4,3,6,0}; KNN.push_back(witness8 ); - typeVectorVertex witness9 = {3,4,0,6,5,1,2}; KNN.push_back(witness9 ); - typeVectorVertex witness10 = {5,0,1,3,6,2,4}; KNN.push_back(witness10); - typeVectorVertex witness11 = {5,6,1,0,2,3,4}; KNN.push_back(witness11); - typeVectorVertex witness12 = {1,6,0,5,2,3,4}; KNN.push_back(witness12); - witnessComplex.witness_complex(KNN); + Simplex_tree<> complex; + std::vector< typeVectorVertex > knn; + typeVectorVertex witness0 = {1,0,5,2,6,3,4}; knn.push_back(witness0 ); + typeVectorVertex witness1 = {2,6,4,5,0,1,3}; knn.push_back(witness1 ); + typeVectorVertex witness2 = {3,4,2,1,5,6,0}; knn.push_back(witness2 ); + typeVectorVertex witness3 = {4,2,1,3,5,6,0}; knn.push_back(witness3 ); + typeVectorVertex witness4 = {5,1,6,0,2,3,4}; knn.push_back(witness4 ); + typeVectorVertex witness5 = {6,0,5,2,1,3,4}; knn.push_back(witness5 ); + typeVectorVertex witness6 = {0,5,6,1,2,3,4}; knn.push_back(witness6 ); + typeVectorVertex witness7 = {2,6,4,5,3,1,0}; knn.push_back(witness7 ); + typeVectorVertex witness8 = {1,2,5,4,3,6,0}; knn.push_back(witness8 ); + typeVectorVertex witness9 = {3,4,0,6,5,1,2}; knn.push_back(witness9 ); + typeVectorVertex witness10 = {5,0,1,3,6,2,4}; knn.push_back(witness10); + typeVectorVertex witness11 = {5,6,1,0,2,3,4}; knn.push_back(witness11); + typeVectorVertex witness12 = {1,6,0,5,2,3,4}; knn.push_back(witness12); + WitnessComplex witnessComplex(knn, complex, 7); + if (witnessComplex.is_witness_complex(knn)) + std::cout << "Witness complex is good\n"; + else + std::cout << "Witness complex is bad\n"; } diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h new file mode 100644 index 00000000..44bf9dbb --- /dev/null +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -0,0 +1,98 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ +#define GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ + +/** + * \class Landmark_choice_by_furthest_point + * \brief The class `Landmark_choice_by_furthest_point` allows to construct the matrix + * of closest landmarks per witness by iteratively choosing the furthest witness + * from the set of already chosen landmarks as the new landmark. + * \ingroup witness_complex + */ + +class Landmark_choice_by_random_point { + +/** + * \brief Landmark choice strategy by iteratively adding the furthest witness from the + * current landmark set as the new landmark. It takes a random access range `points` and + * writes {witness}*{closest landmarks} matrix in `knn`. + */ + + template + Landmark_choice_by_furthest_points(Point_random_access_range &points, + KNearestNeighbours &knn) + { + int nb_points = points.end() - points.begin(); + std::vector> wit_land_dist(nb_points, std::vector()); // distance matrix witness x landmarks + typeVectorVertex chosen_landmarks; // landmark list + + knn = KNearestNeighbours(nb_points, std::vector()); + int current_number_of_landmarks=0; // counter for landmarks + double curr_max_dist = 0; // used for defining the furhest point from L + const double infty = std::numeric_limits::infinity(); // infinity (see next entry) + std::vector< double > dist_to_L(nb_points,infty); // vector of current distances to L from points + + //CHOICE OF THE FIRST LANDMARK + int rand_int = rand() % nb_points; + int curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + //curr_max_w at this point is the next landmark + chosen_landmarks.push_back(curr_max_w); + for (auto v: knn) + v.push_back(current_number_of_landmarks); + int i = 0; + for (const auto& p: points) + { + // used to stock the distance from the current point to L + double curr_dist = euclidean_distance(p, points.begin() + chosen_landmarks[current_number_of_landmarks]); + wit_land_dist[i].push_back(curr_dist); + knn[i].push_back(current_number_of_landmarks); + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + int j = current_number_of_landmarks; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + std::swap(knn[i][j], knn[i][j-1]); + std::swap(wit_land_dist[i][j-1], wit_land_dist[i][j-1]); + --j; + } + ++i; + } + curr_max_dist = 0; + for (auto dist: dist_to_L) { + if (dist > curr_max_dist) + { + curr_max_dist = dist; + curr_max_w = i; + } + } + } + } + +}; + +#endif diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h new file mode 100644 index 00000000..bc3e72d9 --- /dev/null +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -0,0 +1,82 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ +#define GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ + +/** + * \class Landmark_choice_by_random_point + * \brief The class `Landmark_choice_by_random_point` allows to construct the matrix + * of closest landmarks per witness by iteratively choosing a random non-chosen witness + * as a new landmark. + * \ingroup witness_complex + */ + +class Landmark_choice_by_random_point { + + + /** \brief Landmark choice strategy by taking random vertices for landmarks. + * It takes a random access range points and outputs a matrix {witness}*{closest landmarks} + * in knn. + */ + + template + void landmark_choice_by_random_points(Point_random_access_range &points, KNearestNeighbours &knn) + { + int nbP = points.end() - points.begin(); + std::set &landmarks; + int current_number_of_landmarks=0; // counter for landmarks + + int chosen_landmark = rand()%nbP; + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + while (landmarks.find(chosen_landmark) != landmarks.end()) + chosen_landmark = rand()% nbP; + landmarks.insert(chosen_landmark); + } + + int D = points.begin().size(); + typedef std::pair dist_i; + typedef bool (*comp)(dist_i,dist_i); + for (int points_i = 0; points_i < nbP; points_i++) + { + std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); + std::set::iterator landmarks_it; + int landmarks_i = 0; + for (landmarks_it = landmarks.begin(), landmarks_i=0; landmarks_it != landmarks.end(); landmarks_it++, landmarks_i++) + { + dist_i dist = std::make_pair(euclidean_distance(points[points_i],points[*landmarks_it]), landmarks_i); + l_heap.push(dist); + } + for (int i = 0; i < D+1; i++) + { + dist_i dist = l_heap.top(); + knn[points_i].push_back(dist.second); + l_heap.pop(); + } + } + } + +}; + +#endif diff --git a/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h b/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h deleted file mode 100644 index c869628f..00000000 --- a/src/Witness_complex/include/gudhi/Relaxed_witness_complex.h +++ /dev/null @@ -1,886 +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): Siargey Kachanovich - * - * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef GUDHI_RELAXED_WITNESS_COMPLEX_H_ -#define GUDHI_RELAXED_WITNESS_COMPLEX_H_ - -#include -#include -#include -#include -#include "gudhi/reader_utils.h" -#include "gudhi/distance_functions.h" -#include "gudhi/Simplex_tree.h" -#include -#include -#include -#include -#include -#include -#include -#include - -// Needed for nearest neighbours -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -// Needed for the adjacency graph in bad link search -#include -#include -#include - -namespace Gudhi { - - - /** \addtogroup simplex_tree - * Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: - * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ - * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that - * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. - */ - template - class Witness_complex: public Simplex_tree<> { - - private: - - struct Active_witness { - int witness_id; - int landmark_id; - Simplex_handle simplex_handle; - - Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) - : witness_id(witness_id_), - landmark_id(landmark_id_), - simplex_handle(simplex_handle_) - {} - }; - - - - - public: - - - /** \brief Type for the vertex handle. - * - * Must be a signed integer type. It admits a total order <. */ - typedef VertexHandle Vertex_handle; - - /* Type of node in the simplex tree. */ - typedef Simplex_tree_node_explicit_storage Node; - /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ - typedef typename boost::container::flat_map Dictionary; - typedef typename Dictionary::iterator Simplex_handle; - - typedef std::vector< double > Point_t; - typedef std::vector< Point_t > Point_Vector; - - typedef std::vector< Vertex_handle > typeVectorVertex; - typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; - typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - - typedef int Witness_id; - typedef int Landmark_id; - typedef std::list< Vertex_handle > ActiveWitnessList; - - private: - /** Number of landmarks - */ - int nbL; - /** Desired density - */ - double density; - - public: - - /** \brief Set number of landmarks to nbL_ - */ - void setNbL(int nbL_) - { - nbL = nbL_; - } - - /** \brief Set density to density_ - */ - void setDensity(double density_) - { - density = density_; - } - - /** - * /brief Iterative construction of the relaxed witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks} and (1+epsilon)-limit table {witnesses}*{landmarks} consisting of iterators of k nearest neighbor matrix. - * The line lengths can differ, however both matrices have the same corresponding line lengths. - */ - - template< typename KNearestNeighbours, typename OPELimits > - void relaxed_witness_complex(KNearestNeighbours & knn, OPELimits & rl) - //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) - { - std::cout << "**Start the procedure witness_complex" << std::endl; - //Construction of the active witness list - int nbW = knn.size(); - //int nbL = knn.at(0).size(); - typeVectorVertex vv; - //typeSimplex simplex; - //typePairSimplexBool returnValue; - //int counter = 0; - /* The list of still useful witnesses - * it will diminuish in the course of iterations - */ - ActiveWitnessList active_w;// = new ActiveWitnessList(); - for (int i=0; i != nbL; ++i) { - // initial fill of 0-dimensional simplices - // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore - //counter++; - vv = {i}; - insert_simplex(vv, Filtration_value(0.0)); - /* TODO Error if not inserted : normally no need here though*/ - } - int k=1; /* current dimension in iterative construction */ - //std::cout << "Successfully added landmarks" << std::endl; - // PRINT2 - //print_sc(root()); std::cout << std::endl; - for (int i=0; i != nbW; ++i) - active_w.push_back(i); - /* - int u,v; // two extremities of an edge - if (nbL > 1) // if the supposed dimension of the complex is >0 - { - for (int i=0; i != nbW; ++i) - { - // initial fill of active witnesses list - u = knn[i][0]; - v = knn[i][1]; - vv = {u,v}; - this->insert_simplex(vv,Filtration_value(0.0)); - //print_sc(root()); std::cout << std::endl; - //std::cout << "Added edges" << std::endl; - } - //print_sc(root()); - - } - */ - std::cout << "k=0, active witnesses: " << active_w.size() << std::endl; - //std::cout << "Successfully added edges" << std::endl; - //count_good = {0,0}; - //count_bad = {0,0}; - while (!active_w.empty() && k < nbL ) - { - //count_good.push_back(0); - //count_bad.push_back(0); - //std::cout << "Started the step k=" << k << std::endl; - typename ActiveWitnessList::iterator aw_it = active_w.begin(); - while (aw_it != active_w.end()) - { - std::vector simplex; - bool ok = add_all_faces_of_dimension(k, knn[*aw_it].begin(), rl[*aw_it].begin(), simplex, knn[*aw_it].end(), knn[*aw_it].end()); - if (!ok) - active_w.erase(aw_it++); //First increase the iterator and then erase the previous element - else - aw_it++; - } - std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; - k++; - } - //print_sc(root()); std::cout << std::endl; - } - - /* \brief Adds recursively all the faces of a certain dimension dim witnessed by the same witness - * Iterator is needed to know until how far we can take landmarks to form simplexes - * simplex is the prefix of the simplexes to insert - * The output value indicates if the witness rests active or not - */ - bool add_all_faces_of_dimension(int dim, std::vector::iterator curr_l, typename std::vector< std::vector::iterator >::iterator curr_until, std::vector& simplex, std::vector::iterator until, std::vector::iterator end) - { - /* - std::ofstream ofs ("stree_result.txt", std::ofstream::out); - st_to_file(ofs); - ofs.close(); - */ - //print_sc(root()); - bool will_be_active = false; - if (dim > 0) - for (std::vector::iterator it = curr_l; it != until && it != end; ++it, ++curr_until) - { - simplex.push_back(*it); - if (find(simplex) != null_simplex()) - will_be_active = will_be_active || add_all_faces_of_dimension(dim-1, it+1, curr_until+1, simplex, until, end); - simplex.pop_back(); - if (until == end) - until = *curr_until; - } - else if (dim == 0) - for (std::vector::iterator it = curr_l; it != until && it != end; ++it, ++curr_until) - { - simplex.push_back(*it); - if (all_faces_in(simplex)) - { - will_be_active = true; - insert_simplex(simplex, 0.0); - } - simplex.pop_back(); - if (until == end) - until = *curr_until; - } - return will_be_active; - } - - /** \brief Construction of witness complex from points given explicitly - * nbL must be set to the right value of landmarks for strategies - * FURTHEST_POINT_STRATEGY and RANDOM_POINT_STRATEGY and - * density must be set to the right value for DENSITY_STRATEGY - */ - // void witness_complex_from_points(Point_Vector point_vector) - // { - // std::vector > WL; - // landmark_choice_by_random_points(point_vector, point_vector.size(), WL); - // witness_complex(WL); - // } - -private: - - /** \brief Print functions - */ - void print_sc(Siblings * sibl) - { - if (sibl == NULL) - std::cout << "&"; - else - print_children(sibl->members_); - } - - void print_children(Dictionary map) - { - std::cout << "("; - if (!map.empty()) - { - std::cout << map.begin()->first; - if (has_children(map.begin())) - print_sc(map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - std::cout << "," << it->first; - if (has_children(it)) - print_sc(it->second.children()); - } - } - std::cout << ")"; - } - - public: - /** \brief Print functions - */ - - void st_to_file(std::ofstream& out_file) - { - sc_to_file(out_file, root()); - } - - private: - void sc_to_file(std::ofstream& out_file, Siblings * sibl) - { - assert(sibl); - children_to_file(out_file, sibl->members_); - } - - void children_to_file(std::ofstream& out_file, Dictionary& map) - { - out_file << "(" << std::flush; - if (!map.empty()) - { - out_file << map.begin()->first << std::flush; - if (has_children(map.begin())) - sc_to_file(out_file, map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - out_file << "," << it->first << std::flush; - if (has_children(it)) - sc_to_file(out_file, it->second.children()); - } - } - out_file << ")" << std::flush; - } - - - /** \brief Check if the facets of the k-dimensional simplex witnessed - * by witness witness_id are already in the complex. - * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id - */ - bool all_faces_in(std::vector& simplex) - { - //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; - std::vector< VertexHandle > facet; - //VertexHandle curr_vh = curr_sh->first; - // CHECK ALL THE FACETS - for (std::vector::iterator not_it = simplex.begin(); not_it != simplex.end(); ++not_it) - { - facet.clear(); - //facet = {}; - for (std::vector::iterator it = simplex.begin(); it != simplex.end(); ++it) - if (it != not_it) - facet.push_back(*it); - if (find(facet) == null_simplex()) - return false; - } //endfor - return true; - } - - template - void print_vector(std::vector v) - { - std::cout << "["; - if (!v.empty()) - { - std::cout << *(v.begin()); - for (auto it = v.begin()+1; it != v.end(); ++it) - { - std::cout << ","; - std::cout << *it; - } - } - std::cout << "]"; - } - - template - void print_vvector(std::vector< std::vector > vv) - { - std::cout << "["; - if (!vv.empty()) - { - print_vector(*(vv.begin())); - for (auto it = vv.begin()+1; it != vv.end(); ++it) - { - std::cout << ","; - print_vector(*it); - } - } - std::cout << "]\n"; - } - - public: -/** - * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the - * current landmark set - * \arg W is the vector of points which will be the witnesses - * \arg nbP is the number of witnesses - * \arg nbL is the number of landmarks - * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) - */ - - template - void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - { - //std::cout << "Enter landmark_choice_by_furthest_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - //double density = 5.; - Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - typeVectorVertex chosen_landmarks; // landmark list - - WL = KNearestNeighbours(nbP,std::vector()); - int current_number_of_landmarks=0; // counter for landmarks - double curr_max_dist = 0; // used for defining the furhest point from L - double curr_dist; // used to stock the distance from the current point to L - double infty = std::numeric_limits::infinity(); // infinity (see next entry) - std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points - // double mindist = infty; - int curr_max_w=0; // the point currently furthest from L - int j; - int temp_swap_int; - double temp_swap_double; - - //CHOICE OF THE FIRST LANDMARK - std::cout << "Enter the first landmark stage\n"; - srand(354698); - int rand_int = rand()% nbP; - curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - //curr_max_w at this point is the next landmark - chosen_landmarks.push_back(curr_max_w); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - for (auto v: WL) - v.push_back(current_number_of_landmarks); - for (int i = 0; i < nbP; ++i) - { - // iteration on points in W. update of distance vectors - - //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - //std::cout << "The problem is not in distance function\n"; - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - //std::cout << "Push't back\n"; - if (curr_dist < dist_to_L[i]) - dist_to_L[i] = curr_dist; - j = current_number_of_landmarks; - //std::cout << "First half complete\n"; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - // sort the closest landmark vector for every witness - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } - //std::cout << "result WL="; print_vvector(WL); - //std::cout << "result WLD="; print_vvector(wit_land_dist); - //std::cout << "result distL="; print_vector(dist_to_L); std::cout << std::endl; - //std::cout << "End loop\n"; - } - //std::cout << "Distance to landmarks="; print_vector(dist_to_L); std::cout << std::endl; - curr_max_dist = 0; - for (int i = 0; i < nbP; ++i) { - if (dist_to_L[i] > curr_max_dist) - { - curr_max_dist = dist_to_L[i]; - curr_max_w = i; - } - } - //std::cout << "Chose " << curr_max_w << " as new landmark\n"; - } - //std::cout << endl; - } - - /** \brief Landmark choice strategy by taking random vertices for landmarks. - * - */ - - // template - // void landmark_choice_by_random_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - // { - // std::cout << "Enter landmark_choice_by_random_points "<< std::endl; - // //std::cout << "W="; print_vvector(W); - // std::unordered_set< int > chosen_landmarks; // landmark set - - // Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - - // WL = KNearestNeighbours(nbP,std::vector()); - // int current_number_of_landmarks=0; // counter for landmarks - - // srand(24660); - // int chosen_landmark = rand()%nbP; - // double curr_dist; - - // //int j; - // //int temp_swap_int; - // //double temp_swap_double; - - - // for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - // { - // while (chosen_landmarks.find(chosen_landmark) != chosen_landmarks.end()) - // { - // srand((int)clock()); - // chosen_landmark = rand()% nbP; - // //std::cout << chosen_landmark << "\n"; - // } - // chosen_landmarks.insert(chosen_landmark); - // //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - // //std::cout << "WL="; print_vvector(WL); - // //std::cout << "WLD="; print_vvector(wit_land_dist); - // //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - // for (auto v: WL) - // v.push_back(current_number_of_landmarks); - // for (int i = 0; i < nbP; ++i) - // { - // // iteration on points in W. update of distance vectors - - // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - // //std::cout << "The problem is not in distance function\n"; - // wit_land_dist[i].push_back(curr_dist); - // WL[i].push_back(current_number_of_landmarks); - // //std::cout << "Push't back\n"; - // //j = current_number_of_landmarks; - // //std::cout << "First half complete\n"; - // //std::cout << "result WL="; print_vvector(WL); - // //std::cout << "result WLD="; print_vvector(wit_land_dist); - // //std::cout << "End loop\n"; - // } - // } - // for (int i = 0; i < nbP; i++) - // { - // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); - // } - // //std::cout << endl; - // } - - /** \brief Landmark choice strategy by taking random vertices for landmarks. - * - */ - - // template - void landmark_choice_by_random_points(Point_Vector &W, int nbP, std::set &L) - { - std::cout << "Enter landmark_choice_by_random_points "<< std::endl; - //std::cout << "W="; print_vvector(W); - //std::unordered_set< int > chosen_landmarks; // landmark set - - //Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - - //WL = KNearestNeighbours(nbP,std::vector()); - int current_number_of_landmarks=0; // counter for landmarks - - srand(24660); - int chosen_landmark = rand()%nbP; - //double curr_dist; - //int j; - //int temp_swap_int; - //double temp_swap_double; - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - while (L.find(chosen_landmark) != L.end()) - { - srand((int)clock()); - chosen_landmark = rand()% nbP; - //std::cout << chosen_landmark << "\n"; - } - L.insert(chosen_landmark); - //std::cout << "**********Entered loop with current number of landmarks = " << current_number_of_landmarks << std::endl; - //std::cout << "WL="; print_vvector(WL); - //std::cout << "WLD="; print_vvector(wit_land_dist); - //std::cout << "landmarks="; print_vector(chosen_landmarks); std::cout << std::endl; - // for (auto v: WL) - // v.push_back(current_number_of_landmarks); - // for (int i = 0; i < nbP; ++i) - // { - // // iteration on points in W. update of distance vectors - - // //std::cout << "In the loop with i=" << i << " and landmark=" << chosen_landmarks[current_number_of_landmarks] << std::endl; - // //std::cout << "W[i]="; print_vector(W[i]); std::cout << " W[landmark]="; print_vector(W[chosen_landmarks[current_number_of_landmarks]]); std::cout << std::endl; - // curr_dist = euclidean_distance(W[i],W[chosen_landmark]); - // //std::cout << "The problem is not in distance function\n"; - // wit_land_dist[i].push_back(curr_dist); - // WL[i].push_back(current_number_of_landmarks); - // //std::cout << "Push't back\n"; - // //j = current_number_of_landmarks; - // //std::cout << "First half complete\n"; - // //std::cout << "result WL="; print_vvector(WL); - // //std::cout << "result WLD="; print_vvector(wit_land_dist); - // //std::cout << "End loop\n"; - // } - } - // for (int i = 0; i < nbP; i++) - // { - // sort(WL[i].begin(), WL[i].end(), [&](int j1, int j2){return wit_land_dist[i][j1] < wit_land_dist[i][j2];}); - // } - //std::cout << endl; - } - - - /** \brief Construct the matrix |W|x(D+1) of D+1 closest landmarks - * where W is the set of witnesses and D is the ambient dimension - */ - template - void nearest_landmarks(Point_Vector &W, std::set &L, KNearestNeighbours &WL) - { - int D = W[0].size(); - int nbP = W.size(); - WL = KNearestNeighbours(nbP,std::vector()); - typedef std::pair dist_i; - typedef bool (*comp)(dist_i,dist_i); - for (int W_i = 0; W_i < nbP; W_i++) - { - //std::cout << "<<<<<<<<<<<<<<" << W_i <<"\n"; - std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); - std::set::iterator L_it; - int L_i; - for (L_it = L.begin(), L_i=0; L_it != L.end(); L_it++, L_i++) - { - dist_i dist = std::make_pair(euclidean_distance(W[W_i],W[*L_it]), L_i); - l_heap.push(dist); - } - for (int i = 0; i < D+1; i++) - { - dist_i dist = l_heap.top(); - WL[W_i].push_back(dist.second); - //WL[W_i].insert(WL[W_i].begin(),dist.second); - //std::cout << dist.first << " " << dist.second << std::endl; - l_heap.pop(); - } - } - } - - /** \brief Search and output links around vertices that are not pseudomanifolds - * - */ - void write_bad_links(std::ofstream& out_file) - { - out_file << "Bad links list\n"; - std::cout << "Entered write_bad_links\n"; - //typeVectorVertex testv = {9,15,17}; - //int count = 0; - for (auto v: complex_vertex_range()) - { - //std::cout << "Vertex " << v << ":\n"; - std::vector< Vertex_handle > link_vertices; - // Fill link_vertices - for (auto u: complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u != v && find(edge) != null_simplex()) - link_vertices.push_back(u); - } - /* - print_vector(link_vertices); - std::cout << "\n"; - */ - // Find the dimension - typeVectorVertex empty_simplex = {}; - int d = link_dim(link_vertices, link_vertices.begin(),-1, empty_simplex); - //std::cout << " dim " << d << "\n"; - //Siblings* curr_sibl = root(); - if (link_is_pseudomanifold(link_vertices,d)) - count_good[d]++; - //out_file << "Bad link at " << v << "\n"; - } - //out_file << "Number of bad links: " << count << "/" << root()->size(); - //std::cout << "Number of bad links: " << count << "/" << root()->size() << std::endl; - nc = nbL; - for (unsigned int i = 0; i != count_good.size(); i++) - { - out_file << "count_good[" << i << "] = " << count_good[i] << std::endl; - nc -= count_good[i]; - if (count_good[i] != 0) - std::cout << "count_good[" << i << "] = " << count_good[i] << std::endl; - } - for (unsigned int i = 0; i != count_bad.size(); i++) - { - out_file << "count_bad[" << i << "] = " << count_bad[i] << std::endl; - nc -= count_bad[i]; - if (count_bad[i] != 0) - std::cout << "count_bad[" << i << "] = " << count_bad[i] << std::endl; - } - std::cout << "not_connected = " << nc << std::endl; - } - - private: - - std::vector count_good; - std::vector count_bad; - int nc; - - int link_dim(std::vector< Vertex_handle >& link_vertices, - typename std::vector< Vertex_handle >::iterator curr_v, - int curr_d, - typeVectorVertex& curr_simplex) - { - //std::cout << "Entered link_dim for " << *(curr_v-1) << "\n"; - Simplex_handle sh; - int final_d = curr_d; - typename std::vector< Vertex_handle >::iterator it; - for (it = curr_v; it != link_vertices.end(); ++it) - { - curr_simplex.push_back(*it); - /* - std::cout << "Searching for "; - print_vector(curr_simplex); - std::cout << " curr_dim " << curr_d << " final_dim " << final_d; - */ - sh = find(curr_simplex); - if (sh != null_simplex()) - { - //std::cout << " -> " << *it << "\n"; - int d = link_dim(link_vertices, it+1, curr_d+1, curr_simplex); - if (d > final_d) - final_d = d; - } - /* - else - std::cout << "\n"; - */ - curr_simplex.pop_back(); - } - return final_d; - } - - // color is false is a (d-1)-dim face, true is a d-dim face - //typedef bool Color; - // graph is an adjacency list - typedef typename boost::adjacency_list Adj_graph; - // map that gives to a certain simplex its node in graph and its dimension - //typedef std::pair Reference; - typedef boost::graph_traits::vertex_descriptor Vertex_t; - typedef boost::graph_traits::edge_descriptor Edge_t; - - typedef boost::container::flat_map Graph_map; - - /* \brief Verifies if the simplices formed by vertices given by link_vertices - * form a pseudomanifold. - * The idea is to make a bipartite graph, where vertices are the d- and (d-1)-dimensional - * faces and edges represent adjacency between them. - */ - bool link_is_pseudomanifold(std::vector< Vertex_handle >& link_vertices, - int dimension) - { - Adj_graph adj_graph; - Graph_map d_map, f_map; // d_map = map for d-dimensional simplices - // f_map = map for its facets - typeVectorVertex empty_vector = {}; - add_vertices(link_vertices, - link_vertices.begin(), - adj_graph, - d_map, - f_map, - empty_vector, - 0, dimension); - //std::cout << "DMAP_SIZE: " << d_map.size() << "\n"; - //std::cout << "FMAP_SIZE: " << f_map.size() << "\n"; - add_edges(adj_graph, d_map, f_map); - for (auto f_map_it : f_map) - { - //std::cout << "Degree of " << f_map_it.first->first << " is " << boost::out_degree(f_map_it.second, adj_graph) << "\n"; - if (boost::out_degree(f_map_it.second, adj_graph) != 2) - { - count_bad[dimension]++; - return false; - } - } - // At this point I know that all (d-1)-simplices are adjacent to exactly 2 d-simplices - // What is left is to check the connexity - std::vector components(boost::num_vertices(adj_graph)); - return (boost::connected_components(adj_graph, &components[0]) == 1); - } - - void add_vertices(typeVectorVertex& link_vertices, - typename typeVectorVertex::iterator curr_v, - Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map, - typeVectorVertex& curr_simplex, - int curr_d, - int dimension) - { - Simplex_handle sh; - Vertex_t vert; - typename typeVectorVertex::iterator it; - std::pair resPair; - //typename Graph_map::iterator resPair; - //Add vertices - //std::cout << "Entered add vertices\n"; - for (it = curr_v; it != link_vertices.end(); ++it) - { - curr_simplex.push_back(*it); - /* - std::cout << "Searching for "; - print_vector(curr_simplex); - std::cout << " curr_dim " << curr_d << " d " << dimension << ""; - */ - sh = find(curr_simplex); - if (sh != null_simplex()) - { - //std::cout << " added\n"; - if (curr_d == dimension) - { - vert = boost::add_vertex(adj_graph); - resPair = d_map.emplace(sh,vert); - } - else - { - if (curr_d == dimension-1) - { - vert = boost::add_vertex(adj_graph); - resPair = f_map.emplace(sh,vert); - } - add_vertices(link_vertices, - it+1, - adj_graph, - d_map, - f_map, - curr_simplex, - curr_d+1, dimension); - } - } - /* - else - std::cout << "\n"; - */ - curr_simplex.pop_back(); - } - } - - void add_edges(Adj_graph& adj_graph, - Graph_map& d_map, - Graph_map& f_map) - { - Simplex_handle sh; - // Add edges - //std::cout << "Entered add edges:\n"; - typename Graph_map::iterator map_it; - for (auto d_map_pair : d_map) - { - //std::cout << "*"; - sh = d_map_pair.first; - Vertex_t d_vert = d_map_pair.second; - for (auto facet_sh : boundary_simplex_range(sh)) - //for (auto f_map_it : f_map) - { - //std::cout << "'"; - map_it = f_map.find(facet_sh); - //We must have all the facets in the graph at this point - assert(map_it != f_map.end()); - Vertex_t f_vert = map_it->second; - //std::cout << "Added edge " << sh->first << "-" << map_it->first->first << "\n"; - boost::add_edge(d_vert,f_vert,adj_graph); - } - } - } - - ////////////////////////////////////////////////////////////////////////////////////////////////// - //***********COLLAPSES**************************************************************************// - ////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - - - -}; //class Witness_complex - - - -} // namespace Guhdi - -#endif diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 8316fe3e..b218611b 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -27,9 +27,7 @@ #include #include #include -#include "gudhi/reader_utils.h" #include "gudhi/distance_functions.h" -#include "gudhi/Simplex_tree.h" #include #include #include @@ -47,47 +45,32 @@ namespace Gudhi { - /** Witness complex is a simplicial complex defined on two sets of points in \f$\mathbf{R}^D\f$: - * \f$W\f$ set of witnesses and \f$L \subseteq W\f$ set of landmarks. The simplices are based on points in \f$L\f$ - * and a simplex belongs to the witness complex if and only if it is witnessed (there exists a point \f$w \in W\f$ such that - * w is closer to the vertices of this simplex than others) and all of its faces are witnessed as well. + /** + \class Witness_complex + \brief Constructs the witness complex for the given set of witnesses and landmarks. + \ingroup witness_complex */ - template - class Witness_complex: public Simplex_tree<> { - + template< class Simplicial_complex> + class Witness_complex { + private: struct Active_witness { int witness_id; int landmark_id; - Simplex_handle simplex_handle; - Active_witness(int witness_id_, int landmark_id_, Simplex_handle simplex_handle_) + Active_witness(int witness_id_, int landmark_id_) : witness_id(witness_id_), - landmark_id(landmark_id_), - simplex_handle(simplex_handle_) + landmark_id(landmark_id_) {} }; - - - public: - - - /** \brief Type for the vertex handle. - * - * Must be a signed integer type. It admits a total order <. */ - typedef VertexHandle Vertex_handle; - - /* Type of node in the simplex tree. */ - typedef Simplex_tree_node_explicit_storage Node; - /* Type of dictionary Vertex_handle -> Node for traversing the simplex tree. */ - typedef typename boost::container::flat_map Dictionary; - typedef typename Dictionary::iterator Simplex_handle; + private: + typedef typename Simplicial_complex::Simplex_handle Simplex_handle; + typedef typename Simplicial_complex::Vertex_handle Vertex_handle; + typedef std::vector< double > Point_t; typedef std::vector< Point_t > Point_Vector; @@ -102,33 +85,29 @@ namespace Gudhi { private: int nbL; // Number of landmarks double density; // Desired density - + Simplicial_complex& sc; // Simplicial complex + public: - /** \brief Set number of landmarks to nbL_ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** @name Constructor */ - void setNbL(int nbL_) - { - nbL = nbL_; - } - /** \brief Set density to density_ - */ - void setDensity(double density_) - { - density = density_; - } + //@{ /** - * /brief Iterative construction of the witness complex basing on a matrix of k nearest neighbours of the form {witnesses}x{landmarks}. - * Landmarks are supposed to be in [0,nbL-1] - */ - + * \brief Iterative construction of the witness complex. + * \details The witness complex is written in sc_ basing on a matrix knn of + * nearest neighbours of the form {witnesses}x{landmarks}. + * Parameter dim serves as the limit for the number of closest landmarks to consider. + * Landmarks are supposed to be in [0,nbL_-1] + */ template< typename KNearestNeighbours > - void witness_complex(KNearestNeighbours & knn) - //void witness_complex(std::vector< std::vector< Vertex_handle > > & knn) + Witness_complex(KNearestNeighbours & knn, + Simplicial_complex & sc_, + int nbL_, + int dim ): nbL(nbL_), sc(sc_) { - std::cout << "**Start the procedure witness_complex" << std::endl; //Construction of the active witness list int nbW = knn.size(); typeVectorVertex vv; @@ -144,16 +123,14 @@ namespace Gudhi { // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; vv = {i}; - returnValue = insert_simplex(vv, Filtration_value(0.0)); + returnValue = sc.insert_simplex(vv, Filtration_value(0.0)); /* TODO Error if not inserted : normally no need here though*/ } int k=1; /* current dimension in iterative construction */ for (int i=0; i != nbW; ++i) active_w.push_back(i); - std::cout << "k=0, active witnesses: " << active_w.size() << std::endl; //std::cout << "Successfully added edges" << std::endl; - int D = knn[0].size(); - while (!active_w.empty() && k < D ) + while (!active_w.empty() && k < dim ) { //std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); @@ -166,84 +143,20 @@ namespace Gudhi { { for (int i = 0; i != k+1; ++i) simplex_vector.push_back(knn[*it][i]); - returnValue = insert_simplex(simplex_vector,0.0); + returnValue = sc.insert_simplex(simplex_vector,0.0); it++; } else active_w.erase(it++); //First increase the iterator and then erase the previous element } - std::cout << "k=" << k << ", active witnesses: " << active_w.size() << std::endl; k++; } } - -private: - /** \brief Print functions - */ - void print_sc(Siblings * sibl) - { - if (sibl == NULL) - std::cout << "&"; - else - print_children(sibl->members_); - } + //@} - void print_children(Dictionary map) - { - std::cout << "("; - if (!map.empty()) - { - std::cout << map.begin()->first; - if (has_children(map.begin())) - print_sc(map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - std::cout << "," << it->first; - if (has_children(it)) - print_sc(it->second.children()); - } - } - std::cout << ")"; - } - - public: - /** \brief Print functions - */ - - void st_to_file(std::ofstream& out_file) - { - sc_to_file(out_file, root()); - } - private: - void sc_to_file(std::ofstream& out_file, Siblings * sibl) - { - assert(sibl); - children_to_file(out_file, sibl->members_); - } - void children_to_file(std::ofstream& out_file, Dictionary& map) - { - out_file << "(" << std::flush; - if (!map.empty()) - { - out_file << map.begin()->first << std::flush; - if (has_children(map.begin())) - sc_to_file(out_file, map.begin()->second.children()); - typename Dictionary::iterator it; - for (it = map.begin()+1; it != map.end(); ++it) - { - out_file << "," << it->first << std::flush; - if (has_children(it)) - sc_to_file(out_file, it->second.children()); - } - } - out_file << ")" << std::flush; - } - - /** \brief Check if the facets of the k-dimensional simplex witnessed * by witness witness_id are already in the complex. * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id @@ -252,8 +165,8 @@ private: bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k) { //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; - std::vector< VertexHandle > facet; - //VertexHandle curr_vh = curr_sh->first; + std::vector< Vertex_handle > facet; + //Vertex_handle curr_vh = curr_sh->first; // CHECK ALL THE FACETS for (int i = 0; i != k+1; ++i) { @@ -265,14 +178,14 @@ private: facet.push_back(knn[witness_id][j]); } }//endfor - if (find(facet) == null_simplex()) + if (sc.find(facet) == sc.null_simplex()) return false; //std::cout << "++++ finished loop safely\n"; } //endfor return true; } - - template + + template void print_vector(std::vector v) { std::cout << "["; @@ -288,162 +201,25 @@ private: std::cout << "]"; } - template - void print_vvector(std::vector< std::vector > vv) - { - std::cout << "["; - if (!vv.empty()) - { - print_vector(*(vv.begin())); - for (auto it = vv.begin()+1; it != vv.end(); ++it) - { - std::cout << ","; - print_vector(*it); - } - } - std::cout << "]\n"; - } - public: -/** - * \brief Landmark choice strategy by iteratively adding the landmark the furthest from the - * current landmark set - * \arg W is the vector of points which will be the witnesses - * \arg nbP is the number of witnesses - * \arg nbL is the number of landmarks - * \arg WL is the matrix of the nearest landmarks with respect to witnesses (output) - */ - - template - void landmark_choice_by_furthest_points(Point_Vector &W, int nbP, KNearestNeighbours &WL) - { - Point_Vector wit_land_dist(nbP,std::vector()); // distance matrix witness x landmarks - typeVectorVertex chosen_landmarks; // landmark list - - WL = KNearestNeighbours(nbP,std::vector()); - int current_number_of_landmarks=0; // counter for landmarks - double curr_max_dist = 0; // used for defining the furhest point from L - double curr_dist; // used to stock the distance from the current point to L - double infty = std::numeric_limits::infinity(); // infinity (see next entry) - std::vector< double > dist_to_L(nbP,infty); // vector of current distances to L from points - int curr_max_w=0; // the point currently furthest from L - int j; - int temp_swap_int; - double temp_swap_double; - - //CHOICE OF THE FIRST LANDMARK - std::cout << "Enter the first landmark stage\n"; - srand(354698); - int rand_int = rand()% nbP; - curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - //curr_max_w at this point is the next landmark - chosen_landmarks.push_back(curr_max_w); - for (auto v: WL) - v.push_back(current_number_of_landmarks); - for (int i = 0; i < nbP; ++i) - { - curr_dist = euclidean_distance(W[i],W[chosen_landmarks[current_number_of_landmarks]]); - wit_land_dist[i].push_back(curr_dist); - WL[i].push_back(current_number_of_landmarks); - if (curr_dist < dist_to_L[i]) - dist_to_L[i] = curr_dist; - j = current_number_of_landmarks; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - temp_swap_int = WL[i][j]; - WL[i][j] = WL[i][j-1]; - WL[i][j-1] = temp_swap_int; - temp_swap_double = wit_land_dist[i][j]; - wit_land_dist[i][j] = wit_land_dist[i][j-1]; - wit_land_dist[i][j-1] = temp_swap_double; - --j; - } - } - curr_max_dist = 0; - for (int i = 0; i < nbP; ++i) { - if (dist_to_L[i] > curr_max_dist) - { - curr_max_dist = dist_to_L[i]; - curr_max_w = i; - } - } - } - } - - /** \brief Landmark choice strategy by taking random vertices for landmarks. - * - */ - - // template - void landmark_choice_by_random_points(Point_Vector &W, int nbP, std::set &L) - { - int current_number_of_landmarks=0; // counter for landmarks - - srand(24660); - int chosen_landmark = rand()%nbP; - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - while (L.find(chosen_landmark) != L.end()) - { - srand((int)clock()); - chosen_landmark = rand()% nbP; - } - L.insert(chosen_landmark); - } - } - - - /** \brief Construct the matrix |W|x(D+1) of D+1 closest landmarks - * where W is the set of witnesses and D is the ambient dimension - */ - template - void nearest_landmarks(Point_Vector &W, std::set &L, KNearestNeighbours &WL) - { - int D = W[0].size(); - int nbP = W.size(); - WL = KNearestNeighbours(nbP,std::vector()); - typedef std::pair dist_i; - typedef bool (*comp)(dist_i,dist_i); - for (int W_i = 0; W_i < nbP; W_i++) - { - std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); - std::set::iterator L_it; - int L_i; - for (L_it = L.begin(), L_i=0; L_it != L.end(); L_it++, L_i++) - { - dist_i dist = std::make_pair(euclidean_distance(W[W_i],W[*L_it]), L_i); - l_heap.push(dist); - } - for (int i = 0; i < D+1; i++) - { - dist_i dist = l_heap.top(); - WL[W_i].push_back(dist.second); - l_heap.pop(); - } - } - } - - - public: - /** \brief Verification if every simplex in the complex is witnessed + /** + * \brief Verification if every simplex in the complex is witnessed. + * \remark Added for debugging purposes. */ template< class KNearestNeighbors > - bool is_witness_complex(KNearestNeighbors WL) + bool is_witness_complex(KNearestNeighbors & knn) { //bool final_result = true; - for (Simplex_handle sh: complex_simplex_range()) + for (Simplex_handle sh: sc.complex_simplex_range()) { bool is_witnessed = false; typeVectorVertex simplex; int nbV = 0; //number of verticed in the simplex - for (int v: simplex_vertex_range(sh)) + for (int v: sc.simplex_vertex_range(sh)) simplex.push_back(v); nbV = simplex.size(); - for (typeVectorVertex w: WL) + for (typeVectorVertex w: knn) { bool has_vertices = true; for (int v: simplex) diff --git a/src/Witness_complex/include/gudhi/Witness_complex_doc.h b/src/Witness_complex/include/gudhi/Witness_complex_doc.h new file mode 100644 index 00000000..22cfe992 --- /dev/null +++ b/src/Witness_complex/include/gudhi/Witness_complex_doc.h @@ -0,0 +1,37 @@ +#ifndef WITNESS_COMPLEX_DOC_ +#define WITNESS_COMPLEX_DOC_ + +/** + \defgroup witness_complex Witness complex + + \author Siargey Kachanovich + + \section Definitions + + Witness complex \f$ Wit(W,L) \f$ is a simplicial complex defined on two sets of points in \f$\mathbb{R}^D\f$: + + \li \f$W\f$ set of **witnesses** and + \li \f$L \subseteq W\f$ set of **landmarks**. + + The simplices are based on landmarks + and a simplex belongs to the witness complex if and only if it is witnessed, that is: + + \f$ \sigma \subset L \f$ is witnessed if there exists a point \f$w \in W\f$ such that + w is closer to the vertices of \f$ \sigma \f$ than other points in \f$ L \f$ and all of its faces are witnessed as well. + + \section Implementation + + Two classes are implemented in this module: Gudhi::Witness_complex and Gudhi::Relaxed_witness_complex. + + While Gudhi::Witness_complex represents the classical witness complex, Gudhi::Relaxed_witness_complex takes an additional positive real parameter \f$ \alpha \f$ and constructs simplices \f$ \sigma \f$, for which + there exists \f$ w \in W \f$, such that \f$ d(p,w) < d(q,w) + \alpha \f$ for all \f$ p \in \sigma, q \in L\setminus \sigma \f$. + + In both cases, the constructors take a {witness}x{closest_landmarks} table, + which can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. + + \copyright GNU General Public License v3. + + + */ + +#endif -- cgit v1.2.3 From f3fa597138156c3b925ac970555f8482e964c968 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 10 Dec 2015 09:29:52 +0000 Subject: Added things git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@937 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4f0ae39ee1f68d8cce565ad0855edb3bff1e7f3f --- src/Doxyfile | 4 +- src/Witness_complex/doc/bench_Cy8.png | Bin 0 -> 15254 bytes src/Witness_complex/doc/bench_sphere.png | Bin 0 -> 16614 bytes src/Witness_complex/example/CMakeLists.txt | 26 +++++- .../example/simple_witness_complex.cpp | 4 +- .../example/witness_complex_from_file.cpp | 90 ++++++--------------- .../gudhi/Landmark_choice_by_furthest_point.h | 12 ++- .../gudhi/Landmark_choice_by_random_point.h | 16 ++-- .../include/gudhi/Witness_complex.h | 32 +++++--- .../include/gudhi/Witness_complex_doc.h | 11 +-- 10 files changed, 98 insertions(+), 97 deletions(-) create mode 100644 src/Witness_complex/doc/bench_Cy8.png create mode 100644 src/Witness_complex/doc/bench_sphere.png (limited to 'src') diff --git a/src/Doxyfile b/src/Doxyfile index faa0d3fe..6585e50c 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -834,8 +834,8 @@ EXAMPLE_RECURSIVE = NO IMAGE_PATH = doc/Skeleton_blocker/ \ doc/common/ \ - doc/Contraction/ - + doc/Contraction/ \ + doc/Witness_complex/ # 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/Witness_complex/doc/bench_Cy8.png b/src/Witness_complex/doc/bench_Cy8.png new file mode 100644 index 00000000..d9045294 Binary files /dev/null and b/src/Witness_complex/doc/bench_Cy8.png differ diff --git a/src/Witness_complex/doc/bench_sphere.png b/src/Witness_complex/doc/bench_sphere.png new file mode 100644 index 00000000..ba6bb381 Binary files /dev/null and b/src/Witness_complex/doc/bench_sphere.png differ diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 83f9c71c..4f5e33d4 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -6,6 +6,30 @@ project(GUDHIWitnessComplex) add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) add_executable( witness_complex_from_file witness_complex_from_file.cpp ) - #target_link_libraries(witness_complex_from_file ${EIGEN3_LIBRARIES} ${CGAL_LIBRARY}) add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_executable( witness_complex_bench witness_complex_bench.cpp ) + add_test( witness_complex_bench_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_bench ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + +if(CGAL_FOUND) + if (NOT CGAL_VERSION VERSION_LESS 4.6.0) + message(STATUS "CGAL version: ${CGAL_VERSION}.") + + include( ${CGAL_USE_FILE} ) + + find_package(Eigen3 3.1.0) + if (EIGEN3_FOUND) + message(STATUS "Eigen3 version: ${EIGEN3_VERSION}.") + include( ${EIGEN3_USE_FILE} ) + message(STATUS "Eigen3 use file: ${EIGEN3_USE_FILE}.") + include_directories (BEFORE "../../include") + + add_executable ( witness_complex_bench2 witness_complex_bench2.cpp ) + target_link_libraries(witness_complex_bench2 ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + else() + message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") + endif() + else() + message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") + endif () +endif() diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp index 6731f135..bcbf2362 100644 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ b/src/Witness_complex/example/simple_witness_complex.cpp @@ -50,8 +50,8 @@ int main (int argc, char * const argv[]) typeVectorVertex witness10 = {5,0,1,3,6,2,4}; knn.push_back(witness10); typeVectorVertex witness11 = {5,6,1,0,2,3,4}; knn.push_back(witness11); typeVectorVertex witness12 = {1,6,0,5,2,3,4}; knn.push_back(witness12); - WitnessComplex witnessComplex(knn, complex, 7); - if (witnessComplex.is_witness_complex(knn)) + WitnessComplex witnessComplex(knn, complex, 7, 7); + if (witnessComplex.is_witness_complex(knn, true)) std::cout << "Witness complex is good\n"; else std::cout << "Witness complex is bad\n"; diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 70c81528..6add4e0a 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -26,21 +26,18 @@ #include #include -//#include -//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Simplex_tree.h" #include "gudhi/Witness_complex.h" +#include "gudhi/Landmark_choice_by_random_point.h" #include "gudhi/reader_utils.h" -//#include using namespace Gudhi; -//using namespace boost::filesystem; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::vector< std::vector > Point_Vector; -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; +typedef Witness_complex< Simplex_tree<> > WitnessComplex; /** * \brief Customized version of read_points @@ -69,15 +66,15 @@ read_points_cust ( std::string file_name , std::vector< std::vector< double > > in_file.close(); } -void write_wl( std::string file_name, std::vector< std::vector > & WL) +/** Write a gnuplot readable file. + * Data range is a random access range of pairs (arg, value) + */ +template < typename Data_range > +void write_data( Data_range & data, std::string filename ) { - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : WL) - { - for (auto l: w) - ofs << l << " "; - ofs << "\n"; - } + std::ofstream ofs(filename, std::ofstream::out); + for (auto entry: data) + ofs << entry.first << ", " << entry.second << "\n"; ofs.close(); } @@ -89,68 +86,33 @@ int main (int argc, char * const argv[]) << " path_to_point_file nbL \n"; return 0; } - /* - boost::filesystem::path p; - for (; argc > 2; --argc, ++argv) - p /= argv[1]; - */ std::string file_name = argv[1]; int nbL = atoi(argv[2]); - clock_t start, end; - //Construct the Simplex Tree - Witness_complex<> witnessComplex; - - std::cout << "Let the carnage begin!\n"; + + // Construct the Simplex Tree + Simplex_tree<> simplex_tree; + + // Read the point file Point_Vector point_vector; read_points_cust(file_name, point_vector); - //std::cout << "Successfully read the points\n"; - witnessComplex.setNbL(nbL); - // witnessComplex.witness_complex_from_points(point_vector); - std::vector > WL; - std::set L; + std::cout << "Successfully read " << point_vector.size() << " points.\n"; + std::cout << "Ambient dimension is " << point_vector[0].size() << ".\n"; + + // Choose landmarks start = clock(); - //witnessComplex.landmark_choice_by_furthest_points(point_vector, point_vector.size(), WL); - witnessComplex.landmark_choice_by_random_points(point_vector, point_vector.size(), L); - witnessComplex.nearest_landmarks(point_vector,L,WL); + std::vector > knn; + Landmark_choice_by_random_point(point_vector, nbL, knn); end = clock(); std::cout << "Landmark choice for " << nbL << " landmarks took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - // Write the WL matrix in a file - mkdir("output", S_IRWXU); - const size_t last_slash_idx = file_name.find_last_of("/"); - if (std::string::npos != last_slash_idx) - { - file_name.erase(0, last_slash_idx + 1); - } - std::string out_file = "output/"+file_name+"_"+argv[2]+".wl"; - write_wl(out_file,WL); + + // Compute witness complex start = clock(); - witnessComplex.witness_complex(WL); - // + WitnessComplex(knn, simplex_tree, nbL, point_vector[0].size()); end = clock(); - std::cout << "Howdy world! The process took " + std::cout << "Witness complex took " << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - /* - char buffer[100]; - int i = sprintf(buffer,"%s_%s_result.txt",argv[1],argv[2]); - if (i >= 0) - { - std::string out_file = (std::string)buffer; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - } - */ - - out_file = "output/"+file_name+"_"+argv[2]+".stree"; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; - std::ofstream ofs2(out_file, std::ofstream::out); - witnessComplex.write_bad_links(ofs2); - ofs2.close(); } diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 44bf9dbb..0b196f18 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -31,18 +31,22 @@ * \ingroup witness_complex */ -class Landmark_choice_by_random_point { +class Landmark_choice_by_furthest_point { +public: + /** * \brief Landmark choice strategy by iteratively adding the furthest witness from the - * current landmark set as the new landmark. It takes a random access range `points` and + * current landmark set as the new landmark. + * \details It chooses nbL landmarks from a random access range `points` and * writes {witness}*{closest landmarks} matrix in `knn`. */ template - Landmark_choice_by_furthest_points(Point_random_access_range &points, - KNearestNeighbours &knn) + Landmark_choice_by_furthest_point(Point_random_access_range &points, + int nbL, + KNearestNeighbours &knn) { int nb_points = points.end() - points.begin(); std::vector> wit_land_dist(nb_points, std::vector()); // distance matrix witness x landmarks diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index bc3e72d9..fa822591 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -33,18 +33,19 @@ class Landmark_choice_by_random_point { - +public: + /** \brief Landmark choice strategy by taking random vertices for landmarks. - * It takes a random access range points and outputs a matrix {witness}*{closest landmarks} - * in knn. + * \details It chooses nbL distinct landmarks from a random access range `points` + * and outputs a matrix {witness}*{closest landmarks} in knn. */ template - void landmark_choice_by_random_points(Point_random_access_range &points, KNearestNeighbours &knn) + Landmark_choice_by_random_point(Point_random_access_range &points, int nbL, KNearestNeighbours &knn) { int nbP = points.end() - points.begin(); - std::set &landmarks; + std::set landmarks; int current_number_of_landmarks=0; // counter for landmarks int chosen_landmark = rand()%nbP; @@ -55,9 +56,10 @@ class Landmark_choice_by_random_point { landmarks.insert(chosen_landmark); } - int D = points.begin().size(); + int dim = points.begin()->size(); typedef std::pair dist_i; typedef bool (*comp)(dist_i,dist_i); + knn = KNearestNeighbours(nbP); for (int points_i = 0; points_i < nbP; points_i++) { std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2){return j1.first > j2.first;}); @@ -68,7 +70,7 @@ class Landmark_choice_by_random_point { dist_i dist = std::make_pair(euclidean_distance(points[points_i],points[*landmarks_it]), landmarks_i); l_heap.push(dist); } - for (int i = 0; i < D+1; i++) + for (int i = 0; i < dim+1; i++) { dist_i dist = l_heap.top(); knn[points_i].push_back(dist.second); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index b218611b..791d0e45 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -73,10 +73,11 @@ namespace Gudhi { typedef std::vector< double > Point_t; typedef std::vector< Point_t > Point_Vector; - + + typedef typename Simplicial_complex::Filtration_value Filtration_value; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; - typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + typedef std::pair< Simplex_handle, bool > typePairSimplexBool; typedef int Witness_id; typedef int Landmark_id; @@ -204,11 +205,12 @@ namespace Gudhi { public: /** - * \brief Verification if every simplex in the complex is witnessed. + * \brief Verification if every simplex in the complex is witnessed by witnesses in knn. + * \param print_output =true will print the witnesses for each simplex * \remark Added for debugging purposes. */ template< class KNearestNeighbors > - bool is_witness_complex(KNearestNeighbors & knn) + bool is_witness_complex(KNearestNeighbors & knn, bool print_output) { //bool final_result = true; for (Simplex_handle sh: sc.complex_simplex_range()) @@ -231,19 +233,25 @@ namespace Gudhi { if (has_vertices) { is_witnessed = true; - std::cout << "The simplex "; - print_vector(simplex); - std::cout << " is witnessed by the witness "; - print_vector(w); - std::cout << std::endl; + if (print_output) + { + std::cout << "The simplex "; + print_vector(simplex); + std::cout << " is witnessed by the witness "; + print_vector(w); + std::cout << std::endl; + } break; } } if (!is_witnessed) { - std::cout << "The following simplex is not witnessed "; - print_vector(simplex); - std::cout << std::endl; + if (print_output) + { + std::cout << "The following simplex is not witnessed "; + print_vector(simplex); + std::cout << std::endl; + } assert(is_witnessed); return false; } diff --git a/src/Witness_complex/include/gudhi/Witness_complex_doc.h b/src/Witness_complex/include/gudhi/Witness_complex_doc.h index 22cfe992..446f0d11 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex_doc.h +++ b/src/Witness_complex/include/gudhi/Witness_complex_doc.h @@ -21,14 +21,15 @@ \section Implementation - Two classes are implemented in this module: Gudhi::Witness_complex and Gudhi::Relaxed_witness_complex. + The principal class of this module is Gudhi::Witness_complex. - While Gudhi::Witness_complex represents the classical witness complex, Gudhi::Relaxed_witness_complex takes an additional positive real parameter \f$ \alpha \f$ and constructs simplices \f$ \sigma \f$, for which - there exists \f$ w \in W \f$, such that \f$ d(p,w) < d(q,w) + \alpha \f$ for all \f$ p \in \sigma, q \in L\setminus \sigma \f$. - - In both cases, the constructors take a {witness}x{closest_landmarks} table, + In both cases, the constructor for this class takes a {witness}x{closest_landmarks} table, which can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. + *\image html "bench_Cy8.png" "Running time as function on number of landmarks" width=10cm + *\image html "bench_sphere.png" "Running time as function on number of witnesses for |L|=300" width=10cm + + \copyright GNU General Public License v3. -- cgit v1.2.3 From 6775c601c9c9f7a1f0679dbb1fecb3bd5181eb6a Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 10 Dec 2015 09:38:37 +0000 Subject: Changed a phrase in doc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@938 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 407e6784210123fbd00b71efad0659f2d7c9263b --- src/Witness_complex/include/gudhi/Witness_complex_doc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex_doc.h b/src/Witness_complex/include/gudhi/Witness_complex_doc.h index 446f0d11..71c8776b 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex_doc.h +++ b/src/Witness_complex/include/gudhi/Witness_complex_doc.h @@ -23,8 +23,8 @@ The principal class of this module is Gudhi::Witness_complex. - In both cases, the constructor for this class takes a {witness}x{closest_landmarks} table, - which can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. + In both cases, the constructor for this class takes a {witness}x{closest_landmarks} table, where each row represents a witness and consists of landmarks sorted by distance to this witness. + This table can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. *\image html "bench_Cy8.png" "Running time as function on number of landmarks" width=10cm *\image html "bench_sphere.png" "Running time as function on number of witnesses for |L|=300" width=10cm -- cgit v1.2.3 From 1b802ff1bb1a4e245d3c3bb544a047df15e09a32 Mon Sep 17 00:00:00 2001 From: cjamin Date: Thu, 10 Dec 2015 15:55:03 +0000 Subject: Add cmake script to find TBB git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@939 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4caa2f3a1362b07219b7e7e7ca0d059cd73bdac0 --- src/cmake/modules/FindTBB.cmake | 433 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 src/cmake/modules/FindTBB.cmake (limited to 'src') diff --git a/src/cmake/modules/FindTBB.cmake b/src/cmake/modules/FindTBB.cmake new file mode 100644 index 00000000..414a929b --- /dev/null +++ b/src/cmake/modules/FindTBB.cmake @@ -0,0 +1,433 @@ +# Locate Intel Threading Building Blocks include paths and libraries +# FindTBB.cmake can be found at https://code.google.com/p/findtbb/ +# Written by Hannes Hofmann +# Improvements by Gino van den Bergen , +# Florian Uhlig , +# Jiri Marsik + +# The MIT License +# +# Copyright (c) 2011 Hannes Hofmann +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler. +# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21" +# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found +# in the TBB installation directory (TBB_INSTALL_DIR). +# +# GvdB: Mac OS X distribution places libraries directly in lib directory. +# +# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER. +# TBB_ARCHITECTURE [ ia32 | em64t | itanium ] +# which architecture to use +# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9 +# which compiler to use (detected automatically on Windows) + +# This module respects +# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR} + +# This module defines +# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc. +# TBB_LIBRARY_DIRS, where to find TBB libraries +# TBB_INSTALL_DIR, the base TBB install directory. +# TBB_LIBRARIES, all the following TBB libraries (both release and debug versions, using "optimized" and "debug" CMake keywords). Note that if the debug versions are not found, the release versions will be used instead for the debug mode. +# TBB_RELEASE_LIBRARY, the TBB release library +# TBB_MALLOC_RELEASE_LIBRARY, the TBB release malloc library +# TBB_DEBUG_LIBRARY, the TBB debug library +# TBB_MALLOC_DEBUG_LIBRARY, the TBB debug malloc library +# TBB_FOUND, If false, don't try to use TBB. +# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h +# TBB_MALLOCPROXY_DEBUG_LIBRARY, the TBB debug malloc_proxy library (not included in TBB_LIBRARIES since it's optionnal) +# TBB_MALLOCPROXY_RELEASE_LIBRARY, the TBB release malloc_proxy library (not included in TBB_LIBRARIES since it's optionnal) + +include(CheckCXXSourceCompiles) + +# Usage: +# try_TBB_with_pthread( [additional linker args...]) +function(try_TBB_with_pthread result_var) + set(TBB_try_ts_source " + #include + int main() { + tbb::enumerable_thread_specific< + bool*, + tbb::cache_aligned_allocator, + tbb::ets_key_per_instance> grid; + } + ") + set(CMAKE_REQUIRED_LIBRARIES ${ALL_TBB_LIBRARIES} ${ARGN}) + set(CMAKE_REQUIRED_INCLUDES ${TBB_INCLUDE_DIR}) + check_cxx_source_compiles("${TBB_try_ts_source}" ${result_var}) + set(${result_var} ${${result_var}} PARENT_SCOPE) +endfunction(try_TBB_with_pthread) + +if (WIN32) + # has em64t/vc8 em64t/vc9 + # has ia32/vc7.1 ia32/vc8 ia32/vc9 + set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB") + set(_TBB_LIB_RELEASE_NAME "tbb") + set(_TBB_LIB_MALLOC_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc") + set(_TBB_LIB_MALLOCPROXY_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc_proxy") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_RELEASE_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_RELEASE_NAME}_debug") + set(_TBB_LIB_MALLOCPROXY_DEBUG_NAME "${_TBB_LIB_MALLOCPROXY_RELEASE_NAME}_debug") + if (MSVC71) + set (_TBB_COMPILER "vc7.1") + endif(MSVC71) + if (MSVC80) + set(_TBB_COMPILER "vc8") + endif(MSVC80) + if (MSVC90) + set(_TBB_COMPILER "vc9") + endif(MSVC90) + if(MSVC10) + set(_TBB_COMPILER "vc10") + endif(MSVC10) + if(MSVC11) + set(_TBB_COMPILER "vc11") + endif(MSVC11) + if(MSVC12) + set(_TBB_COMPILER "vc12") + endif(MSVC12) + #note there was no MSVC13 + if(MSVC14) + if(RUNNING_CGAL_AUTO_TEST) + set (TBB_FOUND "NO") + return()#binaries for TBB not publicly available when CGAL-4.7 is published + endif(RUNNING_CGAL_AUTO_TEST) + message(STATUS "[Warning] FindTBB.cmake: TBB 4.4 (latest available when CGAL-4.7 is published) does not provide support for MSVC 2015.") + endif(MSVC14) + # Todo: add other Windows compilers such as ICL. + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) +endif (WIN32) + +if (UNIX) + if (APPLE) + # MAC + set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions") + # libs: libtbb.dylib, libtbbmalloc.dylib, *_debug + set(_TBB_LIB_RELEASE_NAME "tbb") + set(_TBB_LIB_MALLOC_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc") + #set(_TBB_LIB_MALLOCPROXY_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc_proxy") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_RELEASE_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_RELEASE_NAME}_debug") + #set(_TBB_LIB_MALLOCPROXY_DEBUG_NAME "${_TBB_LIB_MALLOCPROXY_RELEASE_NAME}_debug") + # default flavor on apple: ia32/cc4.0.1_os10.4.9 + # Jiri: There is no reason to presume there is only one flavor and + # that user's setting of variables should be ignored. + if(NOT TBB_COMPILER) + set(_TBB_COMPILER "cc4.0.1_os10.4.9") + elseif (NOT TBB_COMPILER) + set(_TBB_COMPILER ${TBB_COMPILER}) + endif(NOT TBB_COMPILER) + if(NOT TBB_ARCHITECTURE) + set(_TBB_ARCHITECTURE "ia32") + elseif(NOT TBB_ARCHITECTURE) + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) + endif(NOT TBB_ARCHITECTURE) + else (APPLE) + # LINUX + set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include") + set(_TBB_LIB_RELEASE_NAME "tbb") + set(_TBB_LIB_MALLOC_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc") + set(_TBB_LIB_MALLOCPROXY_RELEASE_NAME "${_TBB_LIB_RELEASE_NAME}malloc_proxy") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_RELEASE_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_RELEASE_NAME}_debug") + set(_TBB_LIB_MALLOCPROXY_DEBUG_NAME "${_TBB_LIB_MALLOCPROXY_RELEASE_NAME}_debug") + # has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21 + # has ia32/* + # has itanium/* + set(_TBB_COMPILER ${TBB_COMPILER}) + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) + endif (APPLE) +endif (UNIX) + +if (CMAKE_SYSTEM MATCHES "SunOS.*") +# SUN +# not yet supported +# has em64t/cc3.4.3_kernel5.10 +# has ia32/* +endif (CMAKE_SYSTEM MATCHES "SunOS.*") + + +#-- Clear the public variables +set (TBB_FOUND "NO") + + +#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR} +# first: use CMake variable TBB_INSTALL_DIR +if (TBB_INSTALL_DIR) + set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR}) +endif (TBB_INSTALL_DIR) +# second: use environment variable +if (NOT _TBB_INSTALL_DIR) + if (NOT "$ENV{TBBROOT}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBBROOT}) + endif (NOT "$ENV{TBBROOT}" STREQUAL "") + if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR}) + endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") + # Intel recommends setting TBB21_INSTALL_DIR + if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR}) + endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") + if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR}) + endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") + if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR}) + endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") +endif (NOT _TBB_INSTALL_DIR) +# third: try to find path automatically +if (NOT _TBB_INSTALL_DIR) + if (_TBB_DEFAULT_INSTALL_DIR) + set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR}) + endif (_TBB_DEFAULT_INSTALL_DIR) +endif (NOT _TBB_INSTALL_DIR) +# sanity check +if (NOT _TBB_INSTALL_DIR) + message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}") +else (NOT _TBB_INSTALL_DIR) +# finally: set the cached CMake variable TBB_INSTALL_DIR +if (NOT TBB_INSTALL_DIR) + set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory") + mark_as_advanced(TBB_INSTALL_DIR) +endif (NOT TBB_INSTALL_DIR) + + +#-- A macro to rewrite the paths of the library. This is necessary, because +# find_library() always found the em64t/vc9 version of the TBB libs +macro(TBB_CORRECT_LIB_DIR var_name) +# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") + string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) +# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") + string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) + string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc11 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) +endmacro(TBB_CORRECT_LIB_DIR var_content) + + +#-- Look for include directory and set ${TBB_INCLUDE_DIR} +set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include) +# Jiri: tbbvars now sets the CPATH environment variable to the directory +# containing the headers. +# LR: search first with NO_DEFAULT_PATH... +find_path(TBB_INCLUDE_DIR + tbb/task_scheduler_init.h + PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH + NO_DEFAULT_PATH +) +if(NOT TBB_INCLUDE_DIR) +# LR: ... and then search again with NO_DEFAULT_PATH if nothing was found in +# hinted paths + find_path(TBB_INCLUDE_DIR + tbb/task_scheduler_init.h + PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH + ) +endif() +mark_as_advanced(TBB_INCLUDE_DIR) + + +#-- Look for libraries +# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] +if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") + set (_TBB_LIBRARY_DIR + ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} + ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib + ) +endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") +# Jiri: This block isn't mutually exclusive with the previous one +# (hence no else), instead I test if the user really specified +# the variables in question. +if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) + # HH: deprecated + message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).") + # Jiri: It doesn't hurt to look in more places, so I store the hints from + # ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER + # variables and search them both. + set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR}) +endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) + +# GvdB: Mac OS X distribution places libraries directly in lib directory. +list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib) + +# Jiri: No reason not to check the default paths. From recent versions, +# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH +# variables, which now point to the directories of the lib files. +# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS +# argument instead of the implicit PATHS as it isn't hard-coded +# but computed by system introspection. Searching the LIBRARY_PATH +# and LD_LIBRARY_PATH environment variables is now even more important +# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates +# the use of TBB built from sources. +# LR: search first with NO_DEFAULT_PATH... +find_library(TBB_RELEASE_LIBRARY ${_TBB_LIB_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +find_library(TBB_MALLOC_RELEASE_LIBRARY ${_TBB_LIB_MALLOC_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +find_library(TBB_MALLOCPROXY_RELEASE_LIBRARY ${_TBB_LIB_MALLOCPROXY_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +if(NOT TBB_RELEASE_LIBRARY OR NOT TBB_MALLOC_RELEASE_LIBRARY OR NOT TBB_MALLOCPROXY_RELEASE_LIBRARY) +# LR: ... and then search again with NO_DEFAULT_PATH if nothing was found +# in hinted paths + find_library(TBB_RELEASE_LIBRARY ${_TBB_LIB_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + find_library(TBB_MALLOC_RELEASE_LIBRARY ${_TBB_LIB_MALLOC_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + find_library(TBB_MALLOCPROXY_RELEASE_LIBRARY ${_TBB_LIB_MALLOCPROXY_RELEASE_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) +endif() + +#Extract path from TBB_RELEASE_LIBRARY name +get_filename_component(TBB_RELEASE_LIBRARY_DIR ${TBB_RELEASE_LIBRARY} PATH) + +#TBB_CORRECT_LIB_DIR(TBB_RELEASE_LIBRARY) +#TBB_CORRECT_LIB_DIR(TBB_MALLOC_RELEASE_LIBRARY) +#TBB_CORRECT_LIB_DIR(TBB_MALLOCPROXY_RELEASE_LIBRARY) +mark_as_advanced(TBB_RELEASE_LIBRARY TBB_MALLOC_RELEASE_LIBRARY TBB_MALLOCPROXY_RELEASE_LIBRARY) + +#-- Look for debug libraries +# Jiri: Changed the same way as for the release libraries. +find_library(TBB_DEBUG_LIBRARY ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +find_library(TBB_MALLOC_DEBUG_LIBRARY ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +find_library(TBB_MALLOCPROXY_DEBUG_LIBRARY ${_TBB_LIB_MALLOCPROXY_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH NO_DEFAULT_PATH) +if(NOT TBB_DEBUG_LIBRARY OR NOT TBB_MALLOC_DEBUG_LIBRARY OR NOT TBB_MALLOCPROXY_DEBUG_LIBRARY) + find_library(TBB_DEBUG_LIBRARY ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + find_library(TBB_MALLOC_DEBUG_LIBRARY ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + find_library(TBB_MALLOCPROXY_DEBUG_LIBRARY ${_TBB_LIB_MALLOCPROXY_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) +endif() + +# Jiri: Self-built TBB stores the debug libraries in a separate directory. +# Extract path from TBB_DEBUG_LIBRARY name +get_filename_component(TBB_DEBUG_LIBRARY_DIR ${TBB_DEBUG_LIBRARY} PATH) + +#TBB_CORRECT_LIB_DIR(TBB_DEBUG_LIBRARY) +#TBB_CORRECT_LIB_DIR(TBB_MALLOC_DEBUG_LIBRARY) +#TBB_CORRECT_LIB_DIR(TBB_MALLOCPROXY_DEBUG_LIBRARY) +mark_as_advanced(TBB_DEBUG_LIBRARY TBB_MALLOC_DEBUG_LIBRARY TBB_MALLOCPROXY_DEBUG_LIBRARY) + +if (TBB_INCLUDE_DIR) + if (TBB_RELEASE_LIBRARY) + set (TBB_FOUND "YES") + + # NOTE: Removed because we don't want to link with the malloc_proxy by default + #if (NOT "${TBB_MALLOCPROXY_RELEASE_LIBRARY}" STREQUAL "TBB_MALLOCPROXY_RELEASE_LIBRARY-NOTFOUND") + # mark_as_advanced(TBB_MALLOCPROXY_RELEASE_LIBRARY) + # set (_TBB_MALLOCPROXY optimized ${TBB_MALLOCPROXY_RELEASE_LIBRARY}) + #endif (NOT "${TBB_MALLOCPROXY_RELEASE_LIBRARY}" STREQUAL "TBB_MALLOCPROXY_RELEASE_LIBRARY-NOTFOUND") + #if (NOT "${TBB_MALLOCPROXY_DEBUG_LIBRARY}" STREQUAL "TBB_MALLOCPROXY_DEBUG_LIBRARY-NOTFOUND") + # mark_as_advanced(TBB_MALLOCPROXY_DEBUG_LIBRARY) + # set (_TBB_MALLOCPROXY ${_TBB_MALLOCPROXY} debug ${TBB_MALLOCPROXY_DEBUG_LIBRARY}) + #endif (NOT "${TBB_MALLOCPROXY_DEBUG_LIBRARY}" STREQUAL "TBB_MALLOCPROXY_DEBUG_LIBRARY-NOTFOUND") + + # TBB release library + set (ALL_TBB_LIBRARIES optimized ${TBB_RELEASE_LIBRARY}) + + # TBB debug library found? + if (TBB_DEBUG_LIBRARY) + list(APPEND ALL_TBB_LIBRARIES debug ${TBB_DEBUG_LIBRARY}) + else (TBB_DEBUG_LIBRARY) + # Otherwise, link with the release library even in debug mode + list(APPEND ALL_TBB_LIBRARIES debug ${TBB_RELEASE_LIBRARY}) + endif (TBB_DEBUG_LIBRARY) + + # TBB malloc - release + if (TBB_MALLOC_RELEASE_LIBRARY) + list(APPEND ALL_TBB_LIBRARIES optimized ${TBB_MALLOC_RELEASE_LIBRARY}) + + # TBB malloc - debug + if (TBB_MALLOC_DEBUG_LIBRARY) + list(APPEND ALL_TBB_LIBRARIES debug ${TBB_MALLOC_DEBUG_LIBRARY}) + else (TBB_MALLOC_DEBUG_LIBRARY) + list(APPEND ALL_TBB_LIBRARIES debug ${TBB_MALLOC_RELEASE_LIBRARY}) + endif (TBB_MALLOC_DEBUG_LIBRARY) + endif (TBB_MALLOC_RELEASE_LIBRARY) + + if(UNIX AND NOT APPLE) + # On Fedora, code using TBB might need -pthread + + # First check without pthread + try_TBB_with_pthread(TBB_without_pthread) + + if(NOT TBB_without_pthread) + # Then check with -pthread + try_TBB_with_pthread(TBB_with_pthread -pthread) + if(TBB_with_pthread) + list(APPEND ALL_TBB_LIBRARIES general -pthread) + endif(TBB_with_pthread) + endif(NOT TBB_without_pthread) + endif(UNIX AND NOT APPLE) + + set (TBB_LIBRARIES ${ALL_TBB_LIBRARIES} + CACHE PATH "TBB libraries" FORCE) + + # Include dirs + set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE) + + # Library dirs + if( "${TBB_DEBUG_LIBRARY_DIR}" STREQUAL "" OR "${TBB_RELEASE_LIBRARY_DIR}" STREQUAL "${TBB_DEBUG_LIBRARY_DIR}" ) + set (TBB_LIBRARY_DIRS + ${TBB_RELEASE_LIBRARY_DIR} + CACHE PATH "TBB library directories" FORCE) + else( "${TBB_DEBUG_LIBRARY_DIR}" STREQUAL "" OR "${TBB_RELEASE_LIBRARY_DIR}" STREQUAL "${TBB_DEBUG_LIBRARY_DIR}" ) + set (TBB_LIBRARY_DIRS + ${TBB_RELEASE_LIBRARY_DIR} ${TBB_DEBUG_LIBRARY_DIR} + CACHE PATH "TBB library directories" FORCE) + endif( "${TBB_DEBUG_LIBRARY_DIR}" STREQUAL "" OR "${TBB_RELEASE_LIBRARY_DIR}" STREQUAL "${TBB_DEBUG_LIBRARY_DIR}" ) + + message(STATUS "Found Intel TBB") + endif (TBB_RELEASE_LIBRARY) +endif (TBB_INCLUDE_DIR) + +if (NOT TBB_FOUND) + if(NOT TBB_FIND_QUIETLY) + message("ERROR: Intel TBB NOT found! Please define the TBBROOT (or TBB_INSTALL_DIR) and/or TBB_ARCH_PLATFORM environment variables.") + message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") + endif(NOT TBB_FIND_QUIETLY) + SET(TBB_INSTALL_DIR "TBB_INSTALL_DIR_NOT_FOUND" CACHE STRING "Intel TBB install directory") + # do only throw fatal, if this pkg is REQUIRED + if (TBB_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find TBB library.") + endif (TBB_FIND_REQUIRED) +endif (NOT TBB_FOUND) + +endif (NOT _TBB_INSTALL_DIR) + +if (TBB_FOUND) + set(TBB_INTERFACE_VERSION 0) + FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS) + STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}") + set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}") +endif (TBB_FOUND) + +set(TBB_USE_FILE "UseTBB") + +### ** Emacs settings ** +### Local Variables: +### cmake-tab-width: 4 +### End: -- cgit v1.2.3 From 9aa0cbbea297ea5996eb0d7fa2fcec3f3b773c98 Mon Sep 17 00:00:00 2001 From: cjamin Date: Thu, 10 Dec 2015 16:03:15 +0000 Subject: Forgot UseTBB.cmake git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@940 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bf6c4d9a54798895a34b89d655f7817534feb8b5 --- src/cmake/modules/UseTBB.cmake | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/cmake/modules/UseTBB.cmake (limited to 'src') diff --git a/src/cmake/modules/UseTBB.cmake b/src/cmake/modules/UseTBB.cmake new file mode 100644 index 00000000..9d09bf3e --- /dev/null +++ b/src/cmake/modules/UseTBB.cmake @@ -0,0 +1,6 @@ +# This module setups the compiler for using TBB library. +# It assumes that find_package(TBB) was already called. + +include_directories ( ${TBB_INCLUDE_DIRS} ) +link_directories( ${TBB_LIBRARY_DIRS} ) +add_definitions( -DNOMINMAX -DGUDHI_LINKED_WITH_TBB ) -- cgit v1.2.3 From f82dc289e2ebe3eb257c42f27876fbc1c64341dd Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 11 Dec 2015 08:08:40 +0000 Subject: Clarify the semantics of FilteredComplex::simplex(key). git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@941 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a2cb908a642ef53c5de25ba5113e03bb45652b9b --- src/Persistent_cohomology/concept/FilteredComplex.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/concept/FilteredComplex.h b/src/Persistent_cohomology/concept/FilteredComplex.h index 1834903b..e124d524 100644 --- a/src/Persistent_cohomology/concept/FilteredComplex.h +++ b/src/Persistent_cohomology/concept/FilteredComplex.h @@ -65,9 +65,9 @@ struct FilteredComplex Simplex_key key ( Simplex_handle sh ); /** \brief Returns the simplex associated to a key. * - * If key is different from null_key(), there must be a unique - * simplex having this key. */ - Simplex_handle simplex ( Simplex_key key ); + * If key is different from null_key(), returns the simplex that + * has index idx in the filtration. */ + Simplex_handle simplex ( Simplex_key idx ); /** \brief Assign a key to a simplex. */ void assign_key(Simplex_handle sh, Simplex_key key); -- cgit v1.2.3 From 4f73cb4a01692dbbe9547177b5b59425eae0d157 Mon Sep 17 00:00:00 2001 From: glisse Date: Tue, 15 Dec 2015 12:24:25 +0000 Subject: Don't use boost::tuple. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@946 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3988b09fafda67297cac8bd68629310cdfdc607e --- src/GudhUI/utils/K_nearest_builder.h | 10 ++++------ .../include/gudhi/Persistent_cohomology.h | 3 +-- .../gudhi/Persistent_cohomology/Persistent_cohomology_column.h | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/GudhUI/utils/K_nearest_builder.h b/src/GudhUI/utils/K_nearest_builder.h index cab24b7c..7be0a4f4 100644 --- a/src/GudhUI/utils/K_nearest_builder.h +++ b/src/GudhUI/utils/K_nearest_builder.h @@ -29,12 +29,10 @@ #include #include #include -#include -#include #include -#include #include +#include #include "utils/UI_utils.h" #include "model/Complex_typedefs.h" @@ -43,9 +41,9 @@ template class K_nearest_builder { private: typedef Geometry_trait Kernel; typedef Point Point_d; - typedef boost::tuple Point_d_with_id; + typedef std::pair Point_d_with_id; typedef CGAL::Search_traits_d Traits_base; - typedef CGAL::Search_traits_adapter, + typedef CGAL::Search_traits_adapter, Traits_base> Traits; typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; typedef Neighbor_search::Tree Tree; @@ -81,7 +79,7 @@ template class K_nearest_builder { for (auto p : complex_.vertex_range()) { Neighbor_search search(tree, complex_.point(p), k + 1); for (auto it = ++search.begin(); it != search.end(); ++it) { - Vertex_handle q(boost::get<1>(it->first)); + Vertex_handle q(std::get<1>(it->first)); if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q)) complex_.add_edge(p, q); } diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h index 2a405830..643b810c 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -223,7 +222,7 @@ class Persistent_cohomology { // Sparse column type for the annotation of the boundary of an element. typedef std::vector > A_ds_type; // Persistent interval type. The Arith_element field is used for the multi-field framework. - typedef boost::tuple Persistent_interval; + typedef std::tuple Persistent_interval; /** \brief Initializes the Persistent_cohomology class. * diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h index 612658e6..5deb2d88 100644 --- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology/Persistent_cohomology_column.h @@ -23,7 +23,6 @@ #ifndef PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_ #define PERSISTENT_COHOMOLOGY_PERSISTENT_COHOMOLOGY_COLUMN_H_ -#include #include #include -- cgit v1.2.3 From d91d9248c66451a765f58b6d03db2124b52c3ae2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 7 Jan 2016 13:34:00 +0000 Subject: Cppcheck fixes after merge git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@951 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4b66d24e46b604e2066c4c2e506b147af4be7e6a --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 6 +++--- .../include/gudhi/Simplex_tree/Simplex_tree_iterators.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 408c0588..50c67185 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -571,9 +571,9 @@ class Simplex_tree { public: /** \private \brief Test if the vertices have contiguous numbering: 0, 1, etc. */ bool contiguous_vertices() const { - if(root_.members_.empty()) return true; - if(root_.members_.begin()->first!=0) return false; - if(std::prev(root_.members_.end())->first!=root_.members_.size()-1) return false; + if (root_.members_.empty()) return true; + if (root_.members_.begin()->first != 0) return false; + if (std::prev(root_.members_.end())->first != root_.members_.size()-1) return false; return true; } diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h index c5027f22..794060ee 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h @@ -99,11 +99,13 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< // any end() iterator explicit Simplex_tree_boundary_simplex_iterator(SimplexTree * st) - : sh_(st->null_simplex()) { + : sib_(NULL), + sh_(st->null_simplex()) { } Simplex_tree_boundary_simplex_iterator(SimplexTree * st, Simplex_handle sh) : suffix_(), + sib_(st->self_siblings(sh)), st_(st) { last_ = sh->first; Siblings * sib = st->self_siblings(sh); @@ -137,9 +139,7 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< Siblings * for_sib = sib_; Siblings * new_sib = sib_->oncles(); auto rit = suffix_.rbegin(); - if (SimplexTree::Options::contiguous_vertices - && new_sib == nullptr - && rit != suffix_.rend()) { + if (SimplexTree::Options::contiguous_vertices && new_sib == nullptr && rit != suffix_.rend()) { // We reached the root, use a short-cut to find a vertex. We could also // optimize finding the second vertex of a segment, but people are // expected to call endpoints(). -- cgit v1.2.3 From 0a5b697f959d673fd51d70058fd3fe90f7c15125 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 7 Jan 2016 15:11:09 +0000 Subject: TBB find package mechanism with definition for code purpose. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/tbb@952 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9b4dcb962d1af208feccf831171029479d37831e --- CMakeLists.txt | 4 ++++ src/CMakeLists.txt | 4 ++++ src/cmake/modules/UseTBB.cmake | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index ae089562..edf7e63f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,10 @@ endif() find_package(CGAL) +# Find TBB package for parallel sort - not mandatory, just optional. +set(TBB_FIND_QUIETLY ON) +find_package(TBB) + # Required programs for unitary tests purpose FIND_PROGRAM( GCOVR_PATH gcovr ) if (GCOVR_PATH) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a84090e9..0e8de7cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,10 @@ endif() find_package(CGAL) +# Find TBB package for parallel sort - not mandatory, just optional. +set(TBB_FIND_QUIETLY ON) +find_package(TBB) + if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") else() diff --git a/src/cmake/modules/UseTBB.cmake b/src/cmake/modules/UseTBB.cmake index 9d09bf3e..e1ef5dfe 100644 --- a/src/cmake/modules/UseTBB.cmake +++ b/src/cmake/modules/UseTBB.cmake @@ -3,4 +3,4 @@ include_directories ( ${TBB_INCLUDE_DIRS} ) link_directories( ${TBB_LIBRARY_DIRS} ) -add_definitions( -DNOMINMAX -DGUDHI_LINKED_WITH_TBB ) +add_definitions( -DNOMINMAX -DGUDHI_USE_TBB ) -- cgit v1.2.3 From 9aa92aa2b504d9530125a6a164f76c11f45d8bb5 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 8 Jan 2016 15:03:16 +0000 Subject: cpplint and cppcheck fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@956 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f54c0a2a375e8818c7162aec05249e446361834b --- src/Hasse_complex/include/gudhi/Hasse_complex.h | 10 ++-- .../example/parallel_rips_persistence.cpp | 2 +- src/Simplex_tree/include/gudhi/Simplex_tree.h | 4 +- .../gudhi/Simplex_tree/Simplex_tree_iterators.h | 60 ++++++++++++---------- .../gudhi/Simplex_tree/Simplex_tree_siblings.h | 2 +- src/common/include/gudhi/allocator.h | 10 ++-- 6 files changed, 47 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/Hasse_complex/include/gudhi/Hasse_complex.h b/src/Hasse_complex/include/gudhi/Hasse_complex.h index 38887264..8b06b771 100644 --- a/src/Hasse_complex/include/gudhi/Hasse_complex.h +++ b/src/Hasse_complex/include/gudhi/Hasse_complex.h @@ -23,14 +23,14 @@ #ifndef HASSE_COMPLEX_H_ #define HASSE_COMPLEX_H_ +#include + #include #include #include // for pair #include -#include - #ifdef GUDHI_USE_TBB #include #endif @@ -109,12 +109,12 @@ class Hasse_complex { , dim_max_(cpx.dimension()) { int size = complex_.size(); #ifdef GUDHI_USE_TBB - tbb::parallel_for(0,size,[&](int idx){new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));}); - for (int idx=0; idx #include #include -#include "gudhi/Hasse_complex.h" +#include #include diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 356deb3a..708cdef9 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -528,7 +528,7 @@ class Simplex_tree { * The type InputVertexRange must be a range of Vertex_handle * on which we can call std::begin() function */ - template> + template> Simplex_handle find(const InputVertexRange & s) { auto first = std::begin(s); auto last = std::end(s); @@ -635,7 +635,7 @@ class Simplex_tree { * * The type InputVertexRange must be a range for which .begin() and * .end() return input iterators, with 'value_type' Vertex_handle. */ - template> + template> std::pair insert_simplex(const InputVertexRange & simplex, Filtration_value filtration = 0) { auto first = std::begin(simplex); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h index 794060ee..936b7a1f 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_iterators.h @@ -54,7 +54,7 @@ class Simplex_tree_simplex_vertex_iterator : public boost::iterator_facade< explicit Simplex_tree_simplex_vertex_iterator(SimplexTree * st) : // any end() iterator - sib_(NULL), + sib_(nullptr), v_(st->null_vertex()) { } @@ -99,19 +99,19 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< // any end() iterator explicit Simplex_tree_boundary_simplex_iterator(SimplexTree * st) - : sib_(NULL), - sh_(st->null_simplex()) { + : sib_(nullptr), + sh_(st->null_simplex()), + st_(st) { } Simplex_tree_boundary_simplex_iterator(SimplexTree * st, Simplex_handle sh) - : suffix_(), - sib_(st->self_siblings(sh)), + : last_(sh->first), + sib_(nullptr), st_(st) { - last_ = sh->first; Siblings * sib = st->self_siblings(sh); next_ = sib->parent(); - sib_ = sib->oncles(); /* \todo check if NULL*/ - if (sib_ != NULL) { + sib_ = sib->oncles(); + if (sib_ != nullptr) { sh_ = sib_->find(next_); } else { sh_ = st->null_simplex(); @@ -131,7 +131,7 @@ class Simplex_tree_boundary_simplex_iterator : public boost::iterator_facade< } void increment() { - if (sib_ == NULL) { + if (sib_ == nullptr) { sh_ = st_->null_simplex(); return; } @@ -189,13 +189,15 @@ class Simplex_tree_complex_simplex_iterator : public boost::iterator_facade< // any end() iterator Simplex_tree_complex_simplex_iterator() - : st_(NULL) { + : sib_(nullptr), + st_(nullptr) { } explicit Simplex_tree_complex_simplex_iterator(SimplexTree * st) - : st_(st) { - if (st == NULL || st->root() == NULL || st->root()->members().empty()) { - st_ = NULL; + : sib_(nullptr), + st_(st) { + if (st == nullptr || st->root() == nullptr || st->root()->members().empty()) { + st_ = nullptr; } else { sh_ = st->root()->members().begin(); sib_ = st->root(); @@ -210,10 +212,10 @@ class Simplex_tree_complex_simplex_iterator : public boost::iterator_facade< // valid when iterating along the SAME boundary. bool equal(Simplex_tree_complex_simplex_iterator const& other) const { - if (other.st_ == NULL) { - return (st_ == NULL); + if (other.st_ == nullptr) { + return (st_ == nullptr); } - if (st_ == NULL) { + if (st_ == nullptr) { return false; } return (&(sh_->second) == &(other.sh_->second)); @@ -227,8 +229,8 @@ class Simplex_tree_complex_simplex_iterator : public boost::iterator_facade< void increment() { ++sh_; if (sh_ == sib_->members().end()) { - if (sib_->oncles() == NULL) { - st_ = NULL; + if (sib_->oncles() == nullptr) { + st_ = nullptr; return; } // reach the end sh_ = sib_->oncles()->members().find(sib_->parent()); @@ -261,15 +263,19 @@ class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade< // any end() iterator Simplex_tree_skeleton_simplex_iterator() - : st_(NULL) { + : sib_(nullptr), + st_(nullptr), + dim_skel_(0), + curr_dim_(0) { } Simplex_tree_skeleton_simplex_iterator(SimplexTree * st, int dim_skel) - : st_(st), + : sib_(nullptr), + st_(st), dim_skel_(dim_skel), curr_dim_(0) { - if (st == NULL || st->root() == NULL || st->root()->members().empty()) { - st_ = NULL; + if (st == nullptr || st->root() == nullptr || st->root()->members().empty()) { + st_ = nullptr; } else { sh_ = st->root()->members().begin(); sib_ = st->root(); @@ -285,10 +291,10 @@ class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade< // valid when iterating along the SAME boundary. bool equal(Simplex_tree_skeleton_simplex_iterator const& other) const { - if (other.st_ == NULL) { - return (st_ == NULL); + if (other.st_ == nullptr) { + return (st_ == nullptr); } - if (st_ == NULL) { + if (st_ == nullptr) { return false; } return (&(sh_->second) == &(other.sh_->second)); @@ -302,8 +308,8 @@ class Simplex_tree_skeleton_simplex_iterator : public boost::iterator_facade< void increment() { ++sh_; if (sh_ == sib_->members().end()) { - if (sib_->oncles() == NULL) { - st_ = NULL; + if (sib_->oncles() == nullptr) { + st_ = nullptr; return; } // reach the end sh_ = sib_->oncles()->members().find(sib_->parent()); diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h index 158ee1f7..072afc8d 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree/Simplex_tree_siblings.h @@ -57,7 +57,7 @@ class Simplex_tree_siblings { /* Default constructor.*/ Simplex_tree_siblings() - : oncles_(NULL), + : oncles_(nullptr), parent_(-1), members_() { } diff --git a/src/common/include/gudhi/allocator.h b/src/common/include/gudhi/allocator.h index b825173b..4ede14e4 100644 --- a/src/common/include/gudhi/allocator.h +++ b/src/common/include/gudhi/allocator.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef GUDHI_ALLOCATOR_H_ -#define GUDHI_ALLOCATOR_H_ +#ifndef ALLOCATOR_H_ +#define ALLOCATOR_H_ #include #include @@ -43,13 +43,13 @@ struct no_init_allocator : Base { // Do nothing: that's the whole point! template - void construct(P*)noexcept{} + void construct(P*) noexcept {} - template void construct(P*p, U&&...u){ + template void construct(P*p, U&&...u) { Base_traits::construct(*(Base*)this, p, std::forward(u)...); } }; } // namespace Gudhi -#endif // GUDHI_ALLOCATOR_H_ +#endif // ALLOCATOR_H_ -- cgit v1.2.3 From 7e40efa04f1cc528f49da82df1502af85feb78d1 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 13 Jan 2016 19:08:03 +0000 Subject: Added a test, moved the old test from example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@964 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5744fdd3d30735cebdbd7442f023585a70bf0fca --- src/Witness_complex/example/CMakeLists.txt | 3 - .../example/simple_witness_complex.cpp | 58 ------------------ .../gudhi/Landmark_choice_by_furthest_point.h | 71 +++++++++++----------- .../test/simple_witness_complex.cpp | 55 +++++++++++++++++ .../test/witness_complex_points.cpp | 64 +++++++++++++++++++ 5 files changed, 155 insertions(+), 96 deletions(-) delete mode 100644 src/Witness_complex/example/simple_witness_complex.cpp create mode 100644 src/Witness_complex/test/simple_witness_complex.cpp create mode 100644 src/Witness_complex/test/witness_complex_points.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 4f5e33d4..4473078a 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -2,9 +2,6 @@ cmake_minimum_required(VERSION 2.6) project(GUDHIWitnessComplex) # A simple example - add_executable ( simple_witness_complex simple_witness_complex.cpp ) - add_test(simple_witness_complex ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) - add_executable( witness_complex_from_file witness_complex_from_file.cpp ) add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) diff --git a/src/Witness_complex/example/simple_witness_complex.cpp b/src/Witness_complex/example/simple_witness_complex.cpp deleted file mode 100644 index bcbf2362..00000000 --- a/src/Witness_complex/example/simple_witness_complex.cpp +++ /dev/null @@ -1,58 +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) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -//#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Simplex_tree.h" -#include "gudhi/Witness_complex.h" - -using namespace Gudhi; - -typedef std::vector< Vertex_handle > typeVectorVertex; -typedef Witness_complex> WitnessComplex; -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -int main (int argc, char * const argv[]) -{ - Simplex_tree<> complex; - std::vector< typeVectorVertex > knn; - typeVectorVertex witness0 = {1,0,5,2,6,3,4}; knn.push_back(witness0 ); - typeVectorVertex witness1 = {2,6,4,5,0,1,3}; knn.push_back(witness1 ); - typeVectorVertex witness2 = {3,4,2,1,5,6,0}; knn.push_back(witness2 ); - typeVectorVertex witness3 = {4,2,1,3,5,6,0}; knn.push_back(witness3 ); - typeVectorVertex witness4 = {5,1,6,0,2,3,4}; knn.push_back(witness4 ); - typeVectorVertex witness5 = {6,0,5,2,1,3,4}; knn.push_back(witness5 ); - typeVectorVertex witness6 = {0,5,6,1,2,3,4}; knn.push_back(witness6 ); - typeVectorVertex witness7 = {2,6,4,5,3,1,0}; knn.push_back(witness7 ); - typeVectorVertex witness8 = {1,2,5,4,3,6,0}; knn.push_back(witness8 ); - typeVectorVertex witness9 = {3,4,0,6,5,1,2}; knn.push_back(witness9 ); - typeVectorVertex witness10 = {5,0,1,3,6,2,4}; knn.push_back(witness10); - typeVectorVertex witness11 = {5,6,1,0,2,3,4}; knn.push_back(witness11); - typeVectorVertex witness12 = {1,6,0,5,2,3,4}; knn.push_back(witness12); - WitnessComplex witnessComplex(knn, complex, 7, 7); - if (witnessComplex.is_witness_complex(knn, true)) - std::cout << "Witness complex is good\n"; - else - std::cout << "Witness complex is bad\n"; -} diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 0b196f18..ebee96ad 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -33,6 +33,9 @@ class Landmark_choice_by_furthest_point { +private: + typedef std::vector typeVectorVertex; + public: /** @@ -57,45 +60,43 @@ public: double curr_max_dist = 0; // used for defining the furhest point from L const double infty = std::numeric_limits::infinity(); // infinity (see next entry) std::vector< double > dist_to_L(nb_points,infty); // vector of current distances to L from points + int dim = points.begin()->size(); - //CHOICE OF THE FIRST LANDMARK - int rand_int = rand() % nb_points; - int curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here - - for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) - { - //curr_max_w at this point is the next landmark - chosen_landmarks.push_back(curr_max_w); - for (auto v: knn) - v.push_back(current_number_of_landmarks); - int i = 0; - for (const auto& p: points) - { - // used to stock the distance from the current point to L - double curr_dist = euclidean_distance(p, points.begin() + chosen_landmarks[current_number_of_landmarks]); - wit_land_dist[i].push_back(curr_dist); - knn[i].push_back(current_number_of_landmarks); - if (curr_dist < dist_to_L[i]) - dist_to_L[i] = curr_dist; - int j = current_number_of_landmarks; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - std::swap(knn[i][j], knn[i][j-1]); - std::swap(wit_land_dist[i][j-1], wit_land_dist[i][j-1]); - --j; - } - ++i; - } - curr_max_dist = 0; - for (auto dist: dist_to_L) { - if (dist > curr_max_dist) + int rand_int = rand() % nb_points; + int curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here + + for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) + { + //curr_max_w at this point is the next landmark + chosen_landmarks.push_back(curr_max_w); + for (auto& v: knn) + v.push_back(current_number_of_landmarks); + unsigned i = 0; + for (auto& p: points) { - curr_max_dist = dist; - curr_max_w = i; + double curr_dist = euclidean_distance(p, *(points.begin() + chosen_landmarks[current_number_of_landmarks])); + wit_land_dist[i].push_back(curr_dist); + knn[i].push_back(current_number_of_landmarks); + if (curr_dist < dist_to_L[i]) + dist_to_L[i] = curr_dist; + int j = current_number_of_landmarks; + while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) + { + std::swap(knn[i][j], knn[i][j-1]); + std::swap(wit_land_dist[i][j-1], wit_land_dist[i][j-1]); + --j; + } + ++i; } + curr_max_dist = 0; + for (i = 0; i < dist_to_L.size(); i++) + if (dist_to_L[i] > curr_max_dist) + { + curr_max_dist = dist_to_L[i]; + curr_max_w = i; + } } - } - } + } }; diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp new file mode 100644 index 00000000..c7d85a4d --- /dev/null +++ b/src/Witness_complex/test/simple_witness_complex.cpp @@ -0,0 +1,55 @@ +/* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Simplex_tree.h" +#include "gudhi/Witness_complex.h" + +using namespace Gudhi; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef Witness_complex> WitnessComplex; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +int main (int argc, char * const argv[]) +{ + Simplex_tree<> complex; + std::vector< typeVectorVertex > knn; + typeVectorVertex witness0 = {1,0,5,2,6,3,4}; knn.push_back(witness0 ); + typeVectorVertex witness1 = {2,6,4,5,0,1,3}; knn.push_back(witness1 ); + typeVectorVertex witness2 = {3,4,2,1,5,6,0}; knn.push_back(witness2 ); + typeVectorVertex witness3 = {4,2,1,3,5,6,0}; knn.push_back(witness3 ); + typeVectorVertex witness4 = {5,1,6,0,2,3,4}; knn.push_back(witness4 ); + typeVectorVertex witness5 = {6,0,5,2,1,3,4}; knn.push_back(witness5 ); + typeVectorVertex witness6 = {0,5,6,1,2,3,4}; knn.push_back(witness6 ); + typeVectorVertex witness7 = {2,6,4,5,3,1,0}; knn.push_back(witness7 ); + typeVectorVertex witness8 = {1,2,5,4,3,6,0}; knn.push_back(witness8 ); + typeVectorVertex witness9 = {3,4,0,6,5,1,2}; knn.push_back(witness9 ); + typeVectorVertex witness10 = {5,0,1,3,6,2,4}; knn.push_back(witness10); + typeVectorVertex witness11 = {5,6,1,0,2,3,4}; knn.push_back(witness11); + typeVectorVertex witness12 = {1,6,0,5,2,3,4}; knn.push_back(witness12); + WitnessComplex witnessComplex(knn, complex, 7, 7); + assert(witnessComplex.is_witness_complex(knn, true)); +} diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp new file mode 100644 index 00000000..f9680874 --- /dev/null +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -0,0 +1,64 @@ +/* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +//#include "gudhi/graph_simplicial_complex.h" +#include "gudhi/Simplex_tree.h" +#include "gudhi/Witness_complex.h" +#include "gudhi/Landmark_choice_by_random_point.h" +#include "gudhi/Landmark_choice_by_furthest_point.h" + + +using namespace Gudhi; + +typedef std::vector< Vertex_handle > typeVectorVertex; +typedef Witness_complex> WitnessComplex; +typedef std::vector Point; +//typedef std::pair typeSimplex; +//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; + +int main (int argc, char * const argv[]) +{ + std::vector< typeVectorVertex > knn; + std::vector< Point > points; + // Add grid points as witnesses + for (double i = 0; i < 10; i += 1.0) + for (double j = 0; j < 10; j += 1.0) + for (double k = 0; k < 10; k += 1.0) + points.push_back(Point({i,j,k})); + + bool b_print_output = true; + // First test: random choice + Simplex_tree<> complex1; + Landmark_choice_by_random_point lcrp(points, 100, knn); + assert(!knn.empty()); + WitnessComplex witnessComplex1(knn, complex1, 100, 3); + assert(witnessComplex1.is_witness_complex(knn, b_print_output)); + + // Second test: furthest choice + knn.clear(); + Simplex_tree<> complex2; + Landmark_choice_by_furthest_point lcfp(points, 100, knn); + WitnessComplex witnessComplex2(knn, complex2, 100, 3); + assert(witnessComplex2.is_witness_complex(knn, b_print_output)); +} -- cgit v1.2.3 From e9f91fe2787f41dd7791c055592ade552ce8df8a Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 13 Jan 2016 19:08:48 +0000 Subject: Oh, forgot the CMakeList in test folder git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@965 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d4a5301e5a48a27050bec9a43c35980a98d8837b --- src/Witness_complex/test/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/Witness_complex/test/CMakeLists.txt (limited to 'src') diff --git a/src/Witness_complex/test/CMakeLists.txt b/src/Witness_complex/test/CMakeLists.txt new file mode 100644 index 00000000..a13fd94a --- /dev/null +++ b/src/Witness_complex/test/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.6) +project(GUDHITestWitnessComplex) + +#if(NOT MSVC) +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") +# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage") +# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} --coverage") +#endif() + +add_executable ( simple_witness_complex simple_witness_complex.cpp ) +add_test(test ${CMAKE_CURRENT_BINARY_DIR}/simple_witness_complex) + +add_executable ( witness_complex_points witness_complex_points.cpp ) +add_test(test ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_points) + +#cpplint_add_tests("${CMAKE_SOURCE_DIR}/src/Simplex_tree/include/gudhi") -- cgit v1.2.3 From 309699bf1dfd0582e671c730aee6bdf0f5031a1a Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 14 Jan 2016 10:37:35 +0000 Subject: Fixed the bug in Landmark_selection_by_furthest_point git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@966 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cbda37a8c267348800fe04e82c58c4021744292e --- .../include/gudhi/Landmark_choice_by_furthest_point.h | 16 ++++++---------- src/Witness_complex/test/witness_complex_points.cpp | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index ebee96ad..6ac59ae9 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -60,7 +60,7 @@ public: double curr_max_dist = 0; // used for defining the furhest point from L const double infty = std::numeric_limits::infinity(); // infinity (see next entry) std::vector< double > dist_to_L(nb_points,infty); // vector of current distances to L from points - int dim = points.begin()->size(); + //int dim = points.begin()->size(); int rand_int = rand() % nb_points; int curr_max_w = rand_int; //For testing purposes a pseudo-random number is used here @@ -69,8 +69,6 @@ public: { //curr_max_w at this point is the next landmark chosen_landmarks.push_back(curr_max_w); - for (auto& v: knn) - v.push_back(current_number_of_landmarks); unsigned i = 0; for (auto& p: points) { @@ -79,13 +77,6 @@ public: knn[i].push_back(current_number_of_landmarks); if (curr_dist < dist_to_L[i]) dist_to_L[i] = curr_dist; - int j = current_number_of_landmarks; - while (j > 0 && wit_land_dist[i][j-1] > wit_land_dist[i][j]) - { - std::swap(knn[i][j], knn[i][j-1]); - std::swap(wit_land_dist[i][j-1], wit_land_dist[i][j-1]); - --j; - } ++i; } curr_max_dist = 0; @@ -96,6 +87,11 @@ public: curr_max_w = i; } } + for (unsigned i = 0; i < points.size(); ++i) + std::sort(knn[i].begin(), + knn[i].end(), + [&wit_land_dist, i](int a, int b) + { return wit_land_dist[i][a] < wit_land_dist[i][b]; }); } }; diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index f9680874..a86bf493 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -47,7 +47,7 @@ int main (int argc, char * const argv[]) for (double k = 0; k < 10; k += 1.0) points.push_back(Point({i,j,k})); - bool b_print_output = true; + bool b_print_output = false; // First test: random choice Simplex_tree<> complex1; Landmark_choice_by_random_point lcrp(points, 100, knn); -- cgit v1.2.3 From 22a90cae3ce7ca63ca712a74281410e61e829dd2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 14 Jan 2016 14:31:08 +0000 Subject: AddressSanitizer bug fixes on Simplex tree copy constructor. debug_tree function git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_insert_with_subfaces_fix@967 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: dd4b15dc8f2a4795d3a0b6fdcf4938aff152906b --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 42 +++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 708cdef9..0a406076 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -325,11 +325,10 @@ class Simplex_tree { Simplex_tree(const Simplex_tree& simplex_source) : null_vertex_(simplex_source.null_vertex_), threshold_(simplex_source.threshold_), + root_(nullptr, null_vertex_ , simplex_source.root_.members_), filtration_vect_(), dimension_(simplex_source.dimension_) { auto root_source = simplex_source.root_; - auto memb_source = root_source.members(); - root_ = Siblings(nullptr, null_vertex_, memb_source); rec_copy(&root_, &root_source); } @@ -341,7 +340,7 @@ class Simplex_tree { Siblings * newsib = new Siblings(sib, sh_source->first); newsib->members_.reserve(sh_source->second.children()->members().size()); for (auto & child : sh_source->second.children()->members()) - newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(sib, child.second.filtration())); + newsib->members_.emplace_hint(newsib->members_.end(), child.first, Node(newsib, child.second.filtration())); rec_copy(newsib, sh_source->second.children()); sh->second.assign_children(newsib); } @@ -1105,6 +1104,43 @@ class Simplex_tree { os << filtration(sh) << " \n"; } } +/***************************************************************************************************************/ + public: + /** \brief Prints the simplex_tree hierarchically. + * Since it prints the vertices recursively, one can watch its tree shape. + */ + void debug_tree() { + std::cout << "{" << &root_ << "} -------------------------------------------------------------------" << std::endl; + for (auto sh = root_.members().begin(); sh != root_.members().end(); ++sh) { + std::cout << sh->first << " [" << sh->second.filtration() << "] "; + if (has_children(sh)) { + rec_debug_tree(sh->second.children()); + } else { + std::cout << " {- " << sh->second.children() << "} "; + } + std::cout << std::endl; + } + std::cout << "--------------------------------------------------------------------------------------" << std::endl; + } + + + /** \brief Recursively prints the simplex_tree, using depth first search. */ + private: + void rec_debug_tree(Siblings * sib) { + std::cout << " {" << sib << "} ("; + for (auto sh = sib->members().begin(); sh != sib->members().end(); ++sh) { + std::cout << " " << sh->first << " [" << sh->second.filtration() << "] "; + if (has_children(sh)) { + rec_debug_tree(sh->second.children()); + } else { + std::cout << " {- " << sh->second.children() << "} "; + } + } + std::cout << ")"; + } + +/*****************************************************************************************************************/ + private: Vertex_handle null_vertex_; -- cgit v1.2.3 From f44d72644fc31bc863d0c81d0ae80630ebc506e5 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 14 Jan 2016 16:17:51 +0000 Subject: Added example stuff git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@968 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a769b41f7d2d784a2740c149da08dac8124e3df9 --- src/Witness_complex/example/CMakeLists.txt | 11 +- src/Witness_complex/example/generators.h | 134 +++++++++++++++++++++ .../example/witness_complex_sphere.cpp | 126 +++++++++++++++++++ .../include/gudhi/Witness_complex.h | 2 +- .../test/simple_witness_complex.cpp | 5 +- .../test/witness_complex_points.cpp | 9 +- 6 files changed, 271 insertions(+), 16 deletions(-) create mode 100644 src/Witness_complex/example/generators.h create mode 100644 src/Witness_complex/example/witness_complex_sphere.cpp (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index 4473078a..b5770ba6 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -4,9 +4,6 @@ project(GUDHIWitnessComplex) # A simple example add_executable( witness_complex_from_file witness_complex_from_file.cpp ) add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) - - add_executable( witness_complex_bench witness_complex_bench.cpp ) - add_test( witness_complex_bench_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_bench ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) if(CGAL_FOUND) if (NOT CGAL_VERSION VERSION_LESS 4.6.0) @@ -21,12 +18,12 @@ if(CGAL_FOUND) message(STATUS "Eigen3 use file: ${EIGEN3_USE_FILE}.") include_directories (BEFORE "../../include") - add_executable ( witness_complex_bench2 witness_complex_bench2.cpp ) - target_link_libraries(witness_complex_bench2 ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) + add_executable ( witness_complex_sphere witness_complex_sphere.cpp ) + target_link_libraries(witness_complex_sphere ${Boost_SYSTEM_LIBRARY} ${CGAL_LIBRARY}) else() - message(WARNING "Eigen3 not found. Version 3.1.0 is required for Alpha shapes feature.") + message(WARNING "Eigen3 not found. Version 3.1.0 is required for witness_complex_sphere example.") endif() else() - message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile Alpha shapes feature. Version 4.6.0 is required.") + message(WARNING "CGAL version: ${CGAL_VERSION} is too old to compile witness_complex_sphere example. Version 4.6.0 is required.") endif () endif() diff --git a/src/Witness_complex/example/generators.h b/src/Witness_complex/example/generators.h new file mode 100644 index 00000000..0d42cda2 --- /dev/null +++ b/src/Witness_complex/example/generators.h @@ -0,0 +1,134 @@ +#ifndef GENERATORS_H +#define GENERATORS_H + +#include + +#include +#include + +typedef CGAL::Epick_d K; +typedef K::FT FT; +typedef K::Point_d Point_d; +typedef std::vector Point_Vector; +typedef CGAL::Random_points_in_cube_d Random_cube_iterator; +typedef CGAL::Random_points_in_ball_d Random_point_iterator; + +/** + * \brief Rock age method of reading off file + * + */ +inline void +off_reader_cust ( std::string file_name , std::vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + // Line OFF. No need in it + if (!getline(in_file, line)) + { + std::cerr << "No line OFF\n"; + return; + } + // Line with 3 numbers. No need + if (!getline(in_file, line)) + { + std::cerr << "No line with 3 numbers\n"; + return; + } + // Reading points + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + points.push_back(Point_d(point)); + } + in_file.close(); +} + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , Point_Vector & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + Point_d p(point.begin(), point.end()); + if (point.size() != 1) + points.push_back(p); + } + in_file.close(); +} + +/** \brief Generate points on a grid in a cube of side 2 + * having {+-1}^D as vertices and insert them in W. + * The grid has "width" points on each side. + * If torus is true then it is supposed that the cube represents + * a flat torus, hence the opposite borders are associated. + * The points on border in this case are not placed twice. + */ +void generate_points_grid(Point_Vector& W, int width, int D, bool torus) +{ + int nb_points = 1; + for (int i = 0; i < D; ++i) + nb_points *= width; + for (int i = 0; i < nb_points; ++i) + { + std::vector point; + int cell_i = i; + for (int l = 0; l < D; ++l) + { + if (torus) + point.push_back(-1+(2.0/(width-1))*(cell_i%width)); + else + point.push_back(-1+(2.0/width)*(cell_i%width)); + //attention: the bottom and the right are covered too! + cell_i /= width; + } + W.push_back(point); + } +} + +/** \brief Generate nbP points uniformly in a cube of side 2 + * having {+-1}^dim as its vertices and insert them in W. + */ +void generate_points_random_box(Point_Vector& W, int nbP, int dim) +{ + Random_cube_iterator rp(dim, 1.0); + for (int i = 0; i < nbP; i++) + { + W.push_back(*rp++); + } +} + +/** \brief Generate nbP points uniformly on a (dim-1)-sphere + * and insert them in W. + */ +void generate_points_sphere(Point_Vector& W, int nbP, int dim) +{ + CGAL::Random_points_on_sphere_d rp(dim,1); + for (int i = 0; i < nbP; i++) + W.push_back(*rp++); +} + + +#endif diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp new file mode 100644 index 00000000..1fa0fc42 --- /dev/null +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -0,0 +1,126 @@ +/* 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) 2015 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define BOOST_PARAMETER_MAX_ARITY 12 + + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "generators.h" + +using namespace Gudhi; + +typedef std::vector< Vertex_handle > typeVectorVertex; +//typedef std::vector< std::vector > Point_Vector; + +typedef Witness_complex< Simplex_tree<> > WitnessComplex; + +/** + * \brief Customized version of read_points + * which takes into account a possible nbP first line + * + */ +inline void +read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) +{ + std::ifstream in_file (file_name.c_str(),std::ios::in); + if(!in_file.is_open()) + { + std::cerr << "Unable to open file " << file_name << std::endl; + return; + } + std::string line; + double x; + while( getline ( in_file , line ) ) + { + std::vector< double > point; + std::istringstream iss( line ); + while(iss >> x) { point.push_back(x); } + if (point.size() != 1) + points.push_back(point); + } + in_file.close(); +} + +/** Write a gnuplot readable file. + * Data range is a random access range of pairs (arg, value) + */ +template < typename Data_range > +void write_data( Data_range & data, std::string filename ) +{ + std::ofstream ofs(filename, std::ofstream::out); + for (auto entry: data) + ofs << entry.first << ", " << entry.second << "\n"; + ofs.close(); +} + +int main (int argc, char * const argv[]) +{ + if (argc != 3) + { + std::cerr << "Usage: " << argv[0] + << " path_to_point_file nbL \n"; + return 0; + } + + std::string file_name = argv[1]; + int nbL = atoi(argv[2]); + clock_t start, end; + + // Construct the Simplex Tree + Simplex_tree<> simplex_tree; + + std::vector< std::pair > l_time; + + // Read the point file + for (int nbP = 500; nbP < 10000; nbP += 500) + { + Point_Vector point_vector; + generate_points_sphere(point_vector, nbP, 4); + std::cout << "Successfully generated " << point_vector.size() << " points.\n"; + std::cout << "Ambient dimension is " << point_vector[0].size() << ".\n"; + + // Choose landmarks + start = clock(); + std::vector > knn; + Landmark_choice_by_random_point(point_vector, nbL, knn); + + // Compute witness complex + WitnessComplex(knn, simplex_tree, nbL, point_vector[0].size()); + end = clock(); + double time = (double)(end-start)/CLOCKS_PER_SEC; + std::cout << "Witness complex for " << nbL << " landmarks took " + << time << " s. \n"; + l_time.push_back(std::make_pair(nbP,time)); + } + write_data(l_time, "w_time.dat"); +} diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 791d0e45..915e445c 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -27,7 +27,7 @@ #include #include #include -#include "gudhi/distance_functions.h" +#include #include #include #include diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp index c7d85a4d..ea38b5c0 100644 --- a/src/Witness_complex/test/simple_witness_complex.cpp +++ b/src/Witness_complex/test/simple_witness_complex.cpp @@ -22,9 +22,8 @@ #include #include -//#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Simplex_tree.h" -#include "gudhi/Witness_complex.h" +#include +#include using namespace Gudhi; diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index a86bf493..0a50101d 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -22,11 +22,10 @@ #include #include -//#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Simplex_tree.h" -#include "gudhi/Witness_complex.h" -#include "gudhi/Landmark_choice_by_random_point.h" -#include "gudhi/Landmark_choice_by_furthest_point.h" +#include +#include +#include +#include using namespace Gudhi; -- cgit v1.2.3 From 500d18704bc26166983ea005278bd187e2d3020c Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 15 Jan 2016 08:53:03 +0000 Subject: Fixed namespaces git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@970 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f71d4840583611d3829d8c4f1049e5d2b01ce71d --- src/Witness_complex/example/witness_complex_from_file.cpp | 1 + src/Witness_complex/example/witness_complex_sphere.cpp | 1 + .../include/gudhi/Landmark_choice_by_furthest_point.h | 8 ++++++++ .../include/gudhi/Landmark_choice_by_random_point.h | 8 ++++++++ src/Witness_complex/include/gudhi/Witness_complex.h | 9 +++++---- src/Witness_complex/test/simple_witness_complex.cpp | 5 ++--- src/Witness_complex/test/witness_complex_points.cpp | 1 + 7 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 6add4e0a..72caf30b 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -33,6 +33,7 @@ #include "gudhi/reader_utils.h" using namespace Gudhi; +using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::vector< std::vector > Point_Vector; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 1fa0fc42..d73445b9 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -38,6 +38,7 @@ #include "generators.h" using namespace Gudhi; +using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; //typedef std::vector< std::vector > Point_Vector; diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 6ac59ae9..050286f2 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -23,6 +23,10 @@ #ifndef GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ #define GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ +namespace Gudhi { + +namespace witness_complex { + /** * \class Landmark_choice_by_furthest_point * \brief The class `Landmark_choice_by_furthest_point` allows to construct the matrix @@ -96,4 +100,8 @@ public: }; +} + +} + #endif diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index fa822591..038deff6 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -23,6 +23,10 @@ #ifndef GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ #define GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ +namespace Gudhi { + +namespace witness_complex { + /** * \class Landmark_choice_by_random_point * \brief The class `Landmark_choice_by_random_point` allows to construct the matrix @@ -81,4 +85,8 @@ public: }; +} + +} + #endif diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 915e445c..8938e59d 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -44,7 +44,8 @@ namespace Gudhi { - + namespace witness_complex { + /** \class Witness_complex \brief Constructs the witness complex for the given set of witnesses and landmarks. @@ -256,13 +257,13 @@ namespace Gudhi { return false; } } - return true; // Arrive here if the not_witnessed check failed all the time + return true; } -}; //class Witness_complex - + }; //class Witness_complex + } //namespace witness_complex } // namespace Guhdi diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp index ea38b5c0..86f5bcd1 100644 --- a/src/Witness_complex/test/simple_witness_complex.cpp +++ b/src/Witness_complex/test/simple_witness_complex.cpp @@ -26,11 +26,10 @@ #include using namespace Gudhi; +using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; typedef Witness_complex> WitnessComplex; -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; int main (int argc, char * const argv[]) { @@ -50,5 +49,5 @@ int main (int argc, char * const argv[]) typeVectorVertex witness11 = {5,6,1,0,2,3,4}; knn.push_back(witness11); typeVectorVertex witness12 = {1,6,0,5,2,3,4}; knn.push_back(witness12); WitnessComplex witnessComplex(knn, complex, 7, 7); - assert(witnessComplex.is_witness_complex(knn, true)); + assert(witnessComplex.is_witness_complex(knn, false)); } diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index 0a50101d..e9fac9b8 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -29,6 +29,7 @@ using namespace Gudhi; +using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; typedef Witness_complex> WitnessComplex; -- cgit v1.2.3 From 377b59e5e7fa6a92bd21b0cb9b9b86e33632e4ed Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 15 Jan 2016 08:57:23 +0000 Subject: Removed relaxed_witness_complex_sphere from repository git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@971 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 886ea9c52839e6cb21872da5097a55037b027ca7 --- .../example/relaxed_witness_complex_sphere.cpp | 461 --------------------- 1 file changed, 461 deletions(-) delete mode 100644 src/Witness_complex/example/relaxed_witness_complex_sphere.cpp (limited to 'src') diff --git a/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp b/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp deleted file mode 100644 index 067321ce..00000000 --- a/src/Witness_complex/example/relaxed_witness_complex_sphere.cpp +++ /dev/null @@ -1,461 +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): Siargey Kachanovich - * - * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -//#include - -//#include "gudhi/graph_simplicial_complex.h" -#include "gudhi/Relaxed_witness_complex.h" -#include "gudhi/reader_utils.h" -#include "gudhi/Collapse/Collapse.h" -//#include - -//#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -using namespace Gudhi; -//using namespace boost::filesystem; - -typedef CGAL::Epick_d K; -typedef K::FT FT; -typedef K::Point_d Point_d; -typedef CGAL::Search_traits< - FT, Point_d, - typename K::Cartesian_const_iterator_d, - typename K::Construct_cartesian_const_iterator_d> Traits_base; -typedef CGAL::Euclidean_distance Euclidean_distance; - -typedef std::vector< Vertex_handle > typeVectorVertex; - -//typedef std::pair typeSimplex; -//typedef std::pair< Simplex_tree<>::Simplex_handle, bool > typePairSimplexBool; - -typedef CGAL::Search_traits_adapter< - std::ptrdiff_t, Point_d*, Traits_base> STraits; -//typedef K TreeTraits; -//typedef CGAL::Distance_adapter Euclidean_adapter; -//typedef CGAL::Kd_tree Kd_tree; -typedef CGAL::Orthogonal_incremental_neighbor_search> Neighbor_search; -typedef Neighbor_search::Tree Tree; -typedef Neighbor_search::Distance Distance; -typedef Neighbor_search::iterator KNS_iterator; -typedef Neighbor_search::iterator KNS_range; -typedef boost::container::flat_map Point_etiquette_map; -typedef CGAL::Kd_tree Tree2; - -typedef CGAL::Fuzzy_sphere Fuzzy_sphere; - -typedef std::vector Point_Vector; - -//typedef K::Equal_d Equal_d; -typedef CGAL::Random_points_in_cube_d Random_cube_iterator; -typedef CGAL::Random_points_in_ball_d Random_point_iterator; - -bool toric=false; - -/** - * \brief Customized version of read_points - * which takes into account a possible nbP first line - * - */ -inline void -read_points_cust ( std::string file_name , Point_Vector & points) -{ - std::ifstream in_file (file_name.c_str(),std::ios::in); - if(!in_file.is_open()) - { - std::cerr << "Unable to open file " << file_name << std::endl; - return; - } - std::string line; - double x; - while( getline ( in_file , line ) ) - { - std::vector< double > point; - std::istringstream iss( line ); - while(iss >> x) { point.push_back(x); } - Point_d p(point.begin(), point.end()); - if (point.size() != 1) - points.push_back(p); - } - in_file.close(); -} - - -void generate_points_sphere(Point_Vector& W, int nbP, int dim) -{ - CGAL::Random_points_on_sphere_d rp(dim,1); - for (int i = 0; i < nbP; i++) - W.push_back(*rp++); -} - - -void write_wl( std::string file_name, std::vector< std::vector > & WL) -{ - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : WL) - { - for (auto l: w) - ofs << l << " "; - ofs << "\n"; - } - ofs.close(); -} - -void write_rl( std::string file_name, std::vector< std::vector ::iterator> > & rl) -{ - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : rl) - { - for (auto l: w) - ofs << *l << " "; - ofs << "\n"; - } - ofs.close(); -} - -std::vector convert_to_torus(std::vector< Point_d>& points) -{ - std::vector< Point_d > points_torus; - for (auto p: points) - { - FT theta = M_PI*p[0]; - FT phi = M_PI*p[1]; - std::vector p_torus; - p_torus.push_back((1+0.2*cos(theta))*cos(phi)); - p_torus.push_back((1+0.2*cos(theta))*sin(phi)); - p_torus.push_back(0.2*sin(theta)); - points_torus.push_back(Point_d(p_torus)); - } - return points_torus; -} - - -void write_points_torus( std::string file_name, std::vector< Point_d > & points) -{ - std::ofstream ofs (file_name, std::ofstream::out); - std::vector points_torus = convert_to_torus(points); - for (auto w : points_torus) - { - for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - } - ofs.close(); -} - - -void write_points( std::string file_name, std::vector< Point_d > & points) -{ - if (toric) write_points_torus(file_name, points); - else - { - std::ofstream ofs (file_name, std::ofstream::out); - for (auto w : points) - { - for (auto it = w.cartesian_begin(); it != w.cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - } - ofs.close(); - } -} - - -void write_edges_torus(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) -{ - std::ofstream ofs (file_name, std::ofstream::out); - Point_Vector l_torus = convert_to_torus(landmarks); - for (auto u: witness_complex.complex_vertex_range()) - for (auto v: witness_complex.complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) - { - for (auto it = l_torus[u].cartesian_begin(); it != l_torus[u].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - for (auto it = l_torus[v].cartesian_begin(); it != l_torus[v].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n\n\n"; - } - } - ofs.close(); -} - -void write_edges(std::string file_name, Witness_complex<>& witness_complex, Point_Vector& landmarks) -{ - std::ofstream ofs (file_name, std::ofstream::out); - if (toric) write_edges_torus(file_name, witness_complex, landmarks); - else - { - for (auto u: witness_complex.complex_vertex_range()) - for (auto v: witness_complex.complex_vertex_range()) - { - typeVectorVertex edge = {u,v}; - if (u < v && witness_complex.find(edge) != witness_complex.null_simplex()) - { - for (auto it = landmarks[u].cartesian_begin(); it != landmarks[u].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n"; - for (auto it = landmarks[v].cartesian_begin(); it != landmarks[v].cartesian_end(); ++it) - ofs << *it << " "; - ofs << "\n\n\n"; - } - } - ofs.close(); - } -} - - -/** Function that chooses landmarks from W and place it in the kd-tree L. - * Note: nbL hould be removed if the code moves to Witness_complex - */ -void landmark_choice(Point_Vector &W, int nbP, int nbL, Point_Vector& landmarks, std::vector& landmarks_ind) -{ - std::cout << "Enter landmark choice to kd tree\n"; - //std::vector landmarks; - int chosen_landmark; - //std::pair res = std::make_pair(L_i.begin(),false); - Point_d* p; - CGAL::Random rand; - for (int i = 0; i < nbL; i++) - { - // while (!res.second) - // { - do chosen_landmark = rand.get_int(0,nbP); - while (std::find(landmarks_ind.begin(), landmarks_ind.end(), chosen_landmark) != landmarks_ind.end()); - //rand++; - //std::cout << "Chose " << chosen_landmark << std::endl; - p = &W[chosen_landmark]; - //L_i.emplace(chosen_landmark,i); - // } - landmarks.push_back(*p); - landmarks_ind.push_back(chosen_landmark); - //std::cout << "Added landmark " << chosen_landmark << std::endl; - } - } - - -void landmarks_to_witness_complex(Point_Vector &W, Point_Vector& landmarks, std::vector& landmarks_ind, FT alpha) -{ - //********************Preface: origin point - unsigned D = W[0].size(); - std::vector orig_vector; - for (unsigned i = 0; i < D; i++) - orig_vector.push_back(0); - Point_d origin(orig_vector); - //Distance dist; - //dist.transformed_distance(0,1); - //******************** Constructing a WL matrix - int nbP = W.size(); - int nbL = landmarks.size(); - STraits traits(&(landmarks[0])); - Euclidean_distance ed; - std::vector< std::vector > WL(nbP); - std::vector< std::vector< typename std::vector::iterator > > ope_limits(nbP); - Tree L(boost::counting_iterator(0), - boost::counting_iterator(nbL), - typename Tree::Splitter(), - traits); - - std::cout << "Enter (D+1) nearest landmarks\n"; - //std::cout << "Size of the tree is " << L.size() << std::endl; - for (int i = 0; i < nbP; i++) - { - //std::cout << "Entered witness number " << i << std::endl; - Point_d& w = W[i]; - std::queue< typename std::vector::iterator > ope_queue; // queue of points at (1+epsilon) distance to current landmark - Neighbor_search search(L, w, FT(0), true, CGAL::Distance_adapter(&(landmarks[0]))); - Neighbor_search::iterator search_it = search.begin(); - - //Incremental search and filling WL - while (WL[i].size() < D) - WL[i].push_back((search_it++)->first); - FT dtow = ed.transformed_distance(w, landmarks[WL[i][D-1]]); - while (search_it->second < dtow + alpha) - WL[i].push_back((search_it++)->first); - - //Filling the (1+epsilon)-limits table - for (std::vector::iterator wl_it = WL[i].begin(); wl_it != WL[i].end(); ++wl_it) - { - ope_queue.push(wl_it); - FT d_to_curr_l = ed.transformed_distance(w, landmarks[*wl_it]); - //std::cout << "d_to_curr_l=" << d_to_curr_l << std::endl; - //std::cout << "d_to_front+alpha=" << d_to_curr_l << std::endl; - while (d_to_curr_l > alpha + ed.transformed_distance(w, landmarks[*(ope_queue.front())])) - { - ope_limits[i].push_back(wl_it); - ope_queue.pop(); - } - } - while (ope_queue.size() > 0) - { - ope_limits[i].push_back(WL[i].end()); - ope_queue.pop(); - } - //std::cout << "Safely constructed a point\n"; - ////Search D+1 nearest neighbours from the tree of landmarks L - /* - if (w[0]>0.95) - std::cout << i << std::endl; - */ - //K_neighbor_search search(L, w, D, FT(0), true, - // CGAL::Distance_adapter(&(landmarks[0])) ); - //std::cout << "Safely found nearest landmarks\n"; - /* - for(K_neighbor_search::iterator it = search.begin(); it != search.end(); ++it) - { - //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; - //Point_etiquette_map::iterator itm = L_i.find(it->first); - //assert(itm != L_i.end()); - //std::cout << "Entered KNN_it with point at distance " << it->second << "\n"; - WL[i].push_back(it->first); - //std::cout << "ITFIRST " << it->first << std::endl; - //std::cout << i << " " << it->first << ": " << it->second << std::endl; - } - */ - } - //std::cout << "\n"; - - //std::string out_file = "wl_result"; - write_wl("wl_result",WL); - write_rl("rl_result",ope_limits); - - //******************** Constructng a witness complex - std::cout << "Entered witness complex construction\n"; - Witness_complex<> witnessComplex; - witnessComplex.setNbL(nbL); - witnessComplex.relaxed_witness_complex(WL, ope_limits); - char buffer[100]; - int i = sprintf(buffer,"stree_result.txt"); - - if (i >= 0) - { - std::string out_file = (std::string)buffer; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - } - write_edges("landmarks/edges", witnessComplex, landmarks); - std::cout << Distance().transformed_distance(Point_d(std::vector({0.1,0.1})), Point_d(std::vector({1.9,1.9}))) << std::endl; -} - - -int main (int argc, char * const argv[]) -{ - - if (argc != 5) - { - std::cerr << "Usage: " << argv[0] - << " nbP nbL dim alpha\n"; - return 0; - } - /* - boost::filesystem::path p; - for (; argc > 2; --argc, ++argv) - p /= argv[1]; - */ - - int nbP = atoi(argv[1]); - int nbL = atoi(argv[2]); - int dim = atoi(argv[3]); - double alpha = atof(argv[4]); - //clock_t start, end; - //Construct the Simplex Tree - Witness_complex<> witnessComplex; - - std::cout << "Let the carnage begin!\n"; - Point_Vector point_vector; - //read_points_cust(file_name, point_vector); - generate_points_sphere(point_vector, nbP, dim); - /* - for (auto &p: point_vector) - { - assert(std::count(point_vector.begin(),point_vector.end(),p) == 1); - } - */ - //std::cout << "Successfully read the points\n"; - //witnessComplex.setNbL(nbL); - Point_Vector L; - std::vector chosen_landmarks; - landmark_choice(point_vector, nbP, nbL, L, chosen_landmarks); - //start = clock(); - - write_points("landmarks/initial_pointset",point_vector); - write_points("landmarks/initial_landmarks",L); - - landmarks_to_witness_complex(point_vector, L, chosen_landmarks, alpha); - //end = clock(); - - /* - std::cout << "Landmark choice took " - << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - start = clock(); - witnessComplex.witness_complex(WL); - // - end = clock(); - std::cout << "Howdy world! The process took " - << (double)(end-start)/CLOCKS_PER_SEC << " s. \n"; - */ - - /* - out_file = "output/"+file_name+"_"+argv[2]+".stree"; - std::ofstream ofs (out_file, std::ofstream::out); - witnessComplex.st_to_file(ofs); - ofs.close(); - - out_file = "output/"+file_name+"_"+argv[2]+".badlinks"; - std::ofstream ofs2(out_file, std::ofstream::out); - witnessComplex.write_bad_links(ofs2); - ofs2.close(); - */ -} -- cgit v1.2.3 From cccb605bb3beca6eeae7d7368a4c3cb48bda98c7 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 15 Jan 2016 14:16:34 +0000 Subject: Added consts where needed git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@973 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 57ca40cd8dcda5125e4412c196862e14ff073744 --- .../include/gudhi/Landmark_choice_by_furthest_point.h | 2 +- .../include/gudhi/Landmark_choice_by_random_point.h | 4 +++- src/Witness_complex/include/gudhi/Witness_complex.h | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 050286f2..163975c9 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -51,7 +51,7 @@ public: template - Landmark_choice_by_furthest_point(Point_random_access_range &points, + Landmark_choice_by_furthest_point(Point_random_access_range const &points, int nbL, KNearestNeighbours &knn) { diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index 038deff6..a54f3848 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -46,7 +46,9 @@ public: template - Landmark_choice_by_random_point(Point_random_access_range &points, int nbL, KNearestNeighbours &knn) + Landmark_choice_by_random_point(Point_random_access_range const &points, + int nbL, + KNearestNeighbours &knn) { int nbP = points.end() - points.begin(); std::set landmarks; diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 8938e59d..2b6a6ad5 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -105,7 +105,7 @@ namespace Gudhi { * Landmarks are supposed to be in [0,nbL_-1] */ template< typename KNearestNeighbours > - Witness_complex(KNearestNeighbours & knn, + Witness_complex(KNearestNeighbours const & knn, Simplicial_complex & sc_, int nbL_, int dim ): nbL(nbL_), sc(sc_) @@ -164,7 +164,7 @@ namespace Gudhi { * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id */ template - bool all_faces_in(KNearestNeighbours &knn, int witness_id, int k) + bool all_faces_in(KNearestNeighbours const &knn, int witness_id, int k) { //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; std::vector< Vertex_handle > facet; @@ -188,7 +188,7 @@ namespace Gudhi { } template - void print_vector(std::vector v) + void print_vector(const std::vector v) { std::cout << "["; if (!v.empty()) @@ -211,7 +211,7 @@ namespace Gudhi { * \remark Added for debugging purposes. */ template< class KNearestNeighbors > - bool is_witness_complex(KNearestNeighbors & knn, bool print_output) + bool is_witness_complex(KNearestNeighbors const & knn, bool print_output) { //bool final_result = true; for (Simplex_handle sh: sc.complex_simplex_range()) -- cgit v1.2.3 From 3b3ceceb624d48775ceb28ab455f0f547df9e6c4 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 19 Jan 2016 14:00:27 +0000 Subject: Try different values for xUnit git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@977 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b3e39a4858a4be139236be0a87619164a35ea7c0 --- src/Simplex_tree/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index c9eae163..b1256768 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -24,5 +24,5 @@ file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DI add_test(NAME SimplexTreeUT COMMAND ${CMAKE_CURRENT_BINARY_DIR}/SimplexTreeUT # XML format for Jenkins xUnit plugin - --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/SimplexTreeUT.xml --log_level=test_suite --report_level=no) + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/SimplexTreeUT.xml --log_level=all --report_level=no) -- cgit v1.2.3 From f4ac13983d5d977cab5c575184e9b21ee000485f Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 19 Jan 2016 15:07:56 +0000 Subject: rollback git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@978 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6aeb45f999861185cda0d0961f22b4a08b413927 --- src/Simplex_tree/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index b1256768..c9eae163 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -24,5 +24,5 @@ file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DI add_test(NAME SimplexTreeUT COMMAND ${CMAKE_CURRENT_BINARY_DIR}/SimplexTreeUT # XML format for Jenkins xUnit plugin - --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/SimplexTreeUT.xml --log_level=all --report_level=no) + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/SimplexTreeUT.xml --log_level=test_suite --report_level=no) -- cgit v1.2.3 From c0ad466a28bd3cc0ac88c0bbd49fc2e0a711afe9 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 19 Jan 2016 16:33:41 +0000 Subject: Added a concept for Simplicial_complex, also added to doc about knn git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@979 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 7d0a98369571ba5fc40196f41e74dd9d54b094ec --- src/CMakeLists.txt | 6 +++--- .../include/gudhi/Witness_complex.h | 23 +++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e79e0b5..4598bc19 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,10 +52,10 @@ else() add_subdirectory(example/Persistent_cohomology) add_subdirectory(example/Skeleton_blocker) add_subdirectory(example/Contraction) - add_subdirectory(example/Hasse_complex) - add_subdirectort(example/Witness_complex) + # add_subdirectory(example/Hasse_complex) + add_subdirectory(example/Witness_complex) # add_subdirectory(example/Alpha_shapes) - add_subdirectory(example/Bottleneck) + # add_subdirectory(example/Bottleneck) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 2b6a6ad5..90b2e094 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -75,7 +75,7 @@ namespace Gudhi { typedef std::vector< double > Point_t; typedef std::vector< Point_t > Point_Vector; - typedef typename Simplicial_complex::Filtration_value Filtration_value; + //typedef typename Simplicial_complex::Filtration_value Filtration_value; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; typedef std::pair< Simplex_handle, bool > typePairSimplexBool; @@ -96,16 +96,25 @@ namespace Gudhi { */ //@{ + + // Witness_range> /** * \brief Iterative construction of the witness complex. * \details The witness complex is written in sc_ basing on a matrix knn of * nearest neighbours of the form {witnesses}x{landmarks}. - * Parameter dim serves as the limit for the number of closest landmarks to consider. + * + * The type KNearestNeighbors can be seen as + * Witness_range>, where + * Witness_range and Closest_landmark_range are random access ranges. + * + * Constructor takes into account at most (dim+1) + * first landmarks from each landmark range to construct simplices. + * * Landmarks are supposed to be in [0,nbL_-1] */ - template< typename KNearestNeighbours > - Witness_complex(KNearestNeighbours const & knn, + template< typename KNearestNeighbors > + Witness_complex(KNearestNeighbors const & knn, Simplicial_complex & sc_, int nbL_, int dim ): nbL(nbL_), sc(sc_) @@ -125,7 +134,7 @@ namespace Gudhi { // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; vv = {i}; - returnValue = sc.insert_simplex(vv, Filtration_value(0.0)); + returnValue = sc.insert_simplex(vv); /* TODO Error if not inserted : normally no need here though*/ } int k=1; /* current dimension in iterative construction */ @@ -163,8 +172,8 @@ namespace Gudhi { * by witness witness_id are already in the complex. * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id */ - template - bool all_faces_in(KNearestNeighbours const &knn, int witness_id, int k) + template + bool all_faces_in(KNearestNeighbors const &knn, int witness_id, int k) { //std::cout << "All face in with the landmark " << inserted_vertex << std::endl; std::vector< Vertex_handle > facet; -- cgit v1.2.3 From e8afd1278aac5b5d76c5171092dca5954961431a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 20 Jan 2016 08:44:44 +0000 Subject: Cmake witness fix for cmake in a build directory and 'make test' to work. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@980 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b3e08e5d5c04c4bc5fbc8a120332e2578cbbe586 --- src/Witness_complex/example/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index b5770ba6..fa6dd062 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -3,13 +3,27 @@ project(GUDHIWitnessComplex) # A simple example add_executable( witness_complex_from_file witness_complex_from_file.cpp ) - add_test( witness_complex_from_bunny &{CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) + add_test( witness_complex_from_bunny ${CMAKE_CURRENT_BINARY_DIR}/witness_complex_from_file ${CMAKE_SOURCE_DIR}/data/points/bunny_5000 100) if(CGAL_FOUND) if (NOT CGAL_VERSION VERSION_LESS 4.6.0) message(STATUS "CGAL version: ${CGAL_VERSION}.") include( ${CGAL_USE_FILE} ) + # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 + # A workaround is to add "-std=c++11" again. + # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html + # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html + # but it implies to use cmake version 3.1 at least. + if(NOT MSVC) + include(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + endif() + # - End of workaround find_package(Eigen3 3.1.0) if (EIGEN3_FOUND) -- cgit v1.2.3 From 9bb012812fe7789fe5cc8cb5cd0aa4212e0af221 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 20 Jan 2016 10:34:31 +0000 Subject: Added the forgotten concept, added asserts nbP >= nbL, some header_defines git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@981 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d7c27be6bb66c79cf73971a80659079b1c8b12e5 --- src/Witness_complex/concept/Simplicial_complex.h | 83 ++++++++++++++++++++++ .../gudhi/Landmark_choice_by_furthest_point.h | 5 +- .../gudhi/Landmark_choice_by_random_point.h | 5 +- .../include/gudhi/Witness_complex.h | 4 +- .../include/gudhi/Witness_complex_doc.h | 4 +- 5 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/Witness_complex/concept/Simplicial_complex.h (limited to 'src') diff --git a/src/Witness_complex/concept/Simplicial_complex.h b/src/Witness_complex/concept/Simplicial_complex.h new file mode 100644 index 00000000..6b0df212 --- /dev/null +++ b/src/Witness_complex/concept/Simplicial_complex.h @@ -0,0 +1,83 @@ + /* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \brief The concept Simplicial_Complex describes the requirements + * for a type to implement a simplicial complex, + * used for example to build a 'Witness_complex'. + */ +struct Simplicial_complex +{ +/** Handle to specify a simplex. */ + typedef unspecified Simplex_handle; +/** Handle to specify a vertex. Must be a non-negative integer. */ + typedef unspecified Vertex_handle; + +/** Returns a Simplex_hanlde that is different from all simplex handles + * of the simplices. */ + Simplex_handle null_simplex(); +/** \brief Returns the number of simplices in the complex. + * + * Does not count the empty simplex. */ + size_t num_simplices(); + +/** \brief Iterator over the simplices of the complex, + * in an arbitrary order. + * + * 'value_type' must be 'Simplex_handle'.*/ +typedef unspecified Complex_simplex_iterator; +typedef unspecified Complex_simplex_range; + +/** +* \brief Returns a range over all the simplices of a +* complex. +*/ +Complex_simplex_range complex_simplex_range(); + +/** \brief Iterator over vertices of a simplex. + * + * 'value type' must be 'Vertex_handle'.*/ + typedef unspecified Simplex_vertex_range; + +/** \brief Returns a range over vertices of a given + * simplex. */ + Simplex_vertex_range simplex_vertex_range(Simplex_handle const & simplex); + +/** \brief Return type of an insertion of a simplex + */ + typedef unspecified Insertion_result_type; + +/** \brief Input range of vertices. + * 'value_type' must be 'Vertex_handle'. */ + typedef unspecified Input_vertex_range; + +/** \brief Inserts a simplex with vertices from a given range + * 'vertex_range' in the simplicial complex. + * */ + Insertion_result_type insert_simplex(Input_vertex_range const & vertex_range); + +/** \brief Finds a simplex with vertices given by a range + * + * If a simplex exists, its Simplex_handle is returned. + * Otherwise null_simplex() is returned. */ + Simplex_handle find(Input_vertex_range const & vertex_range); + +}; diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 163975c9..8dfec99c 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ -#define GUDHI_LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ +#ifndef LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ +#define LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ namespace Gudhi { @@ -56,6 +56,7 @@ public: KNearestNeighbours &knn) { int nb_points = points.end() - points.begin(); + assert(nb_points >= nbL); std::vector> wit_land_dist(nb_points, std::vector()); // distance matrix witness x landmarks typeVectorVertex chosen_landmarks; // landmark list diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index a54f3848..3f8a8d32 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ -#define GUDHI_LANDMARK_CHOICE_BY_RANDOM_POINT_H_ +#ifndef LANDMARK_CHOICE_BY_RANDOM_POINT_H_ +#define LANDMARK_CHOICE_BY_RANDOM_POINT_H_ namespace Gudhi { @@ -51,6 +51,7 @@ public: KNearestNeighbours &knn) { int nbP = points.end() - points.begin(); + assert(nbP >= nbL); std::set landmarks; int current_number_of_landmarks=0; // counter for landmarks diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 90b2e094..819a0583 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef GUDHI_WITNESS_COMPLEX_H_ -#define GUDHI_WITNESS_COMPLEX_H_ +#ifndef WITNESS_COMPLEX_H_ +#define WITNESS_COMPLEX_H_ #include #include diff --git a/src/Witness_complex/include/gudhi/Witness_complex_doc.h b/src/Witness_complex/include/gudhi/Witness_complex_doc.h index 71c8776b..dbe9e7ce 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex_doc.h +++ b/src/Witness_complex/include/gudhi/Witness_complex_doc.h @@ -1,5 +1,5 @@ -#ifndef WITNESS_COMPLEX_DOC_ -#define WITNESS_COMPLEX_DOC_ +#ifndef WITNESS_COMPLEX_DOC_H_ +#define WITNESS_COMPLEX_DOC_H_ /** \defgroup witness_complex Witness complex -- cgit v1.2.3 From d13a8867ca368b1f56be3ba151d2042728fb4754 Mon Sep 17 00:00:00 2001 From: skachano Date: Wed, 20 Jan 2016 10:43:59 +0000 Subject: Almost all Vincent's remarks git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@982 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 32564e3521e0807e26bd2c07d682751a3d47e6da --- .../example/witness_complex_sphere.cpp | 34 ++-------------------- .../test/simple_witness_complex.cpp | 4 +-- .../test/witness_complex_points.cpp | 4 +-- 3 files changed, 7 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index d73445b9..9dc458d4 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -41,36 +41,9 @@ using namespace Gudhi; using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; -//typedef std::vector< std::vector > Point_Vector; typedef Witness_complex< Simplex_tree<> > WitnessComplex; -/** - * \brief Customized version of read_points - * which takes into account a possible nbP first line - * - */ -inline void -read_points_cust ( std::string file_name , std::vector< std::vector< double > > & points) -{ - std::ifstream in_file (file_name.c_str(),std::ios::in); - if(!in_file.is_open()) - { - std::cerr << "Unable to open file " << file_name << std::endl; - return; - } - std::string line; - double x; - while( getline ( in_file , line ) ) - { - std::vector< double > point; - std::istringstream iss( line ); - while(iss >> x) { point.push_back(x); } - if (point.size() != 1) - points.push_back(point); - } - in_file.close(); -} /** Write a gnuplot readable file. * Data range is a random access range of pairs (arg, value) @@ -86,15 +59,14 @@ void write_data( Data_range & data, std::string filename ) int main (int argc, char * const argv[]) { - if (argc != 3) + if (argc != 2) { std::cerr << "Usage: " << argv[0] - << " path_to_point_file nbL \n"; + << " nbL \n"; return 0; } - std::string file_name = argv[1]; - int nbL = atoi(argv[2]); + int nbL = atoi(argv[1]); clock_t start, end; // Construct the Simplex Tree diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp index 86f5bcd1..7735ca6f 100644 --- a/src/Witness_complex/test/simple_witness_complex.cpp +++ b/src/Witness_complex/test/simple_witness_complex.cpp @@ -2,9 +2,9 @@ * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author(s): Vincent Rouvreau + * Author(s): Siargey Kachanovich * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * Copyright (C) 2016 INRIA Sophia Antipolis-Méditerranée (France) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index e9fac9b8..3850bd82 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -2,9 +2,9 @@ * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author(s): Vincent Rouvreau + * Author(s): Siargey Kachanovich * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * Copyright (C) 2016 INRIA Sophia Antipolis-Méditerranée (France) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3 From 9ce621289b5061e30329426aef5695ae3e19a099 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 21 Jan 2016 20:46:10 +0000 Subject: cpplint/cppcheck fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/VR_witness@985 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4dc15b3ab0eecb8d4f5bbb1ac1cb9dabf95233e4 --- .../include/gudhi/Landmark_choice_by_random_point.h | 2 +- src/Witness_complex/include/gudhi/Witness_complex.h | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index 215c9e65..4747dd73 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -76,7 +76,7 @@ class Landmark_choice_by_random_point { std::set::iterator landmarks_it; int landmarks_i = 0; for (landmarks_it = landmarks.begin(), landmarks_i = 0; landmarks_it != landmarks.end(); - landmarks_it++, landmarks_i++) { + ++landmarks_it, landmarks_i++) { dist_i dist = std::make_pair(euclidean_distance(points[points_i], points[*landmarks_it]), landmarks_i); l_heap.push(dist); } diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 27f7a9c0..34cbc882 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -82,7 +82,6 @@ class Witness_complex { private: int nbL; // Number of landmarks - double density; // Desired density Simplicial_complex& sc; // Simplicial complex public: @@ -116,8 +115,6 @@ class Witness_complex { // Construction of the active witness list int nbW = knn.size(); typeVectorVertex vv; - typeSimplex simplex; - typePairSimplexBool returnValue; int counter = 0; /* The list of still useful witnesses * it will diminuish in the course of iterations @@ -128,7 +125,7 @@ class Witness_complex { // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; vv = {i}; - returnValue = sc.insert_simplex(vv); + sc.insert_simplex(vv); // TODO(SK) Error if not inserted : normally no need here though } int k = 1; /* current dimension in iterative construction */ @@ -145,7 +142,8 @@ class Witness_complex { if (ok) { for (int i = 0; i != k + 1; ++i) simplex_vector.push_back(knn[*it][i]); - returnValue = sc.insert_simplex(simplex_vector, 0.0); + sc.insert_simplex(simplex_vector, 0.0); + // TODO(SK) Error if not inserted : normally no need here though it++; } else { active_w.erase(it++); // First increase the iterator and then erase the previous element @@ -183,7 +181,7 @@ class Witness_complex { } template - void print_vector(const std::vector v) { + static void print_vector(const std::vector& v) { std::cout << "["; if (!v.empty()) { std::cout << *(v.begin()); -- cgit v1.2.3 From 945a98537205d4f3e3f7c3c652f373af89723731 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 21 Jan 2016 21:41:33 +0000 Subject: Warning fix - if not BOOST_CHECK, variable b_print_output seen as not used. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/VR_witness@986 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 171f360b478c98edd9e177808e2c0b8410bfbd37 --- src/Witness_complex/test/witness_complex_points.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index 78f01e08..300b2ac5 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -55,12 +55,12 @@ BOOST_AUTO_TEST_CASE(witness_complex_points) { Landmark_choice_by_random_point lcrp(points, 100, knn); assert(!knn.empty()); WitnessComplex witnessComplex1(knn, complex1, 100, 3); - assert(witnessComplex1.is_witness_complex(knn, b_print_output)); + BOOST_CHECK(witnessComplex1.is_witness_complex(knn, b_print_output)); // Second test: furthest choice knn.clear(); Simplex_tree complex2; Landmark_choice_by_furthest_point lcfp(points, 100, knn); WitnessComplex witnessComplex2(knn, complex2, 100, 3); - assert(witnessComplex2.is_witness_complex(knn, b_print_output)); + BOOST_CHECK(witnessComplex2.is_witness_complex(knn, b_print_output)); } -- cgit v1.2.3 From 98bb425ef8c401b2eb8d161393c389b5cf6070c8 Mon Sep 17 00:00:00 2001 From: salinasd Date: Sun, 31 Jan 2016 14:56:30 +0000 Subject: remove creation of useless visitor for test that were just used for display git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_insert_with_subfaces_fix@990 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 13b3baec7f449d1d74cfaca2211571b468be1486 --- src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp index 42482e23..71b1833b 100644 --- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp +++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp @@ -601,7 +601,7 @@ bool test_link4() { } bool test_link5() { - Complex complex(0, new Print_complex_visitor()); + Complex complex(0); // Build the complexes build_complete(4, complex); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); @@ -621,7 +621,7 @@ bool test_link5() { } bool test_link6() { - Complex complex(0, new Print_complex_visitor()); + Complex complex(0); // Build the complexes build_complete(4, complex); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); @@ -642,7 +642,7 @@ bool test_link6() { } bool test_link7() { - Complex complex(0, new Print_complex_visitor()); + Complex complex(0); // Build the complexes build_complete(6, complex); complex.add_vertex(); -- cgit v1.2.3 From 7e667b71d937f83b82240afbf90b8cde7225eb8a Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 2 Feb 2016 14:49:56 +0000 Subject: landmark choice functions are now static git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@994 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f83d337feab944e2c823b8e127f1a8d612d0a1bd --- .../example/witness_complex_from_file.cpp | 2 +- .../example/witness_complex_sphere.cpp | 2 +- .../gudhi/Landmark_choice_by_furthest_point.h | 22 +++++---------------- .../gudhi/Landmark_choice_by_random_point.h | 23 ++++++---------------- .../test/witness_complex_points.cpp | 6 ++---- 5 files changed, 15 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index d94502b1..77109512 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -102,7 +102,7 @@ int main(int argc, char * const argv[]) { // Choose landmarks start = clock(); std::vector > knn; - Landmark_choice_by_random_point(point_vector, nbL, knn); + Gudhi::witness_complex::landmark_choice_by_random_point(point_vector, nbL, knn); end = clock(); std::cout << "Landmark choice for " << nbL << " landmarks took " << static_cast(end - start) / CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 36f63437..1ff35bff 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -82,7 +82,7 @@ int main(int argc, char * const argv[]) { // Choose landmarks start = clock(); std::vector > knn; - Landmark_choice_by_random_point(point_vector, nbL, knn); + Gudhi::witness_complex::landmark_choice_by_random_point(point_vector, nbL, knn); // Compute witness complex WitnessComplex(knn, simplex_tree, nbL, point_vector[0].size()); diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index bb7e87f5..47cd888d 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -31,20 +31,9 @@ namespace Gudhi { namespace witness_complex { -/** - * \class Landmark_choice_by_furthest_point - * \brief The class `Landmark_choice_by_furthest_point` allows to construct the matrix - * of closest landmarks per witness by iteratively choosing the furthest witness - * from the set of already chosen landmarks as the new landmark. - * \ingroup witness_complex - */ - -class Landmark_choice_by_furthest_point { - private: - typedef std::vector typeVectorVertex; + typedef std::vector typeVectorVertex; - public: - /** + /** * \brief Landmark choice strategy by iteratively adding the furthest witness from the * current landmark set as the new landmark. * \details It chooses nbL landmarks from a random access range `points` and @@ -53,9 +42,9 @@ class Landmark_choice_by_furthest_point { template - Landmark_choice_by_furthest_point(Point_random_access_range const &points, - int nbL, - KNearestNeighbours &knn) { + void landmark_choice_by_furthest_point(Point_random_access_range const &points, + int nbL, + KNearestNeighbours &knn) { int nb_points = points.end() - points.begin(); assert(nb_points >= nbL); // distance matrix witness x landmarks @@ -98,7 +87,6 @@ class Landmark_choice_by_furthest_point { [&wit_land_dist, i](int a, int b) { return wit_land_dist[i][a] < wit_land_dist[i][b]; }); } -}; } // namespace witness_complex diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index 4747dd73..dc364007 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -32,26 +32,16 @@ namespace Gudhi { namespace witness_complex { -/** - * \class Landmark_choice_by_random_point - * \brief The class `Landmark_choice_by_random_point` allows to construct the matrix - * of closest landmarks per witness by iteratively choosing a random non-chosen witness - * as a new landmark. - * \ingroup witness_complex - */ - -class Landmark_choice_by_random_point { - public: /** \brief Landmark choice strategy by taking random vertices for landmarks. * \details It chooses nbL distinct landmarks from a random access range `points` * and outputs a matrix {witness}*{closest landmarks} in knn. */ template - Landmark_choice_by_random_point(Point_random_access_range const &points, - int nbL, - KNearestNeighbours &knn) { + typename Point_random_access_range> + void landmark_choice_by_random_point(Point_random_access_range const &points, + int nbL, + KNearestNeighbours &knn) { int nbP = points.end() - points.begin(); assert(nbP >= nbL); std::set landmarks; @@ -71,8 +61,8 @@ class Landmark_choice_by_random_point { knn = KNearestNeighbours(nbP); for (int points_i = 0; points_i < nbP; points_i++) { std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2) { - return j1.first > j2.first; - }); + return j1.first > j2.first; + }); std::set::iterator landmarks_it; int landmarks_i = 0; for (landmarks_it = landmarks.begin(), landmarks_i = 0; landmarks_it != landmarks.end(); @@ -87,7 +77,6 @@ class Landmark_choice_by_random_point { } } } -}; } // namespace witness_complex diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index 300b2ac5..cb1639e1 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -37,8 +37,6 @@ typedef std::vector Point; typedef std::vector< Vertex_handle > typeVectorVertex; typedef Gudhi::Simplex_tree<> Simplex_tree; typedef Gudhi::witness_complex::Witness_complex WitnessComplex; -typedef Gudhi::witness_complex::Landmark_choice_by_random_point Landmark_choice_by_random_point; -typedef Gudhi::witness_complex::Landmark_choice_by_furthest_point Landmark_choice_by_furthest_point; BOOST_AUTO_TEST_CASE(witness_complex_points) { std::vector< typeVectorVertex > knn; @@ -52,7 +50,7 @@ BOOST_AUTO_TEST_CASE(witness_complex_points) { bool b_print_output = false; // First test: random choice Simplex_tree complex1; - Landmark_choice_by_random_point lcrp(points, 100, knn); + Gudhi::witness_complex::landmark_choice_by_random_point(points, 100, knn); assert(!knn.empty()); WitnessComplex witnessComplex1(knn, complex1, 100, 3); BOOST_CHECK(witnessComplex1.is_witness_complex(knn, b_print_output)); @@ -60,7 +58,7 @@ BOOST_AUTO_TEST_CASE(witness_complex_points) { // Second test: furthest choice knn.clear(); Simplex_tree complex2; - Landmark_choice_by_furthest_point lcfp(points, 100, knn); + Gudhi::witness_complex::landmark_choice_by_furthest_point(points, 100, knn); WitnessComplex witnessComplex2(knn, complex2, 100, 3); BOOST_CHECK(witnessComplex2.is_witness_complex(knn, b_print_output)); } -- cgit v1.2.3 From d15e4b04a8b333d0adc09e321241a6a5daa9b94a Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 4 Feb 2016 12:17:04 +0000 Subject: test with include CGAL_USE_FILE to fix windows issue git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@1000 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 11a5fb78933306cfc83951174b38a03837fef58a --- src/Simplex_tree/example/CMakeLists.txt | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index c70cfe35..de75415d 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -14,11 +14,24 @@ add_test(mini_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/mini_simplex_tree) # An example with Simplex-tree using CGAL alpha_shapes_3 if(GMP_FOUND AND CGAL_FOUND) - message("CGAL_lib = ${CGAL_LIBRARIES_DIR}") - message("GMP_LIBRARIES = ${GMP_LIBRARIES}") - INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) - INCLUDE_DIRECTORIES(${CGAL_INCLUDE_DIRS}) - add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) - target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY}) - add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) + include( ${CGAL_USE_FILE} ) + # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 + # A workaround is to add "-std=c++11" again. + # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html + # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html + # but it implies to use cmake version 3.1 at least. + if(NOT MSVC) + include(CheckCXXCompilerFlag) + CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + endif() + # - End of workaround + + INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) + add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) + target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY}) + add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) endif() -- cgit v1.2.3 From 6892c6dbcf1eeaa27825d416503413a74808b625 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 4 Feb 2016 12:44:23 +0000 Subject: requires boost also git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@1001 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: aca5ee1d5587d2e613691a539bb166ac592c137c --- src/Simplex_tree/example/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index de75415d..a86b99a1 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -32,6 +32,6 @@ if(GMP_FOUND AND CGAL_FOUND) INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) - target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY}) + target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY} ${Boost_SYSTEM_LIBRARY}) add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) endif() -- cgit v1.2.3 From c85b24f7e0c489093e0c5ccca934eb53fafab623 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 4 Feb 2016 16:11:42 +0000 Subject: CMake strategy modification git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@1003 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c917934525e020b54b2f4506b5c9d060a28c9d89 --- CMakeLists.txt | 105 +++++++++++++++----------- data/points/generator/CMakeLists.txt | 16 ---- src/Bottleneck/test/CMakeLists.txt | 4 - src/CMakeLists.txt | 67 ++++++++++------ src/GudhUI/CMakeLists.txt | 20 ----- src/Persistent_cohomology/test/CMakeLists.txt | 4 - src/Simplex_tree/example/CMakeLists.txt | 17 ----- src/Simplex_tree/test/CMakeLists.txt | 4 - src/Skeleton_blocker/test/CMakeLists.txt | 4 - 9 files changed, 105 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index edf7e63f..8ced7b0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,52 +7,71 @@ configure_file(GUDHIVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIVersion.cmake" find_package(Boost REQUIRED COMPONENTS system filesystem unit_test_framework chrono timer program_options thread REQUIRED) -set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") -message("CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") -message("CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}") - -enable_testing() - -if(MSVC) - # Turn off some VC++ warnings - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -std=c++11 -Wall -Wpedantic -Wsign-compare") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") -endif() - -set(Boost_USE_STATIC_LIBS ON) -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) - -find_package(GMP) -if(GMP_FOUND) - find_package(GMPXX) -endif() - -find_package(CGAL) - -# Find TBB package for parallel sort - not mandatory, just optional. -set(TBB_FIND_QUIETLY ON) -find_package(TBB) - -# Required programs for unitary tests purpose -FIND_PROGRAM( GCOVR_PATH gcovr ) -if (GCOVR_PATH) - message("gcovr found in ${GCOVR_PATH}") -endif() -# Required programs for unitary tests purpose -FIND_PROGRAM( GPROF_PATH gprof ) -if (GPROF_PATH) - message("gprof found in ${GPROF_PATH}") -endif() - - if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") else() + + set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") + set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") + message("CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}") + message("CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}") + + enable_testing() + + find_package(GMP) + if(GMP_FOUND) + INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) + find_package(GMPXX) + if(GMPXX_FOUND) + INCLUDE_DIRECTORIES(${GMPXX_INCLUDE_DIR}) + endif() + endif() + + # find CGAL package before set of CXX flags because + # in CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 + set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags") + find_package(CGAL) + if(CGAL_FOUND) + include( ${CGAL_USE_FILE} ) + set(CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS "-frounding-math") + endif() + + if(MSVC) + # Turn off some VC++ warnings + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic -Wsign-compare ${CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0") + # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + endif() + + if(CMAKE_BUILD_TYPE MATCHES Debug) + message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") + else() + message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") + endif() + + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + + # Find TBB package for parallel sort - not mandatory, just optional. + set(TBB_FIND_QUIETLY ON) + find_package(TBB) + + # Required programs for unitary tests purpose + FIND_PROGRAM( GCOVR_PATH gcovr ) + if (GCOVR_PATH) + message("gcovr found in ${GCOVR_PATH}") + endif() + # Required programs for unitary tests purpose + FIND_PROGRAM( GPROF_PATH gprof ) + if (GPROF_PATH) + message("gprof found in ${GPROF_PATH}") + endif() + + # BOOST ISSUE result_of vs C++11 add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE) # BOOST ISSUE with Libraries name resolution under Windows diff --git a/data/points/generator/CMakeLists.txt b/data/points/generator/CMakeLists.txt index 26b44446..c01a380d 100644 --- a/data/points/generator/CMakeLists.txt +++ b/data/points/generator/CMakeLists.txt @@ -5,22 +5,6 @@ if(CGAL_FOUND) if (NOT CGAL_VERSION VERSION_LESS 4.6.0) message(STATUS "CGAL version: ${CGAL_VERSION}.") - include( ${CGAL_USE_FILE} ) - # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. - # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 - # A workaround is to add "-std=c++11" again. - # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html - # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html - # but it implies to use cmake version 3.1 at least. - if(NOT MSVC) - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11) - if(COMPILER_SUPPORTS_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() - endif() - # - End of workaround - find_package(Eigen3 3.1.0) if (EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) diff --git a/src/Bottleneck/test/CMakeLists.txt b/src/Bottleneck/test/CMakeLists.txt index 3dfd80cd..ad63c080 100644 --- a/src/Bottleneck/test/CMakeLists.txt +++ b/src/Bottleneck/test/CMakeLists.txt @@ -4,14 +4,10 @@ project(GUDHIBottleneckUT) if (GCOVR_PATH) # for gcovr to make coverage reports - Corbera Jenkins plugin set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") endif() if (GPROF_PATH) # for gprof to make coverage reports - Jenkins set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() add_executable ( BottleneckUT bottleneck_unit_test.cpp ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c38483c..a67e7c92 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,33 +9,52 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") find_package(Boost REQUIRED COMPONENTS system filesystem program_options chrono timer REQUIRED) -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif() -if(MSVC) - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -endif() - -set(Boost_USE_STATIC_LIBS ON) -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) - -find_package(GMP) -if(GMP_FOUND) - find_package(GMPXX) -endif() - -find_package(CGAL) - -# Find TBB package for parallel sort - not mandatory, just optional. -set(TBB_FIND_QUIETLY ON) -find_package(TBB) - if(NOT Boost_FOUND) message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.") else() + + find_package(GMP) + if(GMP_FOUND) + INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) + find_package(GMPXX) + if(GMPXX_FOUND) + INCLUDE_DIRECTORIES(${GMPXX_INCLUDE_DIR}) + endif() + endif() + + # find CGAL package before set of CXX flags because + # in CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 + set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags") + find_package(CGAL) + if(CGAL_FOUND) + include( ${CGAL_USE_FILE} ) + set(CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS "-frounding-math") + endif() + + if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") + endif() + if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS}") + endif() + + if(CMAKE_BUILD_TYPE MATCHES Debug) + message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") + else() + message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") + endif() + + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + + # Find TBB package for parallel sort - not mandatory, just optional. + set(TBB_FIND_QUIETLY ON) + find_package(TBB) + # BOOST ISSUE result_of vs C++11 add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE) # BOOST ISSUE with Libraries name resolution under Windows diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt index 71f4fd1a..1ee43d91 100644 --- a/src/GudhUI/CMakeLists.txt +++ b/src/GudhUI/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 2.8) project(GudhUI) -find_package(CGAL COMPONENTS Qt4) find_package(Qt4) find_package(QGLViewer) find_package(OpenGL) @@ -14,27 +13,8 @@ if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) SET(Boost_USE_STATIC_LIBS ON) SET(Boost_USE_MULTITHREAD OFF) - INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) - LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) - include(${QT_USE_FILE}) - include(${CGAL_USE_FILE}) - # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. - # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 - # A workaround is to add "-std=c++11" again. - # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html - # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html - # but it implies to use cmake version 3.1 at least. - if(NOT MSVC) - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11) - if(COMPILER_SUPPORTS_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() - endif() - # - End of workaround - include_directories (${QGLVIEWER_INCLUDE_DIR}) include_directories(.) diff --git a/src/Persistent_cohomology/test/CMakeLists.txt b/src/Persistent_cohomology/test/CMakeLists.txt index ed63a6ac..d16be5be 100644 --- a/src/Persistent_cohomology/test/CMakeLists.txt +++ b/src/Persistent_cohomology/test/CMakeLists.txt @@ -4,14 +4,10 @@ project(GUDHIPersistentCohomologyUT) if (GCOVR_PATH) # for gcovr to make coverage reports - Corbera Jenkins plugin set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") endif() if (GPROF_PATH) # for gprof to make coverage reports - Jenkins set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() add_executable ( PersistentCohomologyUT persistent_cohomology_unit_test.cpp ) diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index a86b99a1..200161a6 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -14,23 +14,6 @@ add_test(mini_simplex_tree ${CMAKE_CURRENT_BINARY_DIR}/mini_simplex_tree) # An example with Simplex-tree using CGAL alpha_shapes_3 if(GMP_FOUND AND CGAL_FOUND) - include( ${CGAL_USE_FILE} ) - # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. - # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 - # A workaround is to add "-std=c++11" again. - # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html - # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html - # but it implies to use cmake version 3.1 at least. - if(NOT MSVC) - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG(-std=c++11 COMPILER_SUPPORTS_CXX11) - if(COMPILER_SUPPORTS_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif() - endif() - # - End of workaround - - INCLUDE_DIRECTORIES(${GMP_INCLUDE_DIR}) add_executable ( simplex_tree_from_alpha_shapes_3 simplex_tree_from_alpha_shapes_3.cpp ) target_link_libraries(simplex_tree_from_alpha_shapes_3 ${GMP_LIBRARIES} ${CGAL_LIBRARY} ${Boost_SYSTEM_LIBRARY}) add_test(simplex_tree_from_alpha_shapes_3 ${CMAKE_CURRENT_BINARY_DIR}/simplex_tree_from_alpha_shapes_3 ${CMAKE_SOURCE_DIR}/data/points/bunny_5000) diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index c9eae163..1f2f7d33 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -4,14 +4,10 @@ project(GUDHISimplexTreeUT) if (GCOVR_PATH) # for gcovr to make coverage reports - Corbera Jenkins plugin set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") endif() if (GPROF_PATH) # for gprof to make coverage reports - Jenkins set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() add_executable ( SimplexTreeUT simplex_tree_unit_test.cpp ) diff --git a/src/Skeleton_blocker/test/CMakeLists.txt b/src/Skeleton_blocker/test/CMakeLists.txt index 8b6fb672..5e063845 100644 --- a/src/Skeleton_blocker/test/CMakeLists.txt +++ b/src/Skeleton_blocker/test/CMakeLists.txt @@ -4,14 +4,10 @@ project(GUDHIskbl) if (GCOVR_PATH) # for gcovr to make coverage reports - Corbera Jenkins plugin set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") endif() if (GPROF_PATH) # for gprof to make coverage reports - Jenkins set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") endif() add_executable(TestSkeletonBlockerComplex TestSkeletonBlockerComplex.cpp) -- cgit v1.2.3 From abb3faa7088cd6e59f769f2f3b31ecd1b3b0fc0e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 9 Feb 2016 15:54:58 +0000 Subject: Finally, let CGAL set the flags, but before setting CXX_FLAGS with "-std=c++11" git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Win64_Boost_Xunit_fix@1011 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: faeca77f4eebf969e608b0c3be67893d646845a9 --- CMakeLists.txt | 17 ++++++++--------- src/CMakeLists.txt | 21 ++++++++++----------- 2 files changed, 18 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ced7b0d..0ee142c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,29 +27,28 @@ else() endif() endif() - # find CGAL package before set of CXX flags because - # in CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CMAKE_CXX_FLAGS are overwritten. # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 - set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags") + # A workaround is to include(${CGAL_USE_FILE}) before adding "-std=c++11". + # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html + # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html + # but it implies to use cmake version 3.1 at least. find_package(CGAL) if(CGAL_FOUND) include( ${CGAL_USE_FILE} ) - set(CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS "-frounding-math") endif() if(MSVC) # Turn off some VC++ warnings set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic -Wsign-compare ${CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0") - # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic -Wsign-compare") endif() if(CMAKE_BUILD_TYPE MATCHES Debug) - message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") + message("++ Debug compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") else() - message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") + message("++ Release compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") endif() set(Boost_USE_STATIC_LIBS ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a67e7c92..97d53306 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,29 +22,28 @@ else() endif() endif() - # find CGAL package before set of CXX flags because - # in CMakeLists.txt, when include(${CGAL_USE_FILE}), CXX_FLAGS are overwritten. + # In CMakeLists.txt, when include(${CGAL_USE_FILE}), CMAKE_CXX_FLAGS are overwritten. # cf. http://doc.cgal.org/latest/Manual/installation.html#title40 - set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags") + # A workaround is to include(${CGAL_USE_FILE}) before adding "-std=c++11". + # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html + # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html + # but it implies to use cmake version 3.1 at least. find_package(CGAL) if(CGAL_FOUND) include( ${CGAL_USE_FILE} ) - set(CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS "-frounding-math") - endif() - - if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") endif() + if(MSVC) + # Turn off some VC++ warnings set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${CMAKE_CXX_CGAL_FOR_GUDHI_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wpedantic -Wsign-compare") endif() if(CMAKE_BUILD_TYPE MATCHES Debug) - message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") + message("++ Debug compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") else() - message("Compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") + message("++ Release compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") endif() set(Boost_USE_STATIC_LIBS ON) -- cgit v1.2.3 From 2d8cc490a799d991fee29d923c15368c83d24f85 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 11 Feb 2016 14:17:55 +0000 Subject: A small change in sphere example git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1015 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4c479a899c1a3686ac53a03affea63bc96208c7c --- src/Witness_complex/example/witness_complex_sphere.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 1ff35bff..f9d0b5a2 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -90,6 +90,7 @@ int main(int argc, char * const argv[]) { double time = static_cast(end - start) / CLOCKS_PER_SEC; std::cout << "Witness complex for " << nbL << " landmarks took " << time << " s. \n"; + std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << "\n"; l_time.push_back(std::make_pair(nbP, time)); } write_data(l_time, "w_time.dat"); -- cgit v1.2.3 From b7796215d4eac6b4c43ad70998c3737a6527eebb Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 11 Feb 2016 16:05:15 +0000 Subject: Commited Marc's remarks git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1017 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d87eb82f60f4f943f59622f33521bcdce7873091 --- src/Witness_complex/concept/Simplicial_complex.h | 11 ++--------- .../example/witness_complex_from_file.cpp | 13 +------------ src/Witness_complex/example/witness_complex_sphere.cpp | 10 +++++----- .../include/gudhi/Landmark_choice_by_random_point.h | 6 ++++++ src/Witness_complex/include/gudhi/Witness_complex.h | 18 ++++++------------ src/Witness_complex/test/simple_witness_complex.cpp | 2 +- src/Witness_complex/test/witness_complex_points.cpp | 4 ++-- 7 files changed, 23 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/concept/Simplicial_complex.h b/src/Witness_complex/concept/Simplicial_complex.h index d7f3496d..9e9f2ff8 100644 --- a/src/Witness_complex/concept/Simplicial_complex.h +++ b/src/Witness_complex/concept/Simplicial_complex.h @@ -40,16 +40,11 @@ struct Simplicial_complex { /** Returns a Simplex_hanlde that is different from all simplex handles * of the simplices. */ Simplex_handle null_simplex(); - /** \brief Returns the number of simplices in the complex. - * - * Does not count the empty simplex. */ - size_t num_simplices(); /** \brief Iterator over the simplices of the complex, * in an arbitrary order. * * 'value_type' must be 'Simplex_handle'.*/ - typedef unspecified Complex_simplex_iterator; typedef unspecified Complex_simplex_range; /** @@ -71,19 +66,17 @@ struct Simplicial_complex { */ typedef unspecified Insertion_result_type; - /** \brief Input range of vertices. - * 'value_type' must be 'Vertex_handle'. */ - typedef unspecified Input_vertex_range; - /** \brief Inserts a simplex with vertices from a given range * 'vertex_range' in the simplicial complex. * */ + template< typedef Input_vertex_range > Insertion_result_type insert_simplex(Input_vertex_range const & vertex_range); /** \brief Finds a simplex with vertices given by a range * * If a simplex exists, its Simplex_handle is returned. * Otherwise null_simplex() is returned. */ + template< typedef Input_vertex_range > Simplex_handle find(Input_vertex_range const & vertex_range); }; diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 77109512..98d1fe9c 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -68,17 +68,6 @@ read_points_cust(std::string file_name, std::vector< std::vector< double > > & p in_file.close(); } -/** Write a gnuplot readable file. - * Data range is a random access range of pairs (arg, value) - */ -template < typename Data_range > -void write_data(Data_range & data, std::string filename) { - std::ofstream ofs(filename, std::ofstream::out); - for (auto entry : data) - ofs << entry.first << ", " << entry.second << "\n"; - ofs.close(); -} - int main(int argc, char * const argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] @@ -109,7 +98,7 @@ int main(int argc, char * const argv[]) { // Compute witness complex start = clock(); - WitnessComplex(knn, simplex_tree, nbL, point_vector[0].size()); + WitnessComplex(knn, nbL, point_vector[0].size(), simplex_tree); end = clock(); std::cout << "Witness complex took " << static_cast(end - start) / CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index f9d0b5a2..fae80d67 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -60,11 +60,11 @@ void write_data(Data_range & data, std::string filename) { int main(int argc, char * const argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] - << " nbL \n"; + << " number_of_landmarks \n"; return 0; } - int nbL = atoi(argv[1]); + int number_of_landmarks = atoi(argv[1]); clock_t start, end; // Construct the Simplex Tree @@ -82,13 +82,13 @@ int main(int argc, char * const argv[]) { // Choose landmarks start = clock(); std::vector > knn; - Gudhi::witness_complex::landmark_choice_by_random_point(point_vector, nbL, knn); + Gudhi::witness_complex::landmark_choice_by_random_point(point_vector, number_of_landmarks, knn); // Compute witness complex - WitnessComplex(knn, simplex_tree, nbL, point_vector[0].size()); + WitnessComplex(knn, number_of_landmarks, point_vector[0].size(), simplex_tree); end = clock(); double time = static_cast(end - start) / CLOCKS_PER_SEC; - std::cout << "Witness complex for " << nbL << " landmarks took " + std::cout << "Witness complex for " << number_of_landmarks << " landmarks took " << time << " s. \n"; std::cout << "Number of simplices is: " << simplex_tree.num_simplices() << "\n"; l_time.push_back(std::make_pair(nbP, time)); diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index dc364007..617c0258 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -35,6 +35,12 @@ namespace witness_complex { /** \brief Landmark choice strategy by taking random vertices for landmarks. * \details It chooses nbL distinct landmarks from a random access range `points` * and outputs a matrix {witness}*{closest landmarks} in knn. + * + * The type KNearestNeighbors can be seen as + * Witness_range>, where + * Witness_range and Closest_landmark_range are random access ranges and + * Vertex_handle is the label type of a vertex in a simplicial complex. + * Closest_landmark_range needs to have push_back operation. */ template Point_t; typedef std::vector< Point_t > Point_Vector; - // typedef typename Simplicial_complex::Filtration_value Filtration_value; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex; typedef std::pair< Simplex_handle, bool > typePairSimplexBool; @@ -109,9 +108,9 @@ class Witness_complex { */ template< typename KNearestNeighbors > Witness_complex(KNearestNeighbors const & knn, - Simplicial_complex & sc_, int nbL_, - int dim) : nbL(nbL_), sc(sc_) { + int dim, + Simplicial_complex & sc_) : nbL(nbL_), sc(sc_) { // Construction of the active witness list int nbW = knn.size(); typeVectorVertex vv; @@ -120,7 +119,7 @@ class Witness_complex { * it will diminuish in the course of iterations */ ActiveWitnessList active_w; // = new ActiveWitnessList(); - for (int i = 0; i != nbL; ++i) { + for (Vertex_handle i = 0; i != nbL; ++i) { // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; @@ -131,9 +130,7 @@ class Witness_complex { int k = 1; /* current dimension in iterative construction */ for (int i = 0; i != nbW; ++i) active_w.push_back(i); - // std::cout << "Successfully added edges" << std::endl; while (!active_w.empty() && k < dim) { - // std::cout << "Started the step k=" << k << std::endl; typename ActiveWitnessList::iterator it = active_w.begin(); while (it != active_w.end()) { typeVectorVertex simplex_vector; @@ -142,7 +139,7 @@ class Witness_complex { if (ok) { for (int i = 0; i != k + 1; ++i) simplex_vector.push_back(knn[*it][i]); - sc.insert_simplex(simplex_vector, 0.0); + sc.insert_simplex(simplex_vector); // TODO(SK) Error if not inserted : normally no need here though it++; } else { @@ -162,9 +159,7 @@ class Witness_complex { */ template bool all_faces_in(KNearestNeighbors const &knn, int witness_id, int k) { - // std::cout << "All face in with the landmark " << inserted_vertex << std::endl; std::vector< Vertex_handle > facet; - // Vertex_handle curr_vh = curr_sh->first; // CHECK ALL THE FACETS for (int i = 0; i != k + 1; ++i) { facet = {}; @@ -175,7 +170,6 @@ class Witness_complex { } // endfor if (sc.find(facet) == sc.null_simplex()) return false; - // std::cout << "++++ finished loop safely\n"; } // endfor return true; } @@ -206,12 +200,12 @@ class Witness_complex { bool is_witnessed = false; typeVectorVertex simplex; int nbV = 0; // number of verticed in the simplex - for (int v : sc.simplex_vertex_range(sh)) + for (Vertex_handle v : sc.simplex_vertex_range(sh)) simplex.push_back(v); nbV = simplex.size(); for (typeVectorVertex w : knn) { bool has_vertices = true; - for (int v : simplex) + for (Vertex_handle v : simplex) if (std::find(w.begin(), w.begin() + nbV, v) == w.begin() + nbV) { has_vertices = false; // break; diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp index 7d44b90c..03df78ee 100644 --- a/src/Witness_complex/test/simple_witness_complex.cpp +++ b/src/Witness_complex/test/simple_witness_complex.cpp @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(simple_witness_complex) { knn.push_back({5, 0, 1, 3, 6, 2, 4}); knn.push_back({5, 6, 1, 0, 2, 3, 4}); knn.push_back({1, 6, 0, 5, 2, 3, 4}); - WitnessComplex witnessComplex(knn, complex, 7, 7); + WitnessComplex witnessComplex(knn, 7, 7, complex); BOOST_CHECK(witnessComplex.is_witness_complex(knn, false)); } diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp index cb1639e1..bd3df604 100644 --- a/src/Witness_complex/test/witness_complex_points.cpp +++ b/src/Witness_complex/test/witness_complex_points.cpp @@ -52,13 +52,13 @@ BOOST_AUTO_TEST_CASE(witness_complex_points) { Simplex_tree complex1; Gudhi::witness_complex::landmark_choice_by_random_point(points, 100, knn); assert(!knn.empty()); - WitnessComplex witnessComplex1(knn, complex1, 100, 3); + WitnessComplex witnessComplex1(knn, 100, 3, complex1); BOOST_CHECK(witnessComplex1.is_witness_complex(knn, b_print_output)); // Second test: furthest choice knn.clear(); Simplex_tree complex2; Gudhi::witness_complex::landmark_choice_by_furthest_point(points, 100, knn); - WitnessComplex witnessComplex2(knn, complex2, 100, 3); + WitnessComplex witnessComplex2(knn, 100, 3, complex2); BOOST_CHECK(witnessComplex2.is_witness_complex(knn, b_print_output)); } -- cgit v1.2.3 From 6496035f0c8232469bf652c1047eeb66645c1bd6 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 11 Feb 2016 16:07:37 +0000 Subject: Changed concept's name to CamelCase git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1018 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ddc6e2d57b2dd547407e42da44868d1d0658e57c --- src/Witness_complex/concept/Simplicial_complex.h | 2 +- src/Witness_complex/include/gudhi/Witness_complex.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/concept/Simplicial_complex.h b/src/Witness_complex/concept/Simplicial_complex.h index 9e9f2ff8..74d60388 100644 --- a/src/Witness_complex/concept/Simplicial_complex.h +++ b/src/Witness_complex/concept/Simplicial_complex.h @@ -31,7 +31,7 @@ namespace witness_complex { * for a type to implement a simplicial complex, * used for example to build a 'Witness_complex'. */ -struct Simplicial_complex { +struct SimplicialComplex { /** Handle to specify a simplex. */ typedef unspecified Simplex_handle; /** Handle to specify a vertex. Must be a non-negative integer. */ diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 3e14a623..455e008a 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -52,7 +52,7 @@ namespace witness_complex { \brief Constructs the witness complex for the given set of witnesses and landmarks. \ingroup witness_complex */ -template< class Simplicial_complex> +template< class SimplicialComplex> class Witness_complex { private: struct Active_witness { @@ -81,7 +81,7 @@ class Witness_complex { private: int nbL; // Number of landmarks - Simplicial_complex& sc; // Simplicial complex + SimplicialComplex& sc; // Simplicial complex public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -110,7 +110,7 @@ class Witness_complex { Witness_complex(KNearestNeighbors const & knn, int nbL_, int dim, - Simplicial_complex & sc_) : nbL(nbL_), sc(sc_) { + SimplicialComplex & sc_) : nbL(nbL_), sc(sc_) { // Construction of the active witness list int nbW = knn.size(); typeVectorVertex vv; -- cgit v1.2.3 From c9eb5f3526459162fdc241560802b8fa0c5bf6d6 Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 11 Feb 2016 16:08:34 +0000 Subject: now it compiles... git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1019 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5b4cd7b1f767b47190a9bf2f6dd7eab2682df6e8 --- src/Witness_complex/include/gudhi/Witness_complex.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 455e008a..50058740 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -65,8 +65,8 @@ class Witness_complex { }; private: - typedef typename Simplicial_complex::Simplex_handle Simplex_handle; - typedef typename Simplicial_complex::Vertex_handle Vertex_handle; + typedef typename SimplicialComplex::Simplex_handle Simplex_handle; + typedef typename SimplicialComplex::Vertex_handle Vertex_handle; typedef std::vector< double > Point_t; typedef std::vector< Point_t > Point_Vector; -- cgit v1.2.3 From 897f3b6016dac740c5b990c72e2e0ba30cf29963 Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 16 Feb 2016 13:53:04 +0000 Subject: Moved the doc file + changed notations in Witness_complex.h git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1023 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 1053d8ac2f833be8086c81b50dbb34c18de07ebb --- src/Witness_complex/doc/Witness_complex_doc.h | 38 ++++++++++++++++++++++ .../include/gudhi/Witness_complex.h | 20 ++++++------ .../include/gudhi/Witness_complex_doc.h | 38 ---------------------- 3 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 src/Witness_complex/doc/Witness_complex_doc.h delete mode 100644 src/Witness_complex/include/gudhi/Witness_complex_doc.h (limited to 'src') diff --git a/src/Witness_complex/doc/Witness_complex_doc.h b/src/Witness_complex/doc/Witness_complex_doc.h new file mode 100644 index 00000000..e9f78170 --- /dev/null +++ b/src/Witness_complex/doc/Witness_complex_doc.h @@ -0,0 +1,38 @@ +#ifndef WITNESS_COMPLEX_DOC_H_ +#define WITNESS_COMPLEX_DOC_H_ + +/** + \defgroup witness_complex Witness complex + + \author Siargey Kachanovich + + \section Definitions + + Witness complex \f$ Wit(W,L) \f$ is a simplicial complex defined on two sets of points in \f$\mathbb{R}^D\f$: + + \li \f$W\f$ set of **witnesses** and + \li \f$L \subseteq W\f$ set of **landmarks**. + + The simplices are based on landmarks + and a simplex belongs to the witness complex if and only if it is witnessed, that is: + + \f$ \sigma \subset L \f$ is witnessed if there exists a point \f$w \in W\f$ such that + w is closer to the vertices of \f$ \sigma \f$ than other points in \f$ L \f$ and all of its faces are witnessed as well. + + \section Implementation + + The principal class of this module is Gudhi::Witness_complex. + + In both cases, the constructor for this class takes a {witness}x{closest_landmarks} table, where each row represents a witness and consists of landmarks sorted by distance to this witness. + This table can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. + + *\image html "bench_Cy8.png" "Running time as function on number of landmarks" width=10cm + *\image html "bench_sphere.png" "Running time as function on number of witnesses for |L|=300" width=10cm + + + \copyright GNU General Public License v3. + + + */ + +#endif // WITNESS_COMPLEX_DOC_H_ diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 50058740..dab80be6 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -80,8 +80,8 @@ class Witness_complex { typedef std::list< Vertex_handle > ActiveWitnessList; private: - int nbL; // Number of landmarks - SimplicialComplex& sc; // Simplicial complex + int nbL_; // Number of landmarks + SimplicialComplex& sc_; // Simplicial complex public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -108,9 +108,9 @@ class Witness_complex { */ template< typename KNearestNeighbors > Witness_complex(KNearestNeighbors const & knn, - int nbL_, + int nbL, int dim, - SimplicialComplex & sc_) : nbL(nbL_), sc(sc_) { + SimplicialComplex & sc) : nbL_(nbL), sc_(sc) { // Construction of the active witness list int nbW = knn.size(); typeVectorVertex vv; @@ -119,12 +119,12 @@ class Witness_complex { * it will diminuish in the course of iterations */ ActiveWitnessList active_w; // = new ActiveWitnessList(); - for (Vertex_handle i = 0; i != nbL; ++i) { + for (Vertex_handle i = 0; i != nbL_; ++i) { // initial fill of 0-dimensional simplices // by doing it we don't assume that landmarks are necessarily witnesses themselves anymore counter++; vv = {i}; - sc.insert_simplex(vv); + sc_.insert_simplex(vv); // TODO(SK) Error if not inserted : normally no need here though } int k = 1; /* current dimension in iterative construction */ @@ -139,7 +139,7 @@ class Witness_complex { if (ok) { for (int i = 0; i != k + 1; ++i) simplex_vector.push_back(knn[*it][i]); - sc.insert_simplex(simplex_vector); + sc_.insert_simplex(simplex_vector); // TODO(SK) Error if not inserted : normally no need here though it++; } else { @@ -168,7 +168,7 @@ class Witness_complex { facet.push_back(knn[witness_id][j]); } } // endfor - if (sc.find(facet) == sc.null_simplex()) + if (sc_.find(facet) == sc_.null_simplex()) return false; } // endfor return true; @@ -196,11 +196,11 @@ class Witness_complex { template< class KNearestNeighbors > bool is_witness_complex(KNearestNeighbors const & knn, bool print_output) { // bool final_result = true; - for (Simplex_handle sh : sc.complex_simplex_range()) { + for (Simplex_handle sh : sc_.complex_simplex_range()) { bool is_witnessed = false; typeVectorVertex simplex; int nbV = 0; // number of verticed in the simplex - for (Vertex_handle v : sc.simplex_vertex_range(sh)) + for (Vertex_handle v : sc_.simplex_vertex_range(sh)) simplex.push_back(v); nbV = simplex.size(); for (typeVectorVertex w : knn) { diff --git a/src/Witness_complex/include/gudhi/Witness_complex_doc.h b/src/Witness_complex/include/gudhi/Witness_complex_doc.h deleted file mode 100644 index e9f78170..00000000 --- a/src/Witness_complex/include/gudhi/Witness_complex_doc.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef WITNESS_COMPLEX_DOC_H_ -#define WITNESS_COMPLEX_DOC_H_ - -/** - \defgroup witness_complex Witness complex - - \author Siargey Kachanovich - - \section Definitions - - Witness complex \f$ Wit(W,L) \f$ is a simplicial complex defined on two sets of points in \f$\mathbb{R}^D\f$: - - \li \f$W\f$ set of **witnesses** and - \li \f$L \subseteq W\f$ set of **landmarks**. - - The simplices are based on landmarks - and a simplex belongs to the witness complex if and only if it is witnessed, that is: - - \f$ \sigma \subset L \f$ is witnessed if there exists a point \f$w \in W\f$ such that - w is closer to the vertices of \f$ \sigma \f$ than other points in \f$ L \f$ and all of its faces are witnessed as well. - - \section Implementation - - The principal class of this module is Gudhi::Witness_complex. - - In both cases, the constructor for this class takes a {witness}x{closest_landmarks} table, where each row represents a witness and consists of landmarks sorted by distance to this witness. - This table can be constructed by two additional classes Landmark_choice_by_furthest_point and Landmark_choice_by_random_point also included in the module. - - *\image html "bench_Cy8.png" "Running time as function on number of landmarks" width=10cm - *\image html "bench_sphere.png" "Running time as function on number of witnesses for |L|=300" width=10cm - - - \copyright GNU General Public License v3. - - - */ - -#endif // WITNESS_COMPLEX_DOC_H_ -- cgit v1.2.3 From c5469621436305badbc4c5a64380881b6571f7bc Mon Sep 17 00:00:00 2001 From: skachano Date: Tue, 16 Feb 2016 15:02:50 +0000 Subject: Commented is_witness_complex's documentation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1026 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 912a482e67e92b02a20db1be8b602ff8576632ae --- .../include/gudhi/Landmark_choice_by_furthest_point.h | 1 + src/Witness_complex/include/gudhi/Witness_complex.h | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 47cd888d..2491b319 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -34,6 +34,7 @@ namespace witness_complex { typedef std::vector typeVectorVertex; /** + * \ingroup witness_complex * \brief Landmark choice strategy by iteratively adding the furthest witness from the * current landmark set as the new landmark. * \details It chooses nbL landmarks from a random access range `points` and diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index dab80be6..046343db 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -188,11 +188,11 @@ class Witness_complex { } public: - /** - * \brief Verification if every simplex in the complex is witnessed by witnesses in knn. - * \param print_output =true will print the witnesses for each simplex - * \remark Added for debugging purposes. - */ + // /** + // * \brief Verification if every simplex in the complex is witnessed by witnesses in knn. + // * \param print_output =true will print the witnesses for each simplex + // * \remark Added for debugging purposes. + // */ template< class KNearestNeighbors > bool is_witness_complex(KNearestNeighbors const & knn, bool print_output) { // bool final_result = true; -- cgit v1.2.3 From 67f7ecf8e35b51256304b5120daf2827450b6dcd Mon Sep 17 00:00:00 2001 From: skachano Date: Thu, 18 Feb 2016 13:02:25 +0000 Subject: The rest of changes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1031 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: af29326bd4293697211c20001fc120108a38b3f4 --- .../include/gudhi/Landmark_choice_by_furthest_point.h | 7 ++++++- .../include/gudhi/Landmark_choice_by_random_point.h | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 2491b319..472cc0f7 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -39,6 +39,11 @@ namespace witness_complex { * current landmark set as the new landmark. * \details It chooses nbL landmarks from a random access range `points` and * writes {witness}*{closest landmarks} matrix in `knn`. + * + * The type KNearestNeighbors can be seen as + * Witness_range>, where + * Witness_range and Closest_landmark_range are random access ranges + * */ template Date: Fri, 11 Mar 2016 10:36:42 +0000 Subject: Put the class Witness_complex to private in doc git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1037 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 351b135de4d345830ab7fb796eb69b23063fd494 --- .../example/witness_complex_from_file.cpp | 4 +-- .../example/witness_complex_sphere.cpp | 4 +-- .../include/gudhi/Witness_complex.h | 29 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index 98d1fe9c..a8294bad 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -40,7 +40,7 @@ using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::vector< std::vector > Point_Vector; -typedef Witness_complex< Simplex_tree<> > WitnessComplex; +//typedef Witness_complex< Simplex_tree<> > WitnessComplex; /** * \brief Customized version of read_points @@ -98,7 +98,7 @@ int main(int argc, char * const argv[]) { // Compute witness complex start = clock(); - WitnessComplex(knn, nbL, point_vector[0].size(), simplex_tree); + Gudhi::witness_complex::witness_complex(knn, nbL, point_vector[0].size(), simplex_tree); end = clock(); std::cout << "Witness complex took " << static_cast(end - start) / CLOCKS_PER_SEC << " s. \n"; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index fae80d67..7bbf983a 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -44,8 +44,6 @@ using namespace Gudhi::witness_complex; typedef std::vector< Vertex_handle > typeVectorVertex; -typedef Witness_complex< Simplex_tree<> > WitnessComplex; - /** Write a gnuplot readable file. * Data range is a random access range of pairs (arg, value) */ @@ -85,7 +83,7 @@ int main(int argc, char * const argv[]) { Gudhi::witness_complex::landmark_choice_by_random_point(point_vector, number_of_landmarks, knn); // Compute witness complex - WitnessComplex(knn, number_of_landmarks, point_vector[0].size(), simplex_tree); + Gudhi::witness_complex::witness_complex(knn, number_of_landmarks, point_vector[0].size(), simplex_tree); end = clock(); double time = static_cast(end - start) / CLOCKS_PER_SEC; std::cout << "Witness complex for " << number_of_landmarks << " landmarks took " diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 046343db..524912cf 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -48,6 +48,7 @@ namespace Gudhi { namespace witness_complex { /** + * \private \class Witness_complex \brief Constructs the witness complex for the given set of witnesses and landmarks. \ingroup witness_complex @@ -236,6 +237,34 @@ class Witness_complex { } }; + /** + * \ingroup witness_complex + * \brief Iterative construction of the witness complex. + * \details The witness complex is written in simplicial complex sc_ + * basing on a matrix knn of + * nearest neighbours of the form {witnesses}x{landmarks}. + * + * The type KNearestNeighbors can be seen as + * Witness_range>, where + * Witness_range and Closest_landmark_range are random access ranges. + * + * Procedure takes into account at most (dim+1) + * first landmarks from each landmark range to construct simplices. + * + * Landmarks are supposed to be in [0,nbL_-1] + */ + + + template + void witness_complex(KNearestNeighbors const & knn, + int nbL, + int dim, + SimplicialComplexForWitness & sc) + { + + Witness_complex(knn, nbL, dim, sc); + } + } // namespace witness_complex } // namespace Gudhi -- cgit v1.2.3 From b94ae59cf3441a2aa93824e081baa102abf0c286 Mon Sep 17 00:00:00 2001 From: skachano Date: Fri, 11 Mar 2016 13:33:20 +0000 Subject: concept and documentation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1038 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d96a449cd155761d4ae5c61987046733b864e11e --- src/Witness_complex/concept/Simplicial_complex.h | 87 ---------------------- .../concept/Simplicial_complex_for_witness.h | 87 ++++++++++++++++++++++ .../include/gudhi/Witness_complex.h | 20 ++--- 3 files changed, 97 insertions(+), 97 deletions(-) delete mode 100644 src/Witness_complex/concept/Simplicial_complex.h create mode 100644 src/Witness_complex/concept/Simplicial_complex_for_witness.h (limited to 'src') diff --git a/src/Witness_complex/concept/Simplicial_complex.h b/src/Witness_complex/concept/Simplicial_complex.h deleted file mode 100644 index 74d60388..00000000 --- a/src/Witness_complex/concept/Simplicial_complex.h +++ /dev/null @@ -1,87 +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): Siargey Kachanovich - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Méditerranée (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ -#define CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ - -namespace Gudhi { - -namespace witness_complex { - -/** \brief The concept Simplicial_Complex describes the requirements - * for a type to implement a simplicial complex, - * used for example to build a 'Witness_complex'. - */ -struct SimplicialComplex { - /** Handle to specify a simplex. */ - typedef unspecified Simplex_handle; - /** Handle to specify a vertex. Must be a non-negative integer. */ - typedef unspecified Vertex_handle; - - /** Returns a Simplex_hanlde that is different from all simplex handles - * of the simplices. */ - Simplex_handle null_simplex(); - - /** \brief Iterator over the simplices of the complex, - * in an arbitrary order. - * - * 'value_type' must be 'Simplex_handle'.*/ - typedef unspecified Complex_simplex_range; - - /** - * \brief Returns a range over all the simplices of a - * complex. - */ - Complex_simplex_range complex_simplex_range(); - - /** \brief Iterator over vertices of a simplex. - * - * 'value type' must be 'Vertex_handle'.*/ - typedef unspecified Simplex_vertex_range; - - /** \brief Returns a range over vertices of a given - * simplex. */ - Simplex_vertex_range simplex_vertex_range(Simplex_handle const & simplex); - - /** \brief Return type of an insertion of a simplex - */ - typedef unspecified Insertion_result_type; - - /** \brief Inserts a simplex with vertices from a given range - * 'vertex_range' in the simplicial complex. - * */ - template< typedef Input_vertex_range > - Insertion_result_type insert_simplex(Input_vertex_range const & vertex_range); - - /** \brief Finds a simplex with vertices given by a range - * - * If a simplex exists, its Simplex_handle is returned. - * Otherwise null_simplex() is returned. */ - template< typedef Input_vertex_range > - Simplex_handle find(Input_vertex_range const & vertex_range); -}; - -} // namespace witness_complex - -} // namespace Gudhi - -#endif // CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ diff --git a/src/Witness_complex/concept/Simplicial_complex_for_witness.h b/src/Witness_complex/concept/Simplicial_complex_for_witness.h new file mode 100644 index 00000000..a4cf3c77 --- /dev/null +++ b/src/Witness_complex/concept/Simplicial_complex_for_witness.h @@ -0,0 +1,87 @@ +/* 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) 2014 INRIA Sophia Antipolis-Méditerranée (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ +#define CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ + +namespace Gudhi { + +namespace witness_complex { + +/** \brief The concept Simplicial_Complex describes the requirements + * for a type to implement a simplicial complex, + * used for example to build a 'Witness_complex'. + */ +struct SimplicialComplexForWitness { + /** Handle to specify a simplex. */ + typedef unspecified Simplex_handle; + /** Handle to specify a vertex. Must be a non-negative integer. */ + typedef unspecified Vertex_handle; + + /** Returns a Simplex_hanlde that is different from all simplex handles + * of the simplices. */ + Simplex_handle null_simplex(); + + /** \brief Iterator over the simplices of the complex, + * in an arbitrary order. + * + * 'value_type' must be 'Simplex_handle'.*/ + typedef unspecified Complex_simplex_range; + + /** + * \brief Returns a range over all the simplices of a + * complex. + */ + Complex_simplex_range complex_simplex_range(); + + /** \brief Iterator over vertices of a simplex. + * + * 'value type' must be 'Vertex_handle'.*/ + typedef unspecified Simplex_vertex_range; + + /** \brief Returns a range over vertices of a given + * simplex. */ + Simplex_vertex_range simplex_vertex_range(Simplex_handle const & simplex); + + /** \brief Return type of an insertion of a simplex + */ + typedef unspecified Insertion_result_type; + + /** \brief Inserts a simplex with vertices from a given range + * 'vertex_range' in the simplicial complex. + * */ + template< typedef Input_vertex_range > + Insertion_result_type insert_simplex(Input_vertex_range const & vertex_range); + + /** \brief Finds a simplex with vertices given by a range + * + * If a simplex exists, its Simplex_handle is returned. + * Otherwise null_simplex() is returned. */ + template< typedef Input_vertex_range > + Simplex_handle find(Input_vertex_range const & vertex_range); +}; + +} // namespace witness_complex + +} // namespace Gudhi + +#endif // CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 524912cf..60734efe 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -47,12 +47,12 @@ namespace Gudhi { namespace witness_complex { -/** - * \private - \class Witness_complex - \brief Constructs the witness complex for the given set of witnesses and landmarks. - \ingroup witness_complex - */ +// /* +// * \private +// \class Witness_complex +// \brief Constructs the witness complex for the given set of witnesses and landmarks. +// \ingroup witness_complex +// */ template< class SimplicialComplex> class Witness_complex { private: @@ -86,14 +86,14 @@ class Witness_complex { public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /** @name Constructor + /* @name Constructor */ //@{ // Witness_range> - /** + /* * \brief Iterative construction of the witness complex. * \details The witness complex is written in sc_ basing on a matrix knn of * nearest neighbours of the form {witnesses}x{landmarks}. @@ -154,7 +154,7 @@ class Witness_complex { //@} private: - /** \brief Check if the facets of the k-dimensional simplex witnessed + /* \brief Check if the facets of the k-dimensional simplex witnessed * by witness witness_id are already in the complex. * inserted_vertex is the handle of the (k+1)-th vertex witnessed by witness_id */ @@ -189,7 +189,7 @@ class Witness_complex { } public: - // /** + // /* // * \brief Verification if every simplex in the complex is witnessed by witnesses in knn. // * \param print_output =true will print the witnesses for each simplex // * \remark Added for debugging purposes. -- cgit v1.2.3 From 4b19b4553e909c46b1710fde0bec2b5702e1cb73 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 18 Mar 2016 15:07:43 +0000 Subject: Fix cpplint/cppcheck issues git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/witness@1054 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9f850be55ab0565a2004ba23f6a5098aa227a92a --- .../concept/Simplicial_complex_for_witness.h | 6 +++--- .../example/witness_complex_from_file.cpp | 7 +------ src/Witness_complex/example/witness_complex_sphere.cpp | 7 +------ .../include/gudhi/Landmark_choice_by_furthest_point.h | 2 +- .../include/gudhi/Landmark_choice_by_random_point.h | 2 +- src/Witness_complex/include/gudhi/Witness_complex.h | 16 +++++----------- 6 files changed, 12 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/concept/Simplicial_complex_for_witness.h b/src/Witness_complex/concept/Simplicial_complex_for_witness.h index a4cf3c77..caaf0db6 100644 --- a/src/Witness_complex/concept/Simplicial_complex_for_witness.h +++ b/src/Witness_complex/concept/Simplicial_complex_for_witness.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ -#define CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ +#ifndef CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_FOR_WITNESS_H_ +#define CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_FOR_WITNESS_H_ namespace Gudhi { @@ -84,4 +84,4 @@ struct SimplicialComplexForWitness { } // namespace Gudhi -#endif // CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_H_ +#endif // CONCEPT_WITNESS_COMPLEX_SIMPLICIAL_COMPLEX_FOR_WITNESS_H_ diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp index a8294bad..53207ad2 100644 --- a/src/Witness_complex/example/witness_complex_from_file.cpp +++ b/src/Witness_complex/example/witness_complex_from_file.cpp @@ -34,14 +34,9 @@ #include #include -using namespace Gudhi; -using namespace Gudhi::witness_complex; - typedef std::vector< Vertex_handle > typeVectorVertex; typedef std::vector< std::vector > Point_Vector; -//typedef Witness_complex< Simplex_tree<> > WitnessComplex; - /** * \brief Customized version of read_points * which takes into account a possible nbP first line @@ -80,7 +75,7 @@ int main(int argc, char * const argv[]) { clock_t start, end; // Construct the Simplex Tree - Simplex_tree<> simplex_tree; + Gudhi::Simplex_tree<> simplex_tree; // Read the point file Point_Vector point_vector; diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp index 7bbf983a..b26c9f36 100644 --- a/src/Witness_complex/example/witness_complex_sphere.cpp +++ b/src/Witness_complex/example/witness_complex_sphere.cpp @@ -39,11 +39,6 @@ #include "generators.h" -using namespace Gudhi; -using namespace Gudhi::witness_complex; - -typedef std::vector< Vertex_handle > typeVectorVertex; - /** Write a gnuplot readable file. * Data range is a random access range of pairs (arg, value) */ @@ -66,7 +61,7 @@ int main(int argc, char * const argv[]) { clock_t start, end; // Construct the Simplex Tree - Simplex_tree<> simplex_tree; + Gudhi::Simplex_tree<> simplex_tree; std::vector< std::pair > l_time; diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 472cc0f7..86d8ac61 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -31,7 +31,7 @@ namespace Gudhi { namespace witness_complex { - typedef std::vector typeVectorVertex; + typedef std::vector typeVectorVertex; /** * \ingroup witness_complex diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index 7da74066..a73c04ac 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -68,7 +68,7 @@ namespace witness_complex { typedef bool (*comp)(dist_i, dist_i); knn = KNearestNeighbours(nbP); for (int points_i = 0; points_i < nbP; points_i++) { - std::priority_queue, comp> l_heap([&](dist_i j1, dist_i j2) { + std::priority_queue, comp> l_heap([](dist_i j1, dist_i j2) { return j1.first > j2.first; }); std::set::iterator landmarks_it; diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 60734efe..52f374f3 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -142,7 +142,7 @@ class Witness_complex { simplex_vector.push_back(knn[*it][i]); sc_.insert_simplex(simplex_vector); // TODO(SK) Error if not inserted : normally no need here though - it++; + ++it; } else { active_w.erase(it++); // First increase the iterator and then erase the previous element } @@ -196,7 +196,6 @@ class Witness_complex { // */ template< class KNearestNeighbors > bool is_witness_complex(KNearestNeighbors const & knn, bool print_output) { - // bool final_result = true; for (Simplex_handle sh : sc_.complex_simplex_range()) { bool is_witnessed = false; typeVectorVertex simplex; @@ -209,7 +208,6 @@ class Witness_complex { for (Vertex_handle v : simplex) if (std::find(w.begin(), w.begin() + nbV, v) == w.begin() + nbV) { has_vertices = false; - // break; } if (has_vertices) { is_witnessed = true; @@ -244,27 +242,23 @@ class Witness_complex { * basing on a matrix knn of * nearest neighbours of the form {witnesses}x{landmarks}. * - * The type KNearestNeighbors can be seen as + * The type KNearestNeighbors can be seen as * Witness_range>, where * Witness_range and Closest_landmark_range are random access ranges. * - * Procedure takes into account at most (dim+1) + * Procedure takes into account at most (dim+1) * first landmarks from each landmark range to construct simplices. * * Landmarks are supposed to be in [0,nbL_-1] */ - - template void witness_complex(KNearestNeighbors const & knn, int nbL, int dim, - SimplicialComplexForWitness & sc) - { - + SimplicialComplexForWitness & sc) { Witness_complex(knn, nbL, dim, sc); } - + } // namespace witness_complex } // namespace Gudhi -- cgit v1.2.3 From c19dafdee66ca80c5bf5e71129d9cca9b9243c92 Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 20 Mar 2016 13:04:38 +0000 Subject: Let the witness code match its doc better. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@1057 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 99dc557a03f1ea85730ce286b80e384257ab2a77 --- .../include/gudhi/Landmark_choice_by_furthest_point.h | 14 +++++++++----- .../include/gudhi/Landmark_choice_by_random_point.h | 7 +++++-- src/Witness_complex/include/gudhi/Witness_complex.h | 5 ++--- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h index 86d8ac61..df93155b 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -23,7 +23,10 @@ #ifndef LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ #define LANDMARK_CHOICE_BY_FURTHEST_POINT_H_ +#include + #include // for numeric_limits<> +#include #include // for sort #include @@ -51,7 +54,7 @@ namespace witness_complex { void landmark_choice_by_furthest_point(Point_random_access_range const &points, int nbL, KNearestNeighbours &knn) { - int nb_points = points.end() - points.begin(); + int nb_points = boost::size(points); assert(nb_points >= nbL); // distance matrix witness x landmarks std::vector> wit_land_dist(nb_points, std::vector()); @@ -65,6 +68,7 @@ namespace witness_complex { std::vector< double > dist_to_L(nb_points, infty); // vector of current distances to L from points // TODO(SK) Consider using rand_r(...) instead of rand(...) for improved thread safety + // or better yet std::uniform_int_distribution int rand_int = rand() % nb_points; int curr_max_w = rand_int; // For testing purposes a pseudo-random number is used here @@ -73,7 +77,7 @@ namespace witness_complex { chosen_landmarks.push_back(curr_max_w); unsigned i = 0; for (auto& p : points) { - double curr_dist = euclidean_distance(p, *(points.begin() + chosen_landmarks[current_number_of_landmarks])); + double curr_dist = euclidean_distance(p, *(std::begin(points) + chosen_landmarks[current_number_of_landmarks])); wit_land_dist[i].push_back(curr_dist); knn[i].push_back(current_number_of_landmarks); if (curr_dist < dist_to_L[i]) @@ -87,9 +91,9 @@ namespace witness_complex { curr_max_w = i; } } - for (unsigned i = 0; i < nb_points; ++i) - std::sort(knn[i].begin(), - knn[i].end(), + for (int i = 0; i < nb_points; ++i) + std::sort(std::begin(knn[i]), + std::end(knn[i]), [&wit_land_dist, i](int a, int b) { return wit_land_dist[i][a] < wit_land_dist[i][b]; }); } diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h index a73c04ac..ebf6aad1 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -23,8 +23,11 @@ #ifndef LANDMARK_CHOICE_BY_RANDOM_POINT_H_ #define LANDMARK_CHOICE_BY_RANDOM_POINT_H_ +#include + #include // for priority_queue<> #include // for pair<> +#include #include #include @@ -50,7 +53,7 @@ namespace witness_complex { void landmark_choice_by_random_point(Point_random_access_range const &points, int nbL, KNearestNeighbours &knn) { - int nbP = points.end() - points.begin(); + int nbP = boost::size(points); assert(nbP >= nbL); std::set landmarks; int current_number_of_landmarks = 0; // counter for landmarks @@ -63,7 +66,7 @@ namespace witness_complex { landmarks.insert(chosen_landmark); } - int dim = points.begin()->size(); + int dim = boost::size(*std::begin(points)); typedef std::pair dist_i; typedef bool (*comp)(dist_i, dist_i); knn = KNearestNeighbours(nbP); diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h index 52f374f3..489cdf11 100644 --- a/src/Witness_complex/include/gudhi/Witness_complex.h +++ b/src/Witness_complex/include/gudhi/Witness_complex.h @@ -28,8 +28,7 @@ #include #include -#include -#include +#include #include @@ -113,7 +112,7 @@ class Witness_complex { int dim, SimplicialComplex & sc) : nbL_(nbL), sc_(sc) { // Construction of the active witness list - int nbW = knn.size(); + int nbW = boost::size(knn); typeVectorVertex vv; int counter = 0; /* The list of still useful witnesses -- cgit v1.2.3 From 2e66c57e9290fd1ac0304dbd8050bb57ead4b683 Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 20 Mar 2016 13:22:02 +0000 Subject: Clarify some details in the concept FilteredComplex. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@1058 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 825978488684e4dcf5b4fc491e6c4467332dbd20 --- src/Persistent_cohomology/concept/FilteredComplex.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Persistent_cohomology/concept/FilteredComplex.h b/src/Persistent_cohomology/concept/FilteredComplex.h index e124d524..e47babe4 100644 --- a/src/Persistent_cohomology/concept/FilteredComplex.h +++ b/src/Persistent_cohomology/concept/FilteredComplex.h @@ -43,7 +43,7 @@ struct FilteredComplex * is model of IndexingTag. */ typedef unspecified Indexing_tag; -/** Returns a Simplex_hanlde that is different from all simplex handles +/** Returns a Simplex_handle that is different from all simplex handles * of the simplices. */ Simplex_handle null_simplex(); /** \brief Returns the number of simplices in the complex. @@ -61,12 +61,13 @@ struct FilteredComplex /** \brief Returns a key that is different from the keys associated * to the simplices. */ Simplex_key null_key (); -/** \brief Returns the key associated to a simplex. */ +/** \brief Returns the key associated to a simplex. + * + * This is never called on null_simplex(). */ Simplex_key key ( Simplex_handle sh ); -/** \brief Returns the simplex associated to a key. - * - * If key is different from null_key(), returns the simplex that - * has index idx in the filtration. */ +/** \brief Returns the simplex that has index idx in the filtration. + * + * This is never called on null_key(). */ Simplex_handle simplex ( Simplex_key idx ); /** \brief Assign a key to a simplex. */ void assign_key(Simplex_handle sh, Simplex_key key); -- cgit v1.2.3 From 245a316b04bbf0883f17cc5116fb8f26251aabd4 Mon Sep 17 00:00:00 2001 From: glisse Date: Sun, 20 Mar 2016 18:22:24 +0000 Subject: Quiet a signed/unsigned comparison warning. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@1060 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e7640912b59f8bb7357316e4a5cf3d75898dca21 --- src/Simplex_tree/include/gudhi/Simplex_tree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h index 096270ee..8a1a1344 100644 --- a/src/Simplex_tree/include/gudhi/Simplex_tree.h +++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h @@ -576,7 +576,7 @@ class Simplex_tree { bool contiguous_vertices() const { if (root_.members_.empty()) return true; if (root_.members_.begin()->first != 0) return false; - if (std::prev(root_.members_.end())->first != root_.members_.size()-1) return false; + if (std::prev(root_.members_.end())->first != static_cast(root_.members_.size() - 1)) return false; return true; } -- cgit v1.2.3