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 --- .../include/gudhi/Witness_complex.h | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/Witness_complex/include/gudhi/Witness_complex.h (limited to 'src/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/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 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/Witness_complex') 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 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/Witness_complex') 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 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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/Witness_complex') 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