From 62937147e40a7d2da7aa7a7a604808feeccaa75e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Sep 2015 14:57:29 +0000 Subject: Add bitmap cubical complex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@794 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 50d9b8eb80e0fe99f871afa5bdbb853add97e25e --- .../example/Bitmap_cubical_complex.cpp | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp new file mode 100644 index 00000000..c0dbaf36 --- /dev/null +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -0,0 +1,69 @@ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//for persistence algorithm +#include "gudhi/reader_utils.h" +#include "gudhi/Bitmap_cubical_complex.h" +#include "gudhi/Persistent_cohomology.h" + +#include + +using namespace Gudhi; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include + +using namespace std; + +int main(int argc, char** argv) { + cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbed in \ +the first line is a dimension D of a cubical complex. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ +of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ +lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + + int p = 2; + double min_persistence = 0; + + if (argc != 2) { + cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style cubical complex at the input. The program will now terminate.\n"; + return 1; + } + + Bitmap_cubical_complex b(argv[1]); + + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + pcoh.init_coefficients(p); //initilizes the coefficient field for homology + pcoh.compute_persistent_cohomology(min_persistence); + + + stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out((char*) ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} -- cgit v1.2.3 From dd2a15d1a8d2607848527513210330baebce9e8e Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 25 Sep 2015 16:07:20 +0000 Subject: cpplint fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@795 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 94efebf169656da3179640ce9c02e8416cc75a18 --- .../example/Bitmap_cubical_complex.cpp | 30 ++- .../example/Random_bitmap_cubical_complex.cpp | 28 +- .../include/gudhi/Bitmap_cubical_complex.h | 294 +++++++++++---------- .../include/gudhi/Bitmap_cubical_complex_base.h | 144 +++++----- src/Bitmap_cubical_complex/include/gudhi/counter.h | 23 +- 5 files changed, 277 insertions(+), 242 deletions(-) (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index c0dbaf36..37c16618 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -20,33 +20,35 @@ * along with this program. If not, see . */ -//for persistence algorithm -#include "gudhi/reader_utils.h" -#include "gudhi/Bitmap_cubical_complex.h" -#include "gudhi/Persistent_cohomology.h" +// for persistence algorithm +#include +#include +#include #include -using namespace Gudhi; -using namespace Gudhi::persistent_cohomology; - -//standard stuff +// standard stuff #include #include +using namespace Gudhi; +using namespace Gudhi::persistent_cohomology; using namespace std; int main(int argc, char** argv) { - cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbed in \ -the first line is a dimension D of a cubical complex. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ -of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ -lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes " + "provided in text files in Perseus style (the only numbed in the first line is a dimension D of a cubical " + "complex. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N " + "denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of " + "top dimensional cells. We assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or " + "CubicalTwoSphere.txt for example." << endl; int p = 2; double min_persistence = 0; if (argc != 2) { - cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style cubical complex at the input. The program will now terminate.\n"; + cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style cubical complex at the " + "input. The program will now terminate.\n"; return 1; } @@ -55,7 +57,7 @@ lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for exam // Compute the persistence diagram of the complex persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); - pcoh.init_coefficients(p); //initilizes the coefficient field for homology + pcoh.init_coefficients(p); // initializes the coefficient field for homology pcoh.compute_persistent_cohomology(min_persistence); diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp index de9d96e0..ac7557ce 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -21,31 +21,31 @@ */ -//for persistence algorithm -#include "gudhi/reader_utils.h" -#include "gudhi/Bitmap_cubical_complex.h" -#include "gudhi/Persistent_cohomology.h" +// for persistence algorithm +#include +#include +#include #include -using namespace Gudhi; -using namespace Gudhi::persistent_cohomology; - -//standard stuff +// standard stuff #include #include #include #include #include +using namespace Gudhi; +using namespace Gudhi::persistent_cohomology; using namespace std; int main(int argc, char** argv) { srand(time(0)); - cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes. \ -The first parameter of the program is the dimension D of the cubical complex. The next D parameters are number of top dimensional cubes in each dimension of the cubical complex.\ -The program will create random cubical complex of that sizes and compute persistent homology of it." << endl; + cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes. " + "The first parameter of the program is the dimension D of the cubical complex. The next D parameters are number " + "of top dimensional cubes in each dimension of the cubical complex. The program will create random cubical " + "complex of that sizes and compute persistent homology of it." << endl; int p = 2; double min_persistence = 0; @@ -64,17 +64,13 @@ The program will create random cubical complex of that sizes and compute persist data.push_back(rand() / (double) RAND_MAX); } - - Bitmap_cubical_complex b(sizes, data); - // Compute the persistence diagram of the complex persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); - pcoh.init_coefficients(p); //initilizes the coefficient field for homology + pcoh.init_coefficients(p); // initializes the coefficient field for homology pcoh.compute_persistent_cohomology(min_persistence); - stringstream ss; ss << "randomComplex_persistence"; std::ofstream out((char*) ss.str().c_str()); diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index 61ae8105..2f8cb0a3 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -23,38 +23,41 @@ #ifndef BITMAP_CUBICAL_COMPLEX_H_ #define BITMAP_CUBICAL_COMPLEX_H_ -#include - #include -//global variable, was used just for debugging. +#include +#include // for pair +#include // for sort +#include // for vector + +// global variable, was used just for debugging. bool globalDbg = false; template class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { public: - //*********************************************************************************************************************************// - //Typedefs and typenames - //*********************************************************************************************************************************// + //******************************************************************************************************************// + // Typedefs and typenames + //******************************************************************************************************************// friend class Simplex_handle; typedef size_t Simplex_key; typedef T Filtration_value; - //*********************************************************************************************************************************// - //Simplex handle class - //*********************************************************************************************************************************// + //******************************************************************************************************************// + // Simplex handle class + //******************************************************************************************************************// /** - * Handle of a cell, required for compatibility with the function to compute persistence in Gudhi. Elements of this class are: the pointer to the bitmap B in which the considered cell is - * together with a position of this cell in B. Given this data, one can get all the information about the considered cell. + * Handle of a cell, required for compatibility with the function to compute persistence in Gudhi. Elements of this + * class are: the pointer to the bitmap B in which the considered cell is together with a position of this cell in B. + * Given this data, one can get all the information about the considered cell. **/ class Simplex_handle { public: - Simplex_handle() { if (globalDbg) { - cerr << "Simplex_handle()\n"; + std::cerr << "Simplex_handle()\n"; } this->b = 0; this->position = 0; @@ -62,7 +65,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Simplex_handle(Bitmap_cubical_complex* b) { if (globalDbg) { - cerr << "Simplex_handle(Bitmap_cubical_complex* b)\n"; + std::cerr << "Simplex_handle(Bitmap_cubical_complex* b)\n"; } this->b = b; this->position = 0; @@ -70,14 +73,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Simplex_handle(const Simplex_handle& org) : b(org.b) { if (globalDbg) { - cerr << "Simplex_handle( const Simplex_handle& org )\n"; + std::cerr << "Simplex_handle( const Simplex_handle& org )\n"; } this->position = org.position; } Simplex_handle& operator=(const Simplex_handle& rhs) { if (globalDbg) { - cerr << "Simplex_handle operator = \n"; + std::cerr << "Simplex_handle operator = \n"; } this->position = rhs.position; this->b = rhs.b; @@ -86,8 +89,8 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Simplex_handle(Bitmap_cubical_complex* b, Simplex_key position) { if (globalDbg) { - cerr << "Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position)\n"; - cerr << "Position : " << position << endl; + std::cerr << "Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position)\n"; + std::cerr << "Position : " << position << std::endl; } this->b = b; this->position = position; @@ -95,27 +98,28 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { friend class Bitmap_cubical_complex; private: Bitmap_cubical_complex* b; - Simplex_key position; //Assumption -- this field always keep the REAL position of simplex in the bitmap, no matter what keys have been. - //to deal with the keys, the class Bitmap_cubical_complex have extra vectors: keyAssociatedToSimplex and simplexAssociatedToKey - //that allow to move between actual cell and the key assigned to it. + Simplex_key position; + // Assumption -- this field always keep the REAL position of simplex in the bitmap, no matter what keys have been. + // to deal with the keys, the class Bitmap_cubical_complex have extra vectors: keyAssociatedToSimplex and + // simplexAssociatedToKey that allow to move between actual cell and the key assigned to it. }; - //*********************************************************************************************************************************// - //Constructors - //*********************************************************************************************************************************// - //Over here we need to definie various input types. I am proposing the following ones: - //Perseus style - //H5 files? TODO - //binary files with little endiangs / big endians? TODO - //constructor from a vector of elements of a type T. TODO + //******************************************************************************************************************// + // Constructors + //******************************************************************************************************************// + // Over here we need to definie various input types. I am proposing the following ones: + // Perseus style + // TODO(Pawel Dlotko): H5 files? + // TODO(Pawel Dlotko): binary files with little endiangs / big endians? + // TODO(Pawel Dlotko): constructor from a vector of elements of a type T. /** * Constructor form a Perseus-style file. **/ Bitmap_cubical_complex(char* perseusStyleFile) : Bitmap_cubical_complex_base(perseusStyleFile) { if (globalDbg) { - cerr << "Bitmap_cubical_complex( char* perseusStyleFile )\n"; + std::cerr << "Bitmap_cubical_complex( char* perseusStyleFile )\n"; } std::vector< size_t > keyAssociatedToSimplex(this->totalNumberOfCells + 1); std::vector< size_t > simplexAssociatedToKey(this->totalNumberOfCells + 1); @@ -125,16 +129,17 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { } this->keyAssociatedToSimplex = keyAssociatedToSimplex; this->simplexAssociatedToKey = simplexAssociatedToKey; - //we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change some elements of the bitmap, then this procedure need - //to be called again. + // we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change + // some elements of the bitmap, then this procedure need to be called again. this->initializeElementsOrderedAccordingToFiltration(); } /** - * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells in the following directions and vector of element of a type T - * with filtration on top dimensional cells. + * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells in the + * following directions and vector of element of a type T with filtration on top dimensional cells. **/ - Bitmap_cubical_complex(std::vector dimensions, std::vector topDimensionalCells) : Bitmap_cubical_complex_base(dimensions, topDimensionalCells) { + Bitmap_cubical_complex(std::vector dimensions, std::vector topDimensionalCells) + : Bitmap_cubical_complex_base(dimensions, topDimensionalCells) { std::vector< size_t > keyAssociatedToSimplex(this->totalNumberOfCells + 1); std::vector< size_t > simplexAssociatedToKey(this->totalNumberOfCells + 1); @@ -143,14 +148,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { } this->keyAssociatedToSimplex = keyAssociatedToSimplex; this->simplexAssociatedToKey = simplexAssociatedToKey; - //we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change some elements of the bitmap, then this procedure need - //to be called again. + // we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change + // some elements of the bitmap, then this procedure need to be called again. this->initializeElementsOrderedAccordingToFiltration(); } - //*********************************************************************************************************************************// - //Other 'easy' functions - //*********************************************************************************************************************************// + //******************************************************************************************************************// + // Other 'easy' functions + //******************************************************************************************************************// /** * Returns number of all cubes in the complex. @@ -178,7 +183,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ size_t dimension(const Simplex_handle& sh) { if (globalDbg) { - cerr << "int dimension(const Simplex_handle& sh)\n"; + std::cerr << "int dimension(const Simplex_handle& sh)\n"; } if (sh.position != this->data.size()) return sh.b->get_dimension_of_a_cell(sh.position); return std::numeric_limits::max(); @@ -189,9 +194,9 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ T filtration(const Simplex_handle& sh) { if (globalDbg) { - cerr << "T filtration(const Simplex_handle& sh)\n"; + std::cerr << "T filtration(const Simplex_handle& sh)\n"; } - //Returns the filtration value of a simplex. + // Returns the filtration value of a simplex. if (sh.position != this->data.size()) return sh.b->data[ sh.position ]; return INT_MAX; } @@ -201,7 +206,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ Simplex_key null_key() { if (globalDbg) { - cerr << "Simplex_key null_key()\n"; + std::cerr << "Simplex_key null_key()\n"; } return this->data.size(); } @@ -211,7 +216,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ Simplex_key key(const Simplex_handle& sh) { if (globalDbg) { - cerr << "Simplex_key key(const Simplex_handle& sh)\n"; + std::cerr << "Simplex_key key(const Simplex_handle& sh)\n"; } return sh.b->keyAssociatedToSimplex[ sh.position ]; } @@ -221,7 +226,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ Simplex_handle simplex(Simplex_key key) { if (globalDbg) { - cerr << "Simplex_handle simplex(Simplex_key key)\n"; + std::cerr << "Simplex_handle simplex(Simplex_key key)\n"; } return Simplex_handle(this, this->simplexAssociatedToKey[ key ]); } @@ -231,7 +236,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ void assign_key(Simplex_handle& sh, Simplex_key key) { if (globalDbg) { - cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n"; + std::cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n"; } this->keyAssociatedToSimplex[sh.position] = key; this->simplexAssociatedToKey[key] = sh.position; @@ -244,9 +249,9 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { - //*********************************************************************************************************************************// - //Iterators - //*********************************************************************************************************************************// + //******************************************************************************************************************// + // Iterators + //******************************************************************************************************************// /** * Boundary_simplex_iterator class allows iteration on boundary of each cube. @@ -254,13 +259,12 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { class Boundary_simplex_range; class Boundary_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - //Iterator on the simplices belonging to the boundary of a simplex. - //value_type must be 'Simplex_handle'. + // Iterator on the simplices belonging to the boundary of a simplex. + // value_type must be 'Simplex_handle'. public: - Boundary_simplex_iterator(Simplex_handle& sh) : sh(sh) { if (globalDbg) { - cerr << "Boundary_simplex_iterator( Simplex_handle& sh )\n"; + std::cerr << "Boundary_simplex_iterator( Simplex_handle& sh )\n"; } this->position = 0; this->boundaryElements = this->sh.b->get_boundary_of_a_cell(this->sh.position); @@ -268,7 +272,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Boundary_simplex_iterator operator++() { if (globalDbg) { - cerr << "Boundary_simplex_iterator operator++()\n"; + std::cerr << "Boundary_simplex_iterator operator++()\n"; } ++this->position; return *this; @@ -282,16 +286,17 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Boundary_simplex_iterator operator=(const Boundary_simplex_iterator& rhs) { if (globalDbg) { - cerr << "Boundary_simplex_iterator operator =\n"; + std::cerr << "Boundary_simplex_iterator operator =\n"; } this->sh = rhs.sh; this->boundaryElements.clear(); - this->boundaryElementsinsert(this->boundaryElements.end(), rhs.boundaryElements.begin(), rhs.boundaryElements.end()); + this->boundaryElementsinsert(this->boundaryElements.end(), + rhs.boundaryElements.begin(), rhs.boundaryElements.end()); } bool operator==(const Boundary_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator ==\n"; + std::cerr << "bool operator ==\n"; } if (this->position == rhs.position) { if (this->boundaryElements.size() != rhs.boundaryElements.size())return false; @@ -305,14 +310,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { bool operator!=(const Boundary_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator != \n"; + std::cerr << "bool operator != \n"; } return !(*this == rhs); } Simplex_handle operator*() { if (globalDbg) { - cerr << "Simplex_handle operator*\n"; + std::cerr << "Simplex_handle operator*\n"; } return Simplex_handle(this->sh.b, this->boundaryElements[this->position]); } @@ -328,15 +333,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { * Boundary_simplex_range class provides ranges for boundary iterators. **/ class Boundary_simplex_range { - //Range giving access to the simplices in the boundary of a simplex. - //.begin() and .end() return type Boundary_simplex_iterator. + // Range giving access to the simplices in the boundary of a simplex. + // .begin() and .end() return type Boundary_simplex_iterator. public: - - Boundary_simplex_range(const Simplex_handle& sh) : sh(sh) { }; + Boundary_simplex_range(const Simplex_handle& sh) : sh(sh) { } Boundary_simplex_iterator begin() { if (globalDbg) { - cerr << "Boundary_simplex_iterator begin\n"; + std::cerr << "Boundary_simplex_iterator begin\n"; } Boundary_simplex_iterator it(this->sh); return it; @@ -344,12 +348,13 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Boundary_simplex_iterator end() { if (globalDbg) { - cerr << "Boundary_simplex_iterator end()\n"; + std::cerr << "Boundary_simplex_iterator end()\n"; } Boundary_simplex_iterator it(this->sh); it.position = it.boundaryElements.size(); return it; } + private: Simplex_handle sh; }; @@ -363,17 +368,16 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { class Filtration_simplex_range; class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - //Iterator over all simplices of the complex in the order of the indexing scheme. - //'value_type' must be 'Simplex_handle'. + // Iterator over all simplices of the complex in the order of the indexing scheme. + // 'value_type' must be 'Simplex_handle'. public: + Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { } - Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { }; - - Filtration_simplex_iterator() : b(NULL) { }; + Filtration_simplex_iterator() : b(NULL) { } Filtration_simplex_iterator operator++() { if (globalDbg) { - cerr << "Filtration_simplex_iterator operator++\n"; + std::cerr << "Filtration_simplex_iterator operator++\n"; } ++this->position; return (*this); @@ -387,7 +391,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Filtration_simplex_iterator operator=(const Filtration_simplex_iterator& rhs) { if (globalDbg) { - cerr << "Filtration_simplex_iterator operator =\n"; + std::cerr << "Filtration_simplex_iterator operator =\n"; } this->b = rhs.b; this->position = rhs.position; @@ -395,7 +399,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { bool operator==(const Filtration_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n"; + std::cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n"; } if (this->position == rhs.position) { return true; @@ -405,14 +409,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { bool operator!=(const Filtration_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n"; + std::cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n"; } return !(*this == rhs); } Simplex_handle operator*() { if (globalDbg) { - cerr << "Simplex_handle operator*()\n"; + std::cerr << "Simplex_handle operator*()\n"; } return Simplex_handle(this->b, this->b->elementsOrderedAccordingToFiltration[ this->position ]); } @@ -427,22 +431,21 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { * Filtration_simplex_range provides the ranges for Filtration_simplex_iterator. **/ class Filtration_simplex_range { - //Range over the simplices of the complex in the order of the filtration. - //.begin() and .end() return type Filtration_simplex_iterator. + // Range over the simplices of the complex in the order of the filtration. + // .begin() and .end() return type Filtration_simplex_iterator. public: - - Filtration_simplex_range(Bitmap_cubical_complex* b) : b(b) { }; + Filtration_simplex_range(Bitmap_cubical_complex* b) : b(b) { } Filtration_simplex_iterator begin() { if (globalDbg) { - cerr << "Filtration_simplex_iterator begin() \n"; + std::cerr << "Filtration_simplex_iterator begin() \n"; } return Filtration_simplex_iterator(this->b); } Filtration_simplex_iterator end() { if (globalDbg) { - cerr << "Filtration_simplex_iterator end()\n"; + std::cerr << "Filtration_simplex_iterator end()\n"; } Filtration_simplex_iterator it(this->b); it.position = this->b->elementsOrderedAccordingToFiltration.size(); @@ -454,40 +457,44 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { - //*********************************************************************************************************************************// - //Methods to access iterators from the container: + //******************************************************************************************************************// + // Methods to access iterators from the container: /** * boundary_simplex_range creates an object of a Boundary_simplex_range class that provides ranges for the Boundary_simplex_iterator. **/ Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh) { if (globalDbg) { - cerr << "Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh)\n"; + std::cerr << "Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh)\n"; } - //Returns a range giving access to all simplices of the boundary of a simplex, i.e. the set of codimension 1 subsimplices of the Simplex. + // Returns a range giving access to all simplices of the boundary of a simplex, i.e. the set of + // codimension 1 subsimplices of the Simplex. return Boundary_simplex_range(sh); } /** - * filtration_simplex_range creates an object of a Filtration_simplex_range class that provides ranges for the Filtration_simplex_iterator. + * filtration_simplex_range creates an object of a Filtration_simplex_range class that provides ranges for the + * Filtration_simplex_iterator. **/ Filtration_simplex_range filtration_simplex_range() { if (globalDbg) { - cerr << "Filtration_simplex_range filtration_simplex_range()\n"; + std::cerr << "Filtration_simplex_range filtration_simplex_range()\n"; } - //Returns a range over the simplices of the complex in the order of the filtration + // Returns a range over the simplices of the complex in the order of the filtration return Filtration_simplex_range(this); } - //*********************************************************************************************************************************// + //******************************************************************************************************************// - //*********************************************************************************************************************************// - //Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are there. - //TODO -- the file IndexingTag.h in the Gudhi library contains an empty structure, so I understand that this is something that was planned (for simplicial maps?) - //but was never finished. The only idea I have here is to use the same empty structure from IndexingTag.h file, but only if the compiler needs it. If the compiler - //do not need it, then I would rather not add here elements which I do not understand. - //typedef Indexing_tag + //******************************************************************************************************************// + // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are + // there. + // TODO(Pawel Dlotko): The file IndexingTag.h in the Gudhi library contains an empty structure, so I understand that + // this is something that was planned (for simplicial maps?) but was never finished. The only idea I have here is + // to use the same empty structure from IndexingTag.h file, but only if the compiler needs it. If the compiler + // do not need it, then I would rather not add here elements which I do not understand. + // typedef Indexing_tag /** * Function needed for compatibility with Gudhi. Not useful for other purposes. @@ -495,11 +502,13 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { std::pair endpoints(Simplex_handle sh) { std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh.position); if (globalDbg) { - cerr << "std::pair endpoints( Simplex_handle sh )\n"; - cerr << "bdry.size() : " << bdry.size() << endl; + std::cerr << "std::pair endpoints( Simplex_handle sh )\n"; + std::cerr << "bdry.size() : " << bdry.size() << std::endl; } - //this method returns two first elements from the boundary of sh. - if (bdry.size() < 2)throw ("Error in endpoints in Bitmap_cubical_complex class. The cell for which this method was called have less than two elements in the boundary."); + // this method returns two first elements from the boundary of sh. + if (bdry.size() < 2) + throw("Error in endpoints in Bitmap_cubical_complex class. " + "The cell for which this method was called have less than two elements in the boundary."); return std::make_pair(Simplex_handle(this, bdry[0]), Simplex_handle(this, bdry[1])); } @@ -510,30 +519,31 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { class Skeleton_simplex_range; class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - //Iterator over all simplices of the complex in the order of the indexing scheme. - //'value_type' must be 'Simplex_handle'. + // Iterator over all simplices of the complex in the order of the indexing scheme. + // 'value_type' must be 'Simplex_handle'. public: - Skeleton_simplex_iterator(Bitmap_cubical_complex* b, size_t d) : b(b), dimension(d) { if (globalDbg) { - cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n"; + std::cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n"; } - //find the position of the first simplex of a dimension d + // find the position of the first simplex of a dimension d this->position = 0; - while ((this->position != b->data.size()) && (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { + while ((this->position != b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { ++this->position; } - }; + } - Skeleton_simplex_iterator() : b(NULL), dimension(0) { }; + Skeleton_simplex_iterator() : b(NULL), dimension(0) { } Skeleton_simplex_iterator operator++() { if (globalDbg) { - cerr << "Skeleton_simplex_iterator operator++()\n"; + std::cerr << "Skeleton_simplex_iterator operator++()\n"; } - //increment the position as long as you did not get to the next element of the dimension dimension. + // increment the position as long as you did not get to the next element of the dimension dimension. ++this->position; - while ((this->position != this->b->data.size()) && (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { + while ((this->position != this->b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { ++this->position; } return (*this); @@ -547,7 +557,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { Skeleton_simplex_iterator operator=(const Skeleton_simplex_iterator& rhs) { if (globalDbg) { - cerr << "Skeleton_simplex_iterator operator =\n"; + std::cerr << "Skeleton_simplex_iterator operator =\n"; } this->b = rhs.b; this->position = rhs.position; @@ -555,7 +565,7 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { bool operator==(const Skeleton_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator ==\n"; + std::cerr << "bool operator ==\n"; } if (this->position == rhs.position) { return true; @@ -565,14 +575,14 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { bool operator!=(const Skeleton_simplex_iterator& rhs) { if (globalDbg) { - cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n"; + std::cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n"; } return !(*this == rhs); } Simplex_handle operator*() { if (globalDbg) { - cerr << "Simplex_handle operator*() \n"; + std::cerr << "Simplex_handle operator*() \n"; } return Simplex_handle(this->b, this->position); } @@ -588,27 +598,27 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { * Class needed for compatibility with Gudhi. Not useful for other purposes. **/ class Skeleton_simplex_range { - //Range over the simplices of the complex in the order of the filtration. - //.begin() and .end() return type Filtration_simplex_iterator. + // Range over the simplices of the complex in the order of the filtration. + // .begin() and .end() return type Filtration_simplex_iterator. public: - - Skeleton_simplex_range(Bitmap_cubical_complex* b, int dimension) : b(b), dimension(dimension) { }; + Skeleton_simplex_range(Bitmap_cubical_complex* b, int dimension) : b(b), dimension(dimension) { } Skeleton_simplex_iterator begin() { if (globalDbg) { - cerr << "Skeleton_simplex_iterator begin()\n"; + std::cerr << "Skeleton_simplex_iterator begin()\n"; } return Skeleton_simplex_iterator(this->b, this->dimension); } Skeleton_simplex_iterator end() { if (globalDbg) { - cerr << "Skeleton_simplex_iterator end()\n"; + std::cerr << "Skeleton_simplex_iterator end()\n"; } Skeleton_simplex_iterator it(this->b, this->dimension); it.position = this->b->data.size(); return it; } + private: Bitmap_cubical_complex* b; int dimension; @@ -619,22 +629,22 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { **/ Skeleton_simplex_range skeleton_simplex_range(int dimension) { if (globalDbg) { - cerr << "Skeleton_simplex_range skeleton_simplex_range( int dimension )\n"; + std::cerr << "Skeleton_simplex_range skeleton_simplex_range( int dimension )\n"; } return Skeleton_simplex_range(this, dimension); } - //*********************************************************************************************************************************// - //functions used for debugging: + //******************************************************************************************************************// + // functions used for debugging: /** * Function used for debugging purposes. **/ void printKeyAssociatedToSimplex() { for (size_t i = 0; i != this->data.size(); ++i) { - cerr << i << " -> " << this->simplexAssociatedToKey[i] << endl; + std::cerr << i << " -> " << this->simplexAssociatedToKey[i] << std::endl; } } @@ -648,13 +658,17 @@ class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { private: std::vector< size_t > keyAssociatedToSimplex; std::vector< size_t > simplexAssociatedToKey; - std::vector< size_t > elementsOrderedAccordingToFiltration; //needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. -}; //Bitmap_cubical_complex + // needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. + std::vector< size_t > elementsOrderedAccordingToFiltration; +}; template -bool compareElementsForElementsOrderedAccordingToFiltration(const std::pair< size_t, std::pair< T, char > >& f, const std::pair< size_t, std::pair< T, char > >& s) { +bool compareElementsForElementsOrderedAccordingToFiltration(const std::pair< size_t, + std::pair< T, char > >& f, + const std::pair< size_t, + std::pair< T, char > >& s) { if (globalDbg) { - cerr << "ompareElementsForElementsOrderedAccordingToFiltration\n"; + std::cerr << "ompareElementsForElementsOrderedAccordingToFiltration\n"; } if (f.second.first < s.second.first) { return true; @@ -662,14 +676,15 @@ bool compareElementsForElementsOrderedAccordingToFiltration(const std::pair< siz if (f.second.first > s.second.first) { return false; } else { - //in this case f.second.first == s.second.first, and we use dimension to compare: + // in this case f.second.first == s.second.first, and we use dimension to compare: if (f.second.second < s.second.second) { return true; } else { if (f.second.second > s.second.second) { return false; } else { - //in this case, both the filtration value and the dimensions for those cells are the same. Since it may be nice to have a stable sorting procedure, in this case, we compare positions in the bitmap: + // in this case, both the filtration value and the dimensions for those cells are the same. + // Since it may be nice to have a stable sorting procedure, in this case, we compare positions in the bitmap: return ( f.first < s.first); } } @@ -680,21 +695,24 @@ bool compareElementsForElementsOrderedAccordingToFiltration(const std::pair< siz template void Bitmap_cubical_complex::initializeElementsOrderedAccordingToFiltration() { if (globalDbg) { - cerr << "void Bitmap_cubical_complex::initializeElementsOrderedAccordingToFiltration() \n"; + std::cerr << "void Bitmap_cubical_complex::initializeElementsOrderedAccordingToFiltration() \n"; } - //( position , (filtration , dimension) ) + // ( position , (filtration , dimension) ) std::vector< std::pair< size_t, std::pair< T, char > > > dataOfElementsFromBitmap(this->data.size()); for (size_t i = 0; i != this->data.size(); ++i) { - //TODO -- this can be optimized by having a counter here. We do not need to re-compute the dimension for every cell from scratch + // TODO(Pawel Dlotko): This can be optimized by having a counter here. We do not need to re-compute the dimension + // for every cell from scratch dataOfElementsFromBitmap[i] = std::make_pair(i, std::make_pair(this->data[i], this->get_dimension_of_a_cell(i))); } - std::sort(dataOfElementsFromBitmap.begin(), dataOfElementsFromBitmap.end(), compareElementsForElementsOrderedAccordingToFiltration); + std::sort(dataOfElementsFromBitmap.begin(), dataOfElementsFromBitmap.end(), + compareElementsForElementsOrderedAccordingToFiltration); - std::vector< size_t > elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap(this->data.size()); + // Elements of bitmap ordered according to filtration then according to dimension then according to position in bitmap + std::vector< size_t > elements_of_bitmap_ordered(this->data.size()); for (size_t i = 0; i != dataOfElementsFromBitmap.size(); ++i) { - elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap[i] = dataOfElementsFromBitmap[i].first; + elements_of_bitmap_ordered[i] = dataOfElementsFromBitmap[i].first; } - this->elementsOrderedAccordingToFiltration = elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap; + this->elementsOrderedAccordingToFiltration = elements_of_bitmap_ordered; } diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index 26c97872..d9c91832 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -23,20 +23,17 @@ #ifndef BITMAP_CUBICAL_COMPLEX_BASE_H_ #define BITMAP_CUBICAL_COMPLEX_BASE_H_ +#include + #include #include #include -#include #include #include #include #include #include -#include - -using namespace std; - /** * This is a class implementing a basic bitmap data structure to store cubical complexes. It implements only the most basic subroutines. * The idea of the bitmap is the following. Our aim is to have a memory efficient data structure to store d-dimensional cubical complex C being a cubical decomposition @@ -89,7 +86,7 @@ class Bitmap_cubical_complex_base { * cells. The most typical one is by so called lower star filtration. This function is always called by any constructor which takes the top dimensional cells. If you use such a constructor, * then there is no need to call this function. Call it only if you are putting the filtration of the cells by your own (for instance by using topDimensionalCellsIterator). **/ - void impose_lower_star_filtration(); //assume that top dimensional cells are already set. + void impose_lower_star_filtration(); // assume that top dimensional cells are already set. /** * Returns dimension of a complex. @@ -109,9 +106,9 @@ class Bitmap_cubical_complex_base { * Writing to stream operator. **/ template - friend ostream& operator<<(ostream & os_, const Bitmap_cubical_complex_base& b_); + friend std::ostream& operator<<(std::ostream & os_, const Bitmap_cubical_complex_base& b_); - //ITERATORS + // ITERATORS /** * Iterator through all cells in the complex (in order they appear in the structure -- i.e. in lexicographical order). @@ -142,7 +139,6 @@ class Bitmap_cubical_complex_base { **/ class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, double > { public: - Top_dimensional_cells_iterator(Bitmap_cubical_complex_base& b_) : b(b_) { for (size_t i = 0; i != b_.dimension(); ++i) { this->counter.push_back(0); @@ -150,7 +146,7 @@ class Bitmap_cubical_complex_base { } Top_dimensional_cells_iterator operator++() { - //first find first element of the counter that can be increased: + // first find first element of the counter that can be increased: size_t dim = 0; while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1))++dim; @@ -191,7 +187,7 @@ class Bitmap_cubical_complex_base { } T& operator*() { - //given the counter, compute the index in the array and return this element. + // given the counter, compute the index in the array and return this element. unsigned index = 0; for (size_t i = 0; i != this->counter.size(); ++i) { index += (2 * this->counter[i] + 1) * this->b.multipliers[i]; @@ -209,7 +205,7 @@ class Bitmap_cubical_complex_base { void printCounter() { for (size_t i = 0; i != this->counter.size(); ++i) { - cout << this->counter[i] << " "; + std::cout << this->counter[i] << " "; } } friend class Bitmap_cubical_complex_base; @@ -255,10 +251,10 @@ class Bitmap_cubical_complex_base { for (size_t i = 0; i != sizes_.size(); ++i) { this->sizes.push_back(sizes_[i]); this->multipliers.push_back(multiplier); - //multiplier *= 2*(sizes[i]+1)+1; + // multiplier *= 2*(sizes[i]+1)+1; multiplier *= 2 * sizes_[i] + 1; } - //std::reverse( this->sizes.begin() , this->sizes.end() ); + // std::reverse( this->sizes.begin() , this->sizes.end() ); std::vector data(multiplier); std::fill(data.begin(), data.end(), INT_MAX); this->totalNumberOfCells = multiplier; @@ -287,9 +283,11 @@ class Bitmap_cubical_complex_base { }; template -ostream& operator<<(ostream & out_, const Bitmap_cubical_complex_base& b_) { - //for ( typename bitmap::all_cells_const_iterator it = b.all_cells_const_begin() ; it != b.all_cells_const_end() ; ++it ) - for (typename Bitmap_cubical_complex_base::all_cells_const_iterator it = b_.all_cells_const_begin(); it != b_.all_cells_const_end(); ++it) { +std::ostream& operator<<(std::ostream & out_, const Bitmap_cubical_complex_base& b_) { + // for ( typename bitmap::all_cells_const_iterator it = b.all_cells_const_begin() ; + // it != b.all_cells_const_end() ; ++it ) + for (typename Bitmap_cubical_complex_base::all_cells_const_iterator it = b_.all_cells_const_begin(); + it != b_.all_cells_const_end(); ++it) { out_ << *it << " "; } return out_; @@ -301,7 +299,8 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector sizesInFollowingDirections_, std::vector topDimensionalCells_) { +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector sizesInFollowingDirections_, + std::vector topDimensionalCells_) { this->set_up_containers(sizesInFollowingDirections_); size_t numberOfTopDimensionalElements = 1; @@ -309,8 +308,12 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector sizesInFollowingDirections_ , std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from sizesInFollowingDirections vector is different than the size of topDimensionalCells vector." << endl; - throw ("Error in constructor Bitmap_cubical_complex_base( std::vector sizesInFollowingDirections_ , std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from sizesInFollowingDirections vector is different than the size of topDimensionalCells vector."); + std::cerr << "Error in constructor Bitmap_cubical_complex_base( std::vector sizesInFollowingDirections_ , " + "std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from " + "sizesInFollowingDirections vector is different than the size of topDimensionalCells vector." << std::endl; + throw("Error in constructor Bitmap_cubical_complex_base( std::vector sizesInFollowingDirections_ , " + "std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from " + "sizesInFollowingDirections vector is different than the size of topDimensionalCells vector."); } Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); @@ -325,13 +328,13 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(char* perseusStyleFile_) { bool dbg = false; - ifstream inFiltration, inIds; + std::ifstream inFiltration, inIds; inFiltration.open(perseusStyleFile_); unsigned dimensionOfData; inFiltration >> dimensionOfData; if (dbg) { - cerr << "dimensionOfData : " << dimensionOfData << endl; + std::cerr << "dimensionOfData : " << dimensionOfData << std::endl; } std::vector sizes; @@ -341,7 +344,7 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(char* perseusStyleFi sizeInThisDimension = abs(sizeInThisDimension); sizes.push_back(sizeInThisDimension); if (dbg) { - cerr << "sizeInThisDimension : " << sizeInThisDimension << endl; + std::cerr << "sizeInThisDimension : " << sizeInThisDimension << std::endl; } } this->set_up_containers(sizes); @@ -349,12 +352,14 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(char* perseusStyleFi Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); it = this->top_dimensional_cells_begin(); - //TODO -- over here we also need to read id's of cell and put them to bitmapElement structure! + // TODO(Pawel Dlotko): Over here we also need to read id's of cell and put them to bitmapElement structure! while (!inFiltration.eof()) { double filtrationLevel; inFiltration >> filtrationLevel; if (dbg) { - cerr << "Cell of an index : " << it.computeIndexInBitmap() << " and dimension: " << this->get_dimension_of_a_cell(it.computeIndexInBitmap()) << " get the value : " << filtrationLevel << endl; + std::cerr << "Cell of an index : " << it.computeIndexInBitmap() << " and dimension: " << + this->get_dimension_of_a_cell(it.computeIndexInBitmap()) << " get the value : " << + filtrationLevel << std::endl; } *it = filtrationLevel; ++it; @@ -366,7 +371,8 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(char* perseusStyleFi template std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(size_t cell_) { bool bdg = false; - //first of all, we need to take the list of coordinates in which the cell has nonzero length. We do it by using modified version to compute dimension of a cell: + // First of all, we need to take the list of coordinates in which the cell has nonzero length. + // We do it by using modified version to compute dimension of a cell: std::vector< unsigned > dimensionsInWhichCellHasNonzeroLength; unsigned dimension = 0; size_t cell1 = cell_; @@ -380,9 +386,9 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(siz } if (bdg) { - cerr << "dimensionsInWhichCellHasNonzeroLength : \n"; + std::cerr << "dimensionsInWhichCellHasNonzeroLength : \n"; for (size_t i = 0; i != dimensionsInWhichCellHasNonzeroLength.size(); ++i) { - cerr << dimensionsInWhichCellHasNonzeroLength[i] << endl; + std::cerr << dimensionsInWhichCellHasNonzeroLength[i] << std::endl; } getchar(); } @@ -393,9 +399,12 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(siz boundaryElements.push_back(cell_ - multipliers[ dimensionsInWhichCellHasNonzeroLength[i] ]); boundaryElements.push_back(cell_ + multipliers[ dimensionsInWhichCellHasNonzeroLength[i] ]); - if (bdg) cerr << "multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << endl; - if (bdg) cerr << "cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << endl; - if (bdg) cerr << "cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << endl; + if (bdg) std::cerr << "multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; + if (bdg) std::cerr << "cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << + cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; + if (bdg) std::cerr << "cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << + cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; } return boundaryElements; } @@ -403,7 +412,8 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(siz template std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(size_t cell_) { bool bdg = false; - //first of all, we need to take the list of coordinates in which the cell has nonzero length. We do it by using modified version to compute dimension of a cell: + // First of all, we need to take the list of coordinates in which the cell has nonzero length. + // We do it by using modified version to compute dimension of a cell: std::vector< unsigned > dimensionsInWhichCellHasZeroLength; unsigned dimension = 0; size_t cell1 = cell_; @@ -417,16 +427,16 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(s } std::vector counter = this->compute_counter_for_given_cell(cell_); - //reverse(counter.begin() , counter.end()); + // reverse(counter.begin() , counter.end()); if (bdg) { - cerr << "dimensionsInWhichCellHasZeroLength : \n"; + std::cerr << "dimensionsInWhichCellHasZeroLength : \n"; for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { - cerr << dimensionsInWhichCellHasZeroLength[i] << endl; + std::cerr << dimensionsInWhichCellHasZeroLength[i] << std::endl; } - cerr << "\n counter : " << endl; + std::cerr << "\n counter : " << std::endl; for (size_t i = 0; i != counter.size(); ++i) { - cerr << counter[i] << endl; + std::cerr << counter[i] << std::endl; } getchar(); } @@ -435,27 +445,29 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(s if (dimensionsInWhichCellHasZeroLength.size() == 0)return coboundaryElements; for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { if (bdg) { - cerr << "Dimension : " << i << endl; + std::cerr << "Dimension : " << i << std::endl; if (counter[dimensionsInWhichCellHasZeroLength[i]] == 0) { - cerr << "In dimension : " << i << " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; + std::cerr << "In dimension : " << i << + " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; } if (counter[dimensionsInWhichCellHasZeroLength[i]] == 2 * this->sizes[dimensionsInWhichCellHasZeroLength[i]]) { - cerr << "In dimension : " << i << " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; + std::cerr << "In dimension : " << i << + " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; } } - if ((cell_ > multipliers[dimensionsInWhichCellHasZeroLength[i]]) && (counter[dimensionsInWhichCellHasZeroLength[i]] != 0)) - //if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 0 ) - { - if (bdg)cerr << "Subtracting : " << cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]] << endl; + if ((cell_ > multipliers[dimensionsInWhichCellHasZeroLength[i]]) && + (counter[dimensionsInWhichCellHasZeroLength[i]] != 0)) { + // if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 0 ) + if (bdg)std::cerr << "Subtracting : " << cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]] << std::endl; coboundaryElements.push_back(cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]]); } - if ((cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] < this->data.size()) && (counter[dimensionsInWhichCellHasZeroLength[i]] != 2 * this->sizes[dimensionsInWhichCellHasZeroLength[i]])) - //if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 2*this->sizes[dimensionsInWhichCellHasZeroLength[i]] ) - { + if ((cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] < this->data.size()) && + (counter[dimensionsInWhichCellHasZeroLength[i]] != 2 * this->sizes[dimensionsInWhichCellHasZeroLength[i]])) { + // if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 2*this->sizes[dimensionsInWhichCellHasZeroLength[i]] ) coboundaryElements.push_back(cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]]); - if (bdg)cerr << "Adding : " << cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] << endl; + if (bdg)std::cerr << "Adding : " << cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] << std::endl; } } return coboundaryElements; @@ -464,19 +476,19 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(s template unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell(size_t cell_) { bool dbg = false; - if (dbg)cerr << "\n\n\n Computing position o a cell of an index : " << cell_ << endl; + if (dbg)std::cerr << "\n\n\n Computing position o a cell of an index : " << cell_ << std::endl; unsigned dimension = 0; for (size_t i = this->multipliers.size(); i != 0; --i) { unsigned position = cell_ / multipliers[i - 1]; - if (dbg)cerr << "i-1 :" << i - 1 << endl; - if (dbg)cerr << "cell_ : " << cell_ << endl; - if (dbg)cerr << "position : " << position << endl; - if (dbg)cerr << "multipliers[" << i - 1 << "] = " << multipliers[i - 1] << endl; + if (dbg)std::cerr << "i-1 :" << i - 1 << std::endl; + if (dbg)std::cerr << "cell_ : " << cell_ << std::endl; + if (dbg)std::cerr << "position : " << position << std::endl; + if (dbg)std::cerr << "multipliers[" << i - 1 << "] = " << multipliers[i - 1] << std::endl; if (dbg)getchar(); if (position % 2 == 1) { - if (dbg)cerr << "Nonzero length in this direction \n"; + if (dbg)std::cerr << "Nonzero length in this direction \n"; dimension++; } cell_ = cell_ % multipliers[i - 1]; @@ -493,11 +505,12 @@ template void Bitmap_cubical_complex_base::impose_lower_star_filtration() { bool dbg = false; - //this vector will be used to check which elements have already been taken care of in imposing lower star filtration: + // this vector will be used to check which elements have already been taken care of in imposing lower star filtration: std::vector isThisCellConsidered(this->data.size(), false); std::vector indicesToConsider; - //we assume here that we already have a filtration on the top dimensional cells and we have to extend it to lower ones. + // we assume here that we already have a filtration on the top dimensional cells + // and we have to extend it to lower ones. typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); for (it = this->top_dimensional_cells_begin(); it != this->top_dimensional_cells_end(); ++it) { indicesToConsider.push_back(it.computeIndexInBitmap()); @@ -505,9 +518,9 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() { while (indicesToConsider.size()) { if (dbg) { - cerr << "indicesToConsider in this iteration \n"; + std::cerr << "indicesToConsider in this iteration \n"; for (size_t i = 0; i != indicesToConsider.size(); ++i) { - cout << indicesToConsider[i] << " "; + std::cout << indicesToConsider[i] << " "; } getchar(); } @@ -529,9 +542,12 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() { } template -std::vector< size_t > Bitmap_cubical_complex_base::generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions(std::vector< bool > directionsForPeriodicBCond_) { +std::vector< size_t > +Bitmap_cubical_complex_base::generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions(std::vector< bool > directionsForPeriodicBCond_) { bool dbg = false; - if (this->sizes.size() != directionsForPeriodicBCond_.size())throw "directionsForPeriodicBCond_ vector size is different from the size of the bitmap. The program will now terminate \n"; + if (this->sizes.size() != directionsForPeriodicBCond_.size()) + throw ("directionsForPeriodicBCond_ vector size is different from the size of the bitmap. " + "The program will now terminate \n"); std::vector sizes(this->sizes.size()); for (size_t i = 0; i != this->sizes.size(); ++i)sizes[i] = 2 * this->sizes[i]; @@ -544,7 +560,7 @@ std::vector< size_t > Bitmap_cubical_complex_base::generate_vector_of_shifts_ size_t position; if (!c.isFinal()) { position = i; - //result.push_back( i ); + // result.push_back( i ); } else { std::vector< bool > finals = c.directionsOfFinals(); bool jumpInPosition = false; @@ -555,7 +571,7 @@ std::vector< size_t > Bitmap_cubical_complex_base::generate_vector_of_shifts_ } } if (jumpInPosition == true) { - //in this case this guy is final, so we need to find 'the opposite one' + // in this case this guy is final, so we need to find 'the opposite one' position = compute_position_in_bitmap(c.findOpposite(directionsForPeriodicBCond_)); } else { position = i; @@ -563,8 +579,8 @@ std::vector< size_t > Bitmap_cubical_complex_base::generate_vector_of_shifts_ } result.push_back(position); if (dbg) { - cerr << " position : " << position << endl; - cerr << c << endl; + std::cerr << " position : " << position << std::endl; + std::cerr << c << std::endl; getchar(); } diff --git a/src/Bitmap_cubical_complex/include/gudhi/counter.h b/src/Bitmap_cubical_complex/include/gudhi/counter.h index 9df819b2..9445a422 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/counter.h +++ b/src/Bitmap_cubical_complex/include/gudhi/counter.h @@ -26,17 +26,15 @@ #include #include -using namespace std; - /** * This is an implementation of a simple counter. It is needed for the implementation of a bitmapCubicalComplex. **/ class counter { public: - /** - * Constructor of a counter class. It takes only the parameter which is the end value of the counter. The default beginning value is a vector of the same length as the endd, filled-in with zeros. + * Constructor of a counter class. It takes only the parameter which is the end value of the counter. + * The default beginning value is a vector of the same length as the end, filled-in with zeros. **/ counter(std::vector< int > endd) { for (size_t i = 0; i != endd.size(); ++i) { @@ -47,10 +45,12 @@ class counter { } /** - * Constructor of a counter class. It takes as the input beginn and end vector. It assumes that begin vector is lexicographically below the end vector. + * Constructor of a counter class. It takes as the input beginn and endd vector. It assumes that begin vector is + * lexicographically below the end vector. **/ counter(std::vector< int > beginn, std::vector< int > endd) { - if (beginn.size() != endd.size())throw "In constructor of a counter, begin and end vectors do not have the same size. Program terminate"; + if (beginn.size() != endd.size()) + throw("In constructor of a counter, begin and end vectors do not have the same size. Program terminate"); for (size_t i = 0; i != endd.size(); ++i) { this->current.push_back(0); this->begin.push_back(0); @@ -59,7 +59,8 @@ class counter { } /** - * Function to increment the counter. If the value returned by the function is true, then the incrementation process was successful. + * Function to increment the counter. If the value returned by the function is true, then the incrementation process + * was successful. * If the value of the function is false, that means, that the counter have reached its end-value. **/ bool increment() { @@ -87,8 +88,9 @@ class counter { } /** - * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. Its aim is to find an counter corresponding to the element the following - * boundary element is identified with when periodic boundary conditions are imposed. + * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. + * Its aim is to find an counter corresponding to the element the following boundary element is identified with + * when periodic boundary conditions are imposed. **/ std::vector< int > findOpposite(std::vector< bool > directionsForPeriodicBCond) { std::vector< int > result; @@ -121,12 +123,13 @@ class counter { * Function to write counter to the stream. **/ friend std::ostream& operator<<(std::ostream& out, const counter& c) { - //cerr << "c.current.size() : " << c.current.size() << endl; + // std::cerr << "c.current.size() : " << c.current.size() << std::endl; for (size_t i = 0; i != c.current.size(); ++i) { out << c.current[i] << " "; } return out; } + private: std::vector< int > begin; std::vector< int > end; -- cgit v1.2.3 From 39ffc7af64543f0b2ce17487771afbd010a97349 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 27 Nov 2015 14:16:44 +0000 Subject: Adding changes to the cubcial complex class according to Marc and Vincent's comments. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@930 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cb9134a5c18fae3e2e63bbaf8329dd168d08d3b3 --- .../example/Bitmap_cubical_complex.cpp | 147 +- src/Bitmap_cubical_complex/example/CMakeLists.txt | 2 +- .../example/Random_bitmap_cubical_complex.cpp | 174 +-- .../include/gudhi/Bitmap_cubical_complex.h | 1443 ++++++++++---------- .../include/gudhi/Bitmap_cubical_complex_base.h | 1352 ++++++++++-------- src/Bitmap_cubical_complex/include/gudhi/counter.h | 316 +++-- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 1261 ++++++++--------- src/CMakeLists.txt | 8 +- 8 files changed, 2467 insertions(+), 2236 deletions(-) (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index 37c16618..31da3609 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -1,71 +1,76 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Sophia-Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// for persistence algorithm -#include -#include -#include - -#include - -// standard stuff -#include -#include - -using namespace Gudhi; -using namespace Gudhi::persistent_cohomology; -using namespace std; - -int main(int argc, char** argv) { - cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes " - "provided in text files in Perseus style (the only numbed in the first line is a dimension D of a cubical " - "complex. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N " - "denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of " - "top dimensional cells. We assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or " - "CubicalTwoSphere.txt for example." << endl; - - int p = 2; - double min_persistence = 0; - - if (argc != 2) { - cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style cubical complex at the " - "input. The program will now terminate.\n"; - return 1; - } - - Bitmap_cubical_complex b(argv[1]); - - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); - pcoh.init_coefficients(p); // initializes the coefficient field for homology - pcoh.compute_persistent_cohomology(min_persistence); - - - stringstream ss; - ss << argv[1] << "_persistence"; - std::ofstream out((char*) ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +//for persistence algorithm +#include +#include +#include + + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include + +using namespace std; + +int main( int argc , char** argv ) +{ + cout << "This program computes persistent homology, by using bitmap_cubical_complex class,\ + of cubical complexes provided in text files in Perseus style (the only numbered in \ +the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are\ + numbers of top dimensional cells in the direction I. Let N denote product \ +of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are\ + filtrations of top dimensional cells. We assume that the cells are in the \ +lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + + int p = 2; + double min_persistence = 0; + + if ( argc != 2 ) + { + cout << "Wrong number of parameters. Please provide the name of a file with a\ + Perseus style bitmap at the input. The program will now terminate.\n"; + return 1; + } + + Bitmap_cubical_complex b( argv[1] ); + + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + pcoh.compute_persistent_cohomology( min_persistence ); + + + stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out((char*)ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index 05ef1319..dd252a79 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.6) -project(GUDHISimplexTreeFromFile) +project(GUDHIBitmap) add_executable ( Bitmap_cubical_complex Bitmap_cubical_complex.cpp ) target_link_libraries(Bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY}) diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp index ac7557ce..60cfc113 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -1,81 +1,93 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -// for persistence algorithm -#include -#include -#include - -#include - -// standard stuff -#include -#include -#include -#include -#include - -using namespace Gudhi; -using namespace Gudhi::persistent_cohomology; -using namespace std; - -int main(int argc, char** argv) { - srand(time(0)); - - cout << "This program computes persistent homology, by using Bitmap_cubical_complex class, of cubical complexes. " - "The first parameter of the program is the dimension D of the cubical complex. The next D parameters are number " - "of top dimensional cubes in each dimension of the cubical complex. The program will create random cubical " - "complex of that sizes and compute persistent homology of it." << endl; - - int p = 2; - double min_persistence = 0; - - size_t dimensionOfBitmap = (size_t) atoi(argv[1]); - std::vector< unsigned > sizes; - size_t multipliers = 1; - for (size_t dim = 0; dim != dimensionOfBitmap; ++dim) { - unsigned sizeInThisDimension = (unsigned) atoi(argv[2 + dim]); - sizes.push_back(sizeInThisDimension); - multipliers *= sizeInThisDimension; - } - - std::vector< double > data; - for (size_t i = 0; i != multipliers; ++i) { - data.push_back(rand() / (double) RAND_MAX); - } - - Bitmap_cubical_complex b(sizes, data); - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); - pcoh.init_coefficients(p); // initializes the coefficient field for homology - pcoh.compute_persistent_cohomology(min_persistence); - - stringstream ss; - ss << "randomComplex_persistence"; - std::ofstream out((char*) ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +//for persistence algorithm +#include +#include +#include + + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include +#include + +using namespace std; + +int main( int argc , char** argv ) +{ + srand( time(0) ); + + cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes. \ +The first parameter of the program is the dimension D of the bitmap. \ +The next D parameters are number of top dimensional cubes in each dimension of the bitmap.\ +The program will create random cubical complex of that sizes and compute persistent homology of it." << endl; + + int p = 2; + double min_persistence = 0; + + if ( argc < 3 ) + { + cerr << "Wrong number of parameters, the program will now terminate\n"; + return 1; + } + + size_t dimensionOfBitmap = (size_t)atoi( argv[1] ); + std::vector< unsigned > sizes; + size_t multipliers = 1; + for ( size_t dim = 0 ; dim != dimensionOfBitmap ; ++dim ) + { + unsigned sizeInThisDimension = (unsigned)atoi( argv[2+dim] ); + sizes.push_back( sizeInThisDimension ); + multipliers *= sizeInThisDimension; + } + + std::vector< double > data; + for ( size_t i = 0 ; i != multipliers ; ++i ) + { + data.push_back( rand()/(double)RAND_MAX ); + } + + + + Bitmap_cubical_complex b( sizes , data ); + + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + pcoh.compute_persistent_cohomology( min_persistence ); + + + stringstream ss; + ss << "randomComplex_persistence"; + std::ofstream out((char*)ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index 2f8cb0a3..f2c753d9 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -1,724 +1,719 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Sophia-Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef BITMAP_CUBICAL_COMPLEX_H_ -#define BITMAP_CUBICAL_COMPLEX_H_ - -#include - -#include -#include // for pair -#include // for sort -#include // for vector - -// global variable, was used just for debugging. -bool globalDbg = false; - -template -class Bitmap_cubical_complex : public Bitmap_cubical_complex_base { - public: - //******************************************************************************************************************// - // Typedefs and typenames - //******************************************************************************************************************// - friend class Simplex_handle; - typedef size_t Simplex_key; - typedef T Filtration_value; - - - //******************************************************************************************************************// - // Simplex handle class - //******************************************************************************************************************// - - /** - * Handle of a cell, required for compatibility with the function to compute persistence in Gudhi. Elements of this - * class are: the pointer to the bitmap B in which the considered cell is together with a position of this cell in B. - * Given this data, one can get all the information about the considered cell. - **/ - class Simplex_handle { - public: - Simplex_handle() { - if (globalDbg) { - std::cerr << "Simplex_handle()\n"; - } - this->b = 0; - this->position = 0; - } - - Simplex_handle(Bitmap_cubical_complex* b) { - if (globalDbg) { - std::cerr << "Simplex_handle(Bitmap_cubical_complex* b)\n"; - } - this->b = b; - this->position = 0; - } - - Simplex_handle(const Simplex_handle& org) : b(org.b) { - if (globalDbg) { - std::cerr << "Simplex_handle( const Simplex_handle& org )\n"; - } - this->position = org.position; - } - - Simplex_handle& operator=(const Simplex_handle& rhs) { - if (globalDbg) { - std::cerr << "Simplex_handle operator = \n"; - } - this->position = rhs.position; - this->b = rhs.b; - return *this; - } - - Simplex_handle(Bitmap_cubical_complex* b, Simplex_key position) { - if (globalDbg) { - std::cerr << "Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position)\n"; - std::cerr << "Position : " << position << std::endl; - } - this->b = b; - this->position = position; - } - friend class Bitmap_cubical_complex; - private: - Bitmap_cubical_complex* b; - Simplex_key position; - // Assumption -- this field always keep the REAL position of simplex in the bitmap, no matter what keys have been. - // to deal with the keys, the class Bitmap_cubical_complex have extra vectors: keyAssociatedToSimplex and - // simplexAssociatedToKey that allow to move between actual cell and the key assigned to it. - }; - - - //******************************************************************************************************************// - // Constructors - //******************************************************************************************************************// - // Over here we need to definie various input types. I am proposing the following ones: - // Perseus style - // TODO(Pawel Dlotko): H5 files? - // TODO(Pawel Dlotko): binary files with little endiangs / big endians? - // TODO(Pawel Dlotko): constructor from a vector of elements of a type T. - - /** - * Constructor form a Perseus-style file. - **/ - Bitmap_cubical_complex(char* perseusStyleFile) : Bitmap_cubical_complex_base(perseusStyleFile) { - if (globalDbg) { - std::cerr << "Bitmap_cubical_complex( char* perseusStyleFile )\n"; - } - std::vector< size_t > keyAssociatedToSimplex(this->totalNumberOfCells + 1); - std::vector< size_t > simplexAssociatedToKey(this->totalNumberOfCells + 1); - - for (size_t i = 0; i != this->totalNumberOfCells; ++i) { - keyAssociatedToSimplex[i] = simplexAssociatedToKey[i] = i; - } - this->keyAssociatedToSimplex = keyAssociatedToSimplex; - this->simplexAssociatedToKey = simplexAssociatedToKey; - // we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change - // some elements of the bitmap, then this procedure need to be called again. - this->initializeElementsOrderedAccordingToFiltration(); - } - - /** - * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells in the - * following directions and vector of element of a type T with filtration on top dimensional cells. - **/ - Bitmap_cubical_complex(std::vector dimensions, std::vector topDimensionalCells) - : Bitmap_cubical_complex_base(dimensions, topDimensionalCells) { - std::vector< size_t > keyAssociatedToSimplex(this->totalNumberOfCells + 1); - std::vector< size_t > simplexAssociatedToKey(this->totalNumberOfCells + 1); - - for (size_t i = 0; i != this->totalNumberOfCells; ++i) { - keyAssociatedToSimplex[i] = simplexAssociatedToKey[i] = i; - } - this->keyAssociatedToSimplex = keyAssociatedToSimplex; - this->simplexAssociatedToKey = simplexAssociatedToKey; - // we initialize this only once, in each constructor, when the bitmap is constructed. If the user decide to change - // some elements of the bitmap, then this procedure need to be called again. - this->initializeElementsOrderedAccordingToFiltration(); - } - - //******************************************************************************************************************// - // Other 'easy' functions - //******************************************************************************************************************// - - /** - * Returns number of all cubes in the complex. - **/ - size_t num_simplices()const { - return this->totalNumberOfCells; - } - - /** - * Returns a Simplex_handle to a cube that do not exist in this complex. - **/ - Simplex_handle null_simplex() { - return Simplex_handle(this, this->data.size()); - } - - /** - * Returns dimension of the complex. - **/ - size_t dimension() { - return this->sizes.size(); - } - - /** - * Return dimension of a cell pointed by the Simplex_handle. - **/ - size_t dimension(const Simplex_handle& sh) { - if (globalDbg) { - std::cerr << "int dimension(const Simplex_handle& sh)\n"; - } - if (sh.position != this->data.size()) return sh.b->get_dimension_of_a_cell(sh.position); - return std::numeric_limits::max(); - } - - /** - * Return the filtration of a cell pointed by the Simplex_handle. - **/ - T filtration(const Simplex_handle& sh) { - if (globalDbg) { - std::cerr << "T filtration(const Simplex_handle& sh)\n"; - } - // Returns the filtration value of a simplex. - if (sh.position != this->data.size()) return sh.b->data[ sh.position ]; - return INT_MAX; - } - - /** - * Return a key which is not a key of any cube in the considered data structure. - **/ - Simplex_key null_key() { - if (globalDbg) { - std::cerr << "Simplex_key null_key()\n"; - } - return this->data.size(); - } - - /** - * Return the key of a cube pointed by the Simplex_handle. - **/ - Simplex_key key(const Simplex_handle& sh) { - if (globalDbg) { - std::cerr << "Simplex_key key(const Simplex_handle& sh)\n"; - } - return sh.b->keyAssociatedToSimplex[ sh.position ]; - } - - /** - * Return the Simplex_handle given the key of the cube. - **/ - Simplex_handle simplex(Simplex_key key) { - if (globalDbg) { - std::cerr << "Simplex_handle simplex(Simplex_key key)\n"; - } - return Simplex_handle(this, this->simplexAssociatedToKey[ key ]); - } - - /** - * Assign key to a cube pointed by the Simplex_handle - **/ - void assign_key(Simplex_handle& sh, Simplex_key key) { - if (globalDbg) { - std::cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n"; - } - this->keyAssociatedToSimplex[sh.position] = key; - this->simplexAssociatedToKey[key] = sh.position; - } - - /** - * Function called from a constructor. It is needed for Filtration_simplex_iterator to work. - **/ - void initializeElementsOrderedAccordingToFiltration(); - - - - //******************************************************************************************************************// - // Iterators - //******************************************************************************************************************// - - /** - * Boundary_simplex_iterator class allows iteration on boundary of each cube. - **/ - class Boundary_simplex_range; - - class Boundary_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - // Iterator on the simplices belonging to the boundary of a simplex. - // value_type must be 'Simplex_handle'. - public: - Boundary_simplex_iterator(Simplex_handle& sh) : sh(sh) { - if (globalDbg) { - std::cerr << "Boundary_simplex_iterator( Simplex_handle& sh )\n"; - } - this->position = 0; - this->boundaryElements = this->sh.b->get_boundary_of_a_cell(this->sh.position); - } - - Boundary_simplex_iterator operator++() { - if (globalDbg) { - std::cerr << "Boundary_simplex_iterator operator++()\n"; - } - ++this->position; - return *this; - } - - Boundary_simplex_iterator operator++(int) { - Boundary_simplex_iterator result = *this; - ++(*this); - return result; - } - - Boundary_simplex_iterator operator=(const Boundary_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "Boundary_simplex_iterator operator =\n"; - } - this->sh = rhs.sh; - this->boundaryElements.clear(); - this->boundaryElementsinsert(this->boundaryElements.end(), - rhs.boundaryElements.begin(), rhs.boundaryElements.end()); - } - - bool operator==(const Boundary_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator ==\n"; - } - if (this->position == rhs.position) { - if (this->boundaryElements.size() != rhs.boundaryElements.size())return false; - for (size_t i = 0; i != this->boundaryElements.size(); ++i) { - if (this->boundaryElements[i] != rhs.boundaryElements[i])return false; - } - return true; - } - return false; - } - - bool operator!=(const Boundary_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator != \n"; - } - return !(*this == rhs); - } - - Simplex_handle operator*() { - if (globalDbg) { - std::cerr << "Simplex_handle operator*\n"; - } - return Simplex_handle(this->sh.b, this->boundaryElements[this->position]); - } - - friend class Boundary_simplex_range; - private: - Simplex_handle sh; - std::vector< size_t > boundaryElements; - size_t position; - }; - - /** - * Boundary_simplex_range class provides ranges for boundary iterators. - **/ - class Boundary_simplex_range { - // Range giving access to the simplices in the boundary of a simplex. - // .begin() and .end() return type Boundary_simplex_iterator. - public: - Boundary_simplex_range(const Simplex_handle& sh) : sh(sh) { } - - Boundary_simplex_iterator begin() { - if (globalDbg) { - std::cerr << "Boundary_simplex_iterator begin\n"; - } - Boundary_simplex_iterator it(this->sh); - return it; - } - - Boundary_simplex_iterator end() { - if (globalDbg) { - std::cerr << "Boundary_simplex_iterator end()\n"; - } - Boundary_simplex_iterator it(this->sh); - it.position = it.boundaryElements.size(); - return it; - } - - private: - Simplex_handle sh; - }; - - - /** - * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. Secondary criteria for filtration are: - * (1) Dimension of a cube (lower dimensional comes first). - * (2) Position in the data structure (the ones that are earlies in the data structure comes first). - **/ - class Filtration_simplex_range; - - class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - // Iterator over all simplices of the complex in the order of the indexing scheme. - // 'value_type' must be 'Simplex_handle'. - public: - Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { } - - Filtration_simplex_iterator() : b(NULL) { } - - Filtration_simplex_iterator operator++() { - if (globalDbg) { - std::cerr << "Filtration_simplex_iterator operator++\n"; - } - ++this->position; - return (*this); - } - - Filtration_simplex_iterator operator++(int) { - Filtration_simplex_iterator result = *this; - ++(*this); - return result; - } - - Filtration_simplex_iterator operator=(const Filtration_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "Filtration_simplex_iterator operator =\n"; - } - this->b = rhs.b; - this->position = rhs.position; - } - - bool operator==(const Filtration_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n"; - } - if (this->position == rhs.position) { - return true; - } - return false; - } - - bool operator!=(const Filtration_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n"; - } - return !(*this == rhs); - } - - Simplex_handle operator*() { - if (globalDbg) { - std::cerr << "Simplex_handle operator*()\n"; - } - return Simplex_handle(this->b, this->b->elementsOrderedAccordingToFiltration[ this->position ]); - } - - friend class Filtration_simplex_range; - private: - Bitmap_cubical_complex* b; - size_t position; - }; - - /** - * Filtration_simplex_range provides the ranges for Filtration_simplex_iterator. - **/ - class Filtration_simplex_range { - // Range over the simplices of the complex in the order of the filtration. - // .begin() and .end() return type Filtration_simplex_iterator. - public: - Filtration_simplex_range(Bitmap_cubical_complex* b) : b(b) { } - - Filtration_simplex_iterator begin() { - if (globalDbg) { - std::cerr << "Filtration_simplex_iterator begin() \n"; - } - return Filtration_simplex_iterator(this->b); - } - - Filtration_simplex_iterator end() { - if (globalDbg) { - std::cerr << "Filtration_simplex_iterator end()\n"; - } - Filtration_simplex_iterator it(this->b); - it.position = this->b->elementsOrderedAccordingToFiltration.size(); - return it; - } - private: - Bitmap_cubical_complex* b; - }; - - - - //******************************************************************************************************************// - // Methods to access iterators from the container: - - /** - * boundary_simplex_range creates an object of a Boundary_simplex_range class that provides ranges for the Boundary_simplex_iterator. - **/ - Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh) { - if (globalDbg) { - std::cerr << "Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh)\n"; - } - // Returns a range giving access to all simplices of the boundary of a simplex, i.e. the set of - // codimension 1 subsimplices of the Simplex. - return Boundary_simplex_range(sh); - } - - /** - * filtration_simplex_range creates an object of a Filtration_simplex_range class that provides ranges for the - * Filtration_simplex_iterator. - **/ - Filtration_simplex_range filtration_simplex_range() { - if (globalDbg) { - std::cerr << "Filtration_simplex_range filtration_simplex_range()\n"; - } - // Returns a range over the simplices of the complex in the order of the filtration - return Filtration_simplex_range(this); - } - //******************************************************************************************************************// - - - - //******************************************************************************************************************// - // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are - // there. - // TODO(Pawel Dlotko): The file IndexingTag.h in the Gudhi library contains an empty structure, so I understand that - // this is something that was planned (for simplicial maps?) but was never finished. The only idea I have here is - // to use the same empty structure from IndexingTag.h file, but only if the compiler needs it. If the compiler - // do not need it, then I would rather not add here elements which I do not understand. - // typedef Indexing_tag - - /** - * Function needed for compatibility with Gudhi. Not useful for other purposes. - **/ - std::pair endpoints(Simplex_handle sh) { - std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh.position); - if (globalDbg) { - std::cerr << "std::pair endpoints( Simplex_handle sh )\n"; - std::cerr << "bdry.size() : " << bdry.size() << std::endl; - } - // this method returns two first elements from the boundary of sh. - if (bdry.size() < 2) - throw("Error in endpoints in Bitmap_cubical_complex class. " - "The cell for which this method was called have less than two elements in the boundary."); - return std::make_pair(Simplex_handle(this, bdry[0]), Simplex_handle(this, bdry[1])); - } - - - /** - * Class needed for compatibility with Gudhi. Not useful for other purposes. - **/ - class Skeleton_simplex_range; - - class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { - // Iterator over all simplices of the complex in the order of the indexing scheme. - // 'value_type' must be 'Simplex_handle'. - public: - Skeleton_simplex_iterator(Bitmap_cubical_complex* b, size_t d) : b(b), dimension(d) { - if (globalDbg) { - std::cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n"; - } - // find the position of the first simplex of a dimension d - this->position = 0; - while ((this->position != b->data.size()) && - (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { - ++this->position; - } - } - - Skeleton_simplex_iterator() : b(NULL), dimension(0) { } - - Skeleton_simplex_iterator operator++() { - if (globalDbg) { - std::cerr << "Skeleton_simplex_iterator operator++()\n"; - } - // increment the position as long as you did not get to the next element of the dimension dimension. - ++this->position; - while ((this->position != this->b->data.size()) && - (this->b->get_dimension_of_a_cell(this->position) != this->dimension)) { - ++this->position; - } - return (*this); - } - - Skeleton_simplex_iterator operator++(int) { - Skeleton_simplex_iterator result = *this; - ++(*this); - return result; - } - - Skeleton_simplex_iterator operator=(const Skeleton_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "Skeleton_simplex_iterator operator =\n"; - } - this->b = rhs.b; - this->position = rhs.position; - } - - bool operator==(const Skeleton_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator ==\n"; - } - if (this->position == rhs.position) { - return true; - } - return false; - } - - bool operator!=(const Skeleton_simplex_iterator& rhs) { - if (globalDbg) { - std::cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n"; - } - return !(*this == rhs); - } - - Simplex_handle operator*() { - if (globalDbg) { - std::cerr << "Simplex_handle operator*() \n"; - } - return Simplex_handle(this->b, this->position); - } - - friend class Skeleton_simplex_range; - private: - Bitmap_cubical_complex* b; - size_t position; - int dimension; - }; - - /** - * Class needed for compatibility with Gudhi. Not useful for other purposes. - **/ - class Skeleton_simplex_range { - // Range over the simplices of the complex in the order of the filtration. - // .begin() and .end() return type Filtration_simplex_iterator. - public: - Skeleton_simplex_range(Bitmap_cubical_complex* b, int dimension) : b(b), dimension(dimension) { } - - Skeleton_simplex_iterator begin() { - if (globalDbg) { - std::cerr << "Skeleton_simplex_iterator begin()\n"; - } - return Skeleton_simplex_iterator(this->b, this->dimension); - } - - Skeleton_simplex_iterator end() { - if (globalDbg) { - std::cerr << "Skeleton_simplex_iterator end()\n"; - } - Skeleton_simplex_iterator it(this->b, this->dimension); - it.position = this->b->data.size(); - return it; - } - - private: - Bitmap_cubical_complex* b; - int dimension; - }; - - /** - * Function needed for compatibility with Gudhi. Not useful for other purposes. - **/ - Skeleton_simplex_range skeleton_simplex_range(int dimension) { - if (globalDbg) { - std::cerr << "Skeleton_simplex_range skeleton_simplex_range( int dimension )\n"; - } - return Skeleton_simplex_range(this, dimension); - } - - - - //******************************************************************************************************************// - // functions used for debugging: - - /** - * Function used for debugging purposes. - **/ - void printKeyAssociatedToSimplex() { - for (size_t i = 0; i != this->data.size(); ++i) { - std::cerr << i << " -> " << this->simplexAssociatedToKey[i] << std::endl; - } - } - - /** - * Function used for debugging purposes. - **/ - size_t printRealPosition(const Simplex_handle& sh) { - return sh.position; - } - - private: - std::vector< size_t > keyAssociatedToSimplex; - std::vector< size_t > simplexAssociatedToKey; - // needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. - std::vector< size_t > elementsOrderedAccordingToFiltration; -}; - -template -bool compareElementsForElementsOrderedAccordingToFiltration(const std::pair< size_t, - std::pair< T, char > >& f, - const std::pair< size_t, - std::pair< T, char > >& s) { - if (globalDbg) { - std::cerr << "ompareElementsForElementsOrderedAccordingToFiltration\n"; - } - if (f.second.first < s.second.first) { - return true; - } else { - if (f.second.first > s.second.first) { - return false; - } else { - // in this case f.second.first == s.second.first, and we use dimension to compare: - if (f.second.second < s.second.second) { - return true; - } else { - if (f.second.second > s.second.second) { - return false; - } else { - // in this case, both the filtration value and the dimensions for those cells are the same. - // Since it may be nice to have a stable sorting procedure, in this case, we compare positions in the bitmap: - return ( f.first < s.first); - } - } - } - } -} - -template -void Bitmap_cubical_complex::initializeElementsOrderedAccordingToFiltration() { - if (globalDbg) { - std::cerr << "void Bitmap_cubical_complex::initializeElementsOrderedAccordingToFiltration() \n"; - } - // ( position , (filtration , dimension) ) - std::vector< std::pair< size_t, std::pair< T, char > > > dataOfElementsFromBitmap(this->data.size()); - for (size_t i = 0; i != this->data.size(); ++i) { - // TODO(Pawel Dlotko): This can be optimized by having a counter here. We do not need to re-compute the dimension - // for every cell from scratch - dataOfElementsFromBitmap[i] = std::make_pair(i, std::make_pair(this->data[i], this->get_dimension_of_a_cell(i))); - } - std::sort(dataOfElementsFromBitmap.begin(), dataOfElementsFromBitmap.end(), - compareElementsForElementsOrderedAccordingToFiltration); - - // Elements of bitmap ordered according to filtration then according to dimension then according to position in bitmap - std::vector< size_t > elements_of_bitmap_ordered(this->data.size()); - for (size_t i = 0; i != dataOfElementsFromBitmap.size(); ++i) { - elements_of_bitmap_ordered[i] = dataOfElementsFromBitmap[i].first; - } - this->elementsOrderedAccordingToFiltration = elements_of_bitmap_ordered; -} - - -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// - -#endif // BITMAP_CUBICAL_COMPLEX_H_ + /* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#pragma once +#include +#include "Bitmap_cubical_complex_base.h" + + + +namespace Gudhi +{ + +namespace Cubical_complex +{ + +//global variable, was used just for debugging. +const bool globalDbg = false; + +template +class Bitmap_cubical_complex : public Bitmap_cubical_complex_base +{ +public: +//*********************************************// +//Typedefs and typenames +//*********************************************// + friend class Simplex_handle; + typedef size_t Simplex_key; + typedef T Filtration_value; + + +//*********************************************// +//Simplex handle class +//*********************************************// + /** + * Handle of a cell, required for compatibility with the function to compute persistence in Gudhi. + * Elements of this class are: the pointer to the bitmap B in which the considered cell is + * together with a position of this cell in B. Given this data, + * one can get all the information about the considered cell. + **/ + class Simplex_handle + { + public: + Simplex_handle() + { + if ( globalDbg ){cerr << "Simplex_handle()\n";} + this->b = 0; + this->position = 0; + } + + Simplex_handle(Bitmap_cubical_complex* b) + { + if ( globalDbg ) + { + cerr << "Simplex_handle(Bitmap_cubical_complex* b)\n"; + } + this->b = b; + this->position = 0; + } + + //Simplex_handle( const Simplex_handle& org ):b(org.b) + //{ + // if ( globalDbg ){cerr << "Simplex_handle( const Simplex_handle& org )\n";} + // this->position = org.position; + //} + + Simplex_handle operator = ( const Simplex_handle& rhs ) + { + if ( globalDbg ){cerr << "Simplex_handle operator = \n";} + this->position = rhs.position; + this->b = rhs.b; + return *this; + } + + Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position) + { + if ( globalDbg ) + { + cerr << "Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position)\n"; + cerr << "Position : " << position << endl; + } + this->b = b; + this->position = position; + } + friend class Bitmap_cubical_complex; + private: + Bitmap_cubical_complex* b; + Simplex_key position; + //Assumption -- field above always keep the REAL position of simplex in the bitmap, + //no matter what keys have been. + //to deal with the keys, the class Bitmap_cubical_complex have extra vectors: key_associated_to_simplex and + //simplex_associated_to_key that allow to move between actual cell and the key assigned to it. + }; + + +//*********************************************// +//Constructors +//*********************************************// + //Over here we need to definie various input types. I am proposing the following ones: + //Perseus style + //H5 files? TODO + //binary files with little endiangs / big endians? TODO + //constructor from a vector of elements of a type T. TODO + + /** + * Constructor form a Perseus-style file. + **/ + Bitmap_cubical_complex( const char* perseus_style_file ): + Bitmap_cubical_complex_base(perseus_style_file),key_associated_to_simplex(this->total_number_of_cells+1), + simplex_associated_to_key(this->total_number_of_cells+1) + { + if ( globalDbg ){cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n";} + for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) + { + this->key_associated_to_simplex[i] = this->simplex_associated_to_key[i] = i; + } + //we initialize this only once, in each constructor, when the bitmap is constructed. + //If the user decide to change some elements of the bitmap, then this procedure need + //to be called again. + this->initialize_elements_ordered_according_to_filtration(); + } + + + /** + * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells + * in the following directions and vector of element of a type T + * with filtration on top dimensional cells. + **/ + Bitmap_cubical_complex( std::vector& dimensions , std::vector& top_dimensional_cells ): + Bitmap_cubical_complex_base(dimensions,top_dimensional_cells), + key_associated_to_simplex(this->total_number_of_cells+1), + simplex_associated_to_key(this->total_number_of_cells+1) + { + for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) + { + this->key_associated_to_simplex[i] = this->simplex_associated_to_key[i] = i; + } + //we initialize this only once, in each constructor, when the bitmap is constructed. + //If the user decide to change some elements of the bitmap, then this procedure need + //to be called again. + this->initialize_elements_ordered_according_to_filtration(); + } + +//*********************************************// +//Other 'easy' functions +//*********************************************// + /** + * Returns number of all cubes in the complex. + **/ + size_t num_simplices()const + { + return this->total_number_of_cells; + } + + /** + * Returns a Simplex_handle to a cube that do not exist in this complex. + **/ + Simplex_handle null_simplex() + { + return Simplex_handle(this,this->data.size()); + } + + /** + * Returns dimension of the complex. + **/ + size_t dimension() + { + return this->sizes.size(); + } + + /** + * Return dimension of a cell pointed by the Simplex_handle. + **/ + unsigned dimension(const Simplex_handle& sh) + { + if ( globalDbg ){cerr << "unsigned dimension(const Simplex_handle& sh)\n";} + if ( sh.position != this->data.size() ) return sh.b->get_dimension_of_a_cell( sh.position ); + return -1; + } + + /** + * Return the filtration of a cell pointed by the Simplex_handle. + **/ + T filtration(const Simplex_handle& sh) + { + if ( globalDbg ){cerr << "T filtration(const Simplex_handle& sh)\n";} + //Returns the filtration value of a simplex. + if ( sh.position != this->data.size() ) return sh.b->data[ sh.position ]; + return std::numeric_limits::max(); + } + + /** + * Return a key which is not a key of any cube in the considered data structure. + **/ + Simplex_key null_key() + { + if ( globalDbg ){cerr << "Simplex_key null_key()\n";} + return this->data.size(); + } + + /** + * Return the key of a cube pointed by the Simplex_handle. + **/ + Simplex_key key(const Simplex_handle& sh) + { + if ( globalDbg ){cerr << "Simplex_key key(const Simplex_handle& sh)\n";} + return sh.b->key_associated_to_simplex[ sh.position ]; + } + + /** + * Return the Simplex_handle given the key of the cube. + **/ + Simplex_handle simplex(Simplex_key key) + { + if ( globalDbg ){cerr << "Simplex_handle simplex(Simplex_key key)\n";} + return Simplex_handle( this , this->simplex_associated_to_key[ key ] ); + } + + /** + * Assign key to a cube pointed by the Simplex_handle + **/ + void assign_key(Simplex_handle& sh, Simplex_key key) + { + if ( globalDbg ){cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";} + this->key_associated_to_simplex[sh.position] = key; + this->simplex_associated_to_key[key] = sh.position; + } + + /** + * Function called from a constructor. It is needed for Filtration_simplex_iterator to work. + **/ + void initialize_elements_ordered_according_to_filtration(); + + + +//*********************************************// +//Iterators +//*********************************************// + + /** + * Boundary_simplex_iterator class allows iteration on boundary of each cube. + **/ + class Boundary_simplex_range; + class Boundary_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > + { + //Iterator on the simplices belonging to the boundary of a simplex. + //value_type must be 'Simplex_handle'. + public: + Boundary_simplex_iterator( Simplex_handle& sh ):sh(sh) + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator( Simplex_handle& sh )\n";} + this->position = 0; + this->boundary_elements = this->sh.b->get_boundary_of_a_cell( this->sh.position ); + } + Boundary_simplex_iterator operator++() + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator operator++()\n";} + ++this->position; + return *this; + } + Boundary_simplex_iterator operator++(int) + { + Boundary_simplex_iterator result = *this; + ++(*this); + return result; + } + Boundary_simplex_iterator operator =( const Boundary_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator operator =\n";} + this->sh = rhs.sh; + this->boundary_elements.clear(); + this->boundary_elementsinsert + (this->boundary_elements.end(), rhs.boundary_elements.begin(), rhs.boundary_elements.end()); + } + bool operator == ( const Boundary_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator ==\n";} + if ( this->position == rhs.position ) + { + if ( this->boundary_elements.size() != rhs.boundary_elements.size() )return false; + for ( size_t i = 0 ; i != this->boundary_elements.size() ; ++i ) + { + if ( this->boundary_elements[i] != rhs.boundary_elements[i] )return false; + } + return true; + } + return false; + } + + bool operator != ( const Boundary_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator != \n";} + return !(*this == rhs); + } + Simplex_handle operator*() + { + if ( globalDbg ){cerr << "Simplex_handle operator*\n";} + return Simplex_handle( this->sh.b , this->boundary_elements[this->position] ); + } + + friend class Boundary_simplex_range; + private: + Simplex_handle sh; + std::vector< size_t > boundary_elements; + size_t position; + }; + + + /** + * Boundary_simplex_range class provides ranges for boundary iterators. + **/ + class Boundary_simplex_range + { + //Range giving access to the simplices in the boundary of a simplex. + //.begin() and .end() return type Boundary_simplex_iterator. + public: + Boundary_simplex_range(const Simplex_handle& sh):sh(sh){}; + Boundary_simplex_iterator begin() + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator begin\n";} + Boundary_simplex_iterator it( this->sh ); + return it; + } + Boundary_simplex_iterator end() + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator end()\n";} + Boundary_simplex_iterator it( this->sh ); + it.position = it.boundary_elements.size(); + return it; + } + private: + Simplex_handle sh; + }; + + + /** + * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. + * Secondary criteria for filtration are: + * (1) Dimension of a cube (lower dimensional comes first). + * (2) Position in the data structure (the ones that are earlies in the data structure comes first). + **/ + class Filtration_simplex_range; + class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > + { + //Iterator over all simplices of the complex in the order of the indexing scheme. + //'value_type' must be 'Simplex_handle'. + public: + Filtration_simplex_iterator( Bitmap_cubical_complex* b ):b(b),position(0){}; + Filtration_simplex_iterator():b(NULL){}; + + Filtration_simplex_iterator operator++() + { + if ( globalDbg ){cerr << "Filtration_simplex_iterator operator++\n";} + ++this->position; + return (*this); + } + Filtration_simplex_iterator operator++(int) + { + Filtration_simplex_iterator result = *this; + ++(*this); + return result; + } + Filtration_simplex_iterator operator =( const Filtration_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "Filtration_simplex_iterator operator =\n";} + this->b = rhs.b; + this->position = rhs.position; + } + bool operator == ( const Filtration_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n";} + if ( this->position == rhs.position ) + { + return true; + } + return false; + } + + bool operator != ( const Filtration_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n";} + return !(*this == rhs); + } + Simplex_handle operator*() + { + if ( globalDbg ){cerr << "Simplex_handle operator*()\n";} + return Simplex_handle( this->b , this->b->elements_ordered_according_to_filtration[ this->position ] ); + } + + friend class Filtration_simplex_range; + private: + Bitmap_cubical_complex* b; + size_t position; + }; + + + /** + * Filtration_simplex_range provides the ranges for Filtration_simplex_iterator. + **/ + class Filtration_simplex_range + { + //Range over the simplices of the complex in the order of the filtration. + //.begin() and .end() return type Filtration_simplex_iterator. + public: + Filtration_simplex_range(Bitmap_cubical_complex* b):b(b){}; + Filtration_simplex_iterator begin() + { + if ( globalDbg ){cerr << "Filtration_simplex_iterator begin() \n";} + return Filtration_simplex_iterator( this->b ); + } + Filtration_simplex_iterator end() + { + if ( globalDbg ){cerr << "Filtration_simplex_iterator end()\n";} + Filtration_simplex_iterator it( this->b ); + it.position = this->b->elements_ordered_according_to_filtration.size(); + return it; + } + private: + Bitmap_cubical_complex* b; + }; + + + +//*********************************************// +//Methods to access iterators from the container: + /** + * boundary_simplex_range creates an object of a Boundary_simplex_range class + * that provides ranges for the Boundary_simplex_iterator. + **/ + Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh) + { + if ( globalDbg ){cerr << "Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh)\n";} + //Returns a range giving access to all simplices of the boundary of a simplex, + //i.e. the set of codimension 1 subsimplices of the Simplex. + return Boundary_simplex_range(sh); + } + + /** + * filtration_simplex_range creates an object of a Filtration_simplex_range class + * that provides ranges for the Filtration_simplex_iterator. + **/ + Filtration_simplex_range filtration_simplex_range() + { + if ( globalDbg ){cerr << "Filtration_simplex_range filtration_simplex_range()\n";} + //Returns a range over the simplices of the complex in the order of the filtration + return Filtration_simplex_range(this); + } +//*********************************************// + + + +//*********************************************// +//Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are there. + //TODO -- the file IndexingTag.h in the Gudhi library contains an empty structure, so + //I understand that this is something that was planned (for simplicial maps?) + //but was never finished. The only idea I have here is to use the same empty structure from + //IndexingTag.h file, but only if the compiler needs it. If the compiler + //do not need it, then I would rather not add here elements which I do not understand. + //typedef Indexing_tag + /** + * Function needed for compatibility with Gudhi. Not useful for other purposes. + **/ + std::pair endpoints( Simplex_handle sh ) + { + std::vector< size_t > bdry = this->get_boundary_of_a_cell( sh.position ); + if ( globalDbg ) + { + cerr << "std::pair endpoints( Simplex_handle sh )\n"; + cerr << "bdry.size() : " << bdry.size() << endl; + } + //this method returns two first elements from the boundary of sh. + if ( bdry.size() < 2 ) + throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the boundary."); + return std::make_pair( Simplex_handle(this,bdry[0]) , Simplex_handle(this,bdry[1]) ); + } + + + /** + * Class needed for compatibility with Gudhi. Not useful for other purposes. + **/ + class Skeleton_simplex_range; + class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > + { + //Iterator over all simplices of the complex in the order of the indexing scheme. + //'value_type' must be 'Simplex_handle'. + public: + Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d ):b(b),dimension(d) + { + if ( globalDbg ){cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n";} + //find the position of the first simplex of a dimension d + this->position = 0; + while ( + (this->position != b->data.size()) && + ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) + ) + { + ++this->position; + } + }; + Skeleton_simplex_iterator ():b(NULL),dimension(0){}; + + Skeleton_simplex_iterator operator++() + { + if ( globalDbg ){cerr << "Skeleton_simplex_iterator operator++()\n";} + //increment the position as long as you did not get to the next element of the dimension dimension. + ++this->position; + while ( + (this->position != this->b->data.size()) && + ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) + ) + { + ++this->position; + } + return (*this); + } + Skeleton_simplex_iterator operator++(int) + { + Skeleton_simplex_iterator result = *this; + ++(*this); + return result; + } + Skeleton_simplex_iterator operator =( const Skeleton_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "Skeleton_simplex_iterator operator =\n";} + this->b = rhs.b; + this->position = rhs.position; + } + bool operator == ( const Skeleton_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator ==\n";} + if ( this->position == rhs.position ) + { + return true; + } + return false; + } + + bool operator != ( const Skeleton_simplex_iterator& rhs ) + { + if ( globalDbg ){cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n";} + return !(*this == rhs); + } + Simplex_handle operator*() + { + if ( globalDbg ){cerr << "Simplex_handle operator*() \n";} + return Simplex_handle( this->b , this->position ); + } + + friend class Skeleton_simplex_range; + private: + Bitmap_cubical_complex* b; + size_t position; + unsigned dimension; + }; + /** + * Class needed for compatibility with Gudhi. Not useful for other purposes. + **/ + class Skeleton_simplex_range + { + //Range over the simplices of the complex in the order of the filtration. + //.begin() and .end() return type Filtration_simplex_iterator. + public: + Skeleton_simplex_range(Bitmap_cubical_complex* b , unsigned dimension):b(b),dimension(dimension){}; + Skeleton_simplex_iterator begin() + { + if ( globalDbg ){cerr << "Skeleton_simplex_iterator begin()\n";} + return Skeleton_simplex_iterator( this->b , this->dimension ); + } + Skeleton_simplex_iterator end() + { + if ( globalDbg ){cerr << "Skeleton_simplex_iterator end()\n";} + Skeleton_simplex_iterator it( this->b , this->dimension ); + it.position = this->b->data.size(); + return it; + } + private: + Bitmap_cubical_complex* b; + unsigned dimension; + }; + + /** + * Function needed for compatibility with Gudhi. Not useful for other purposes. + **/ + Skeleton_simplex_range skeleton_simplex_range( unsigned dimension ) + { + if ( globalDbg ){cerr << "Skeleton_simplex_range skeleton_simplex_range( unsigned dimension )\n";} + return Skeleton_simplex_range( this , dimension ); + } + + + +//*********************************************// +//functions used for debugging: + /** + * Function used for debugging purposes. + **/ + //void printkey_associated_to_simplex() + //{ + // for ( size_t i = 0 ; i != this->data.size() ; ++i ) + // { + // cerr << i << " -> " << this->simplex_associated_to_key[i] << endl; + // } + //} + + /** + * Function used for debugging purposes. + **/ + size_t printRealPosition( const Simplex_handle& sh ) + { + return sh.position; + } + +private: + std::vector< size_t > key_associated_to_simplex; + std::vector< size_t > simplex_associated_to_key; + std::vector< size_t > elements_ordered_according_to_filtration; + //filed above is needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. +};//Bitmap_cubical_complex + +template +bool compare_elements_for_elements_ordered_according_to_filtration +( const std::pair< size_t , std::pair< T , char > >& f , const std::pair< size_t , std::pair< T , char > >& s ) +{ + if ( globalDbg ){cerr << "compare_elements_for_elements_ordered_according_to_filtration\n";} + if ( f.second.first < s.second.first ) + { + return true; + } + else + { + if ( f.second.first > s.second.first ) + { + return false; + } + else + { + //in this case f.second.first == s.second.first, and we use dimension to compare: + if ( f.second.second < s.second.second ) + { + return true; + } + else + { + if ( f.second.second > s.second.second ) + { + return false; + } + else + { + //in this case, both the filtration value and the dimensions for those cells are the same. + //Since it may be nice to have a stable sorting procedure, in this case, + //we compare positions in the bitmap: + return ( f.first < s.first ); + } + } + } + } +} + +template +void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() +{ + if ( globalDbg ) + { + cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; + } + //( position , (filtration , dimension) ) + std::vector< std::pair< size_t , std::pair< T , char > > > data_of_elements_from_bitmap( this->data.size() ); + for ( size_t i = 0 ; i != this->data.size() ; ++i ) + { + //TODO -- this can be optimized by having a counter here. + //We do not need to re-compute the dimension for every cell from scratch + data_of_elements_from_bitmap[i] = + std::make_pair( i , std::make_pair( this->data[i] , this->get_dimension_of_a_cell(i) ) ); + } + std::sort( data_of_elements_from_bitmap.begin() , + data_of_elements_from_bitmap.end() , + compare_elements_for_elements_ordered_according_to_filtration ); + + std::vector< size_t > + elements_ordered_according_to_filtration_then_to_dimension_then_to_position + ( this->data.size() ); + for ( size_t i = 0 ; i != data_of_elements_from_bitmap.size() ; ++i ) + { + elements_ordered_according_to_filtration_then_to_dimension_then_to_position[i] + = data_of_elements_from_bitmap[i].first; + } + this->elements_ordered_according_to_filtration = + elements_ordered_according_to_filtration_then_to_dimension_then_to_position; +} + + +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// + + +} +} \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index d9c91832..2c2bd481 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -1,593 +1,759 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Sophia-Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef BITMAP_CUBICAL_COMPLEX_BASE_H_ -#define BITMAP_CUBICAL_COMPLEX_BASE_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * This is a class implementing a basic bitmap data structure to store cubical complexes. It implements only the most basic subroutines. - * The idea of the bitmap is the following. Our aim is to have a memory efficient data structure to store d-dimensional cubical complex C being a cubical decomposition - * of a rectangular region of a space. This is achieved by storing C as a vector of bits (this is where the name 'bitmap' came from). Each cell is represented by a single - * bit (in case of black and white bitmaps, or by a single element of a type T (here T is a filtration type of a bitmap, typically a double). All the informations needed for homology and - * persistent homology computations (like dimension of a cell, boundary and coboundary elements of a cell, are then obtained from the position of the element in C. - */ -template -class Bitmap_cubical_complex_base { - public: - /** - * There are a few constructors of a Bitmap_cubical_complex_base class. First one, that takes vector, creates an empty bitmap of a dimension equal to the number of elements in the - * input vector and size in the i-th dimension equal the number in the position i-of the input vector. - */ - Bitmap_cubical_complex_base(std::vector sizes_); - /** - * The second constructor takes as a input a Perseus style file. For more details, please consult the documentations of Perseus software as well as examples attached to this - * implementation. - **/ - Bitmap_cubical_complex_base(char* perseusStyleFile_); - /** - * The last constructor of a Bitmap_cubical_complex_base class accepts vector of dimensions (as the first one) together with vector of filtration values of top dimensional cells. - **/ - Bitmap_cubical_complex_base(std::vector dimensions_, std::vector topDimensionalCells_); - - /** - * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell and get_cell_data are the basic functions that compute boundary / coboundary / dimension and the filtration - * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a non-negative integer, indicating a position of a cube in the data structure. - * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to the positions of (co)boundary element of the input cell. - */ - inline std::vector< size_t > get_boundary_of_a_cell(size_t cell_); - /** - * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell and get_cell_data are the basic functions that compute boundary / coboundary / dimension and the filtration - * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a non-negative integer, indicating a position of a cube in the data structure. - * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to the positions of (co)boundary element of the input cell. - **/ - inline std::vector< size_t > get_coboundary_of_a_cell(size_t cell_); - /** - * In the case of get_dimension_of_a_cell function, the output is a non-negative integer indicating the dimension of a cell. - **/ - inline unsigned get_dimension_of_a_cell(size_t cell_); - /** - * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position. - **/ - inline T& get_cell_data(size_t cell_); - - - /** - * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. Then, there are a few ways one can pick the filtration of lower dimensional - * cells. The most typical one is by so called lower star filtration. This function is always called by any constructor which takes the top dimensional cells. If you use such a constructor, - * then there is no need to call this function. Call it only if you are putting the filtration of the cells by your own (for instance by using topDimensionalCellsIterator). - **/ - void impose_lower_star_filtration(); // assume that top dimensional cells are already set. - - /** - * Returns dimension of a complex. - **/ - inline unsigned dimension() { - return sizes.size(); - } - - /** - * Returns number of all cubes in the data structure. - **/ - inline unsigned size_of_bitmap() { - return this->data.size(); - } - - /** - * Writing to stream operator. - **/ - template - friend std::ostream& operator<<(std::ostream & os_, const Bitmap_cubical_complex_base& b_); - - // ITERATORS - - /** - * Iterator through all cells in the complex (in order they appear in the structure -- i.e. in lexicographical order). - **/ - typedef typename std::vector< T >::iterator all_cells_iterator; - - all_cells_iterator all_cells_begin()const { - return this->data.begin(); - } - - all_cells_iterator all_cells_end()const { - return this->data.end(); - } - - - typedef typename std::vector< T >::const_iterator all_cells_const_iterator; - - all_cells_const_iterator all_cells_const_begin()const { - return this->data.begin(); - } - - all_cells_const_iterator all_cells_const_end()const { - return this->data.end(); - } - - /** - * Iterator through top dimensional cells of the complex. The cells appear in order they are stored in the structure (i.e. in lexicographical order) - **/ - class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, double > { - public: - Top_dimensional_cells_iterator(Bitmap_cubical_complex_base& b_) : b(b_) { - for (size_t i = 0; i != b_.dimension(); ++i) { - this->counter.push_back(0); - } - } - - Top_dimensional_cells_iterator operator++() { - // first find first element of the counter that can be increased: - size_t dim = 0; - while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1))++dim; - - if (dim != this->b.dimension()) { - ++this->counter[dim]; - for (size_t i = 0; i != dim; ++i) { - this->counter[i] = 0; - } - } else { - ++this->counter[0]; - } - return *this; - } - - Top_dimensional_cells_iterator operator++(int) { - Top_dimensional_cells_iterator result = *this; - ++(*this); - return result; - } - - Top_dimensional_cells_iterator operator=(const Top_dimensional_cells_iterator& rhs_) { - this->counter = rhs_.counter; - this->b = rhs_.b; - return *this; - } - - bool operator==(const Top_dimensional_cells_iterator& rhs_) { - if (&this->b != &rhs_.b)return false; - if (this->counter.size() != rhs_.counter.size())return false; - for (size_t i = 0; i != this->counter.size(); ++i) { - if (this->counter[i] != rhs_.counter[i])return false; - } - return true; - } - - bool operator!=(const Top_dimensional_cells_iterator& rhs_) { - return !(*this == rhs_); - } - - T& operator*() { - // given the counter, compute the index in the array and return this element. - unsigned index = 0; - for (size_t i = 0; i != this->counter.size(); ++i) { - index += (2 * this->counter[i] + 1) * this->b.multipliers[i]; - } - return this->b.data[index]; - } - - size_t computeIndexInBitmap() { - size_t index = 0; - for (size_t i = 0; i != this->counter.size(); ++i) { - index += (2 * this->counter[i] + 1) * this->b.multipliers[i]; - } - return index; - } - - void printCounter() { - for (size_t i = 0; i != this->counter.size(); ++i) { - std::cout << this->counter[i] << " "; - } - } - friend class Bitmap_cubical_complex_base; - protected: - std::vector< unsigned > counter; - Bitmap_cubical_complex_base& b; - }; - - Top_dimensional_cells_iterator top_dimensional_cells_begin() { - Top_dimensional_cells_iterator a(*this); - return a; - } - - Top_dimensional_cells_iterator top_dimensional_cells_end() { - Top_dimensional_cells_iterator a(*this); - for (size_t i = 0; i != this->dimension(); ++i) { - a.counter[i] = this->sizes[i] - 1; - } - a.counter[0]++; - return a; - } - - - //****************************************************************************************************************// - //****************************************************************************************************************// - //****************************************************************************************************************// - //****************************************************************************************************************// - - - //****************************************************************************************************************// - //****************************************************************************************************************// - //****************************************************************************************************************// - //****************************************************************************************************************// - - protected: - std::vector sizes; - std::vector multipliers; - std::vector data; - size_t totalNumberOfCells; - - void set_up_containers(std::vector sizes_) { - unsigned multiplier = 1; - for (size_t i = 0; i != sizes_.size(); ++i) { - this->sizes.push_back(sizes_[i]); - this->multipliers.push_back(multiplier); - // multiplier *= 2*(sizes[i]+1)+1; - multiplier *= 2 * sizes_[i] + 1; - } - // std::reverse( this->sizes.begin() , this->sizes.end() ); - std::vector data(multiplier); - std::fill(data.begin(), data.end(), INT_MAX); - this->totalNumberOfCells = multiplier; - this->data = data; - } - - size_t compute_position_in_bitmap(std::vector< int > counter_) { - size_t position = 0; - for (size_t i = 0; i != this->multipliers.size(); ++i) { - position += this->multipliers[i] * counter_[i]; - } - return position; - } - - std::vector compute_counter_for_given_cell(size_t cell_) { - std::vector counter; - for (size_t dim = this->sizes.size(); dim != 0; --dim) { - counter.push_back(cell_ / this->multipliers[dim - 1]); - cell_ = cell_ % this->multipliers[dim - 1]; - } - std::reverse(counter.begin(), counter.end()); - return counter; - } - - std::vector< size_t > generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions(std::vector< bool > directionsForPeriodicBCond_); -}; - -template -std::ostream& operator<<(std::ostream & out_, const Bitmap_cubical_complex_base& b_) { - // for ( typename bitmap::all_cells_const_iterator it = b.all_cells_const_begin() ; - // it != b.all_cells_const_end() ; ++it ) - for (typename Bitmap_cubical_complex_base::all_cells_const_iterator it = b_.all_cells_const_begin(); - it != b_.all_cells_const_end(); ++it) { - out_ << *it << " "; - } - return out_; -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector sizes_) { - this->set_up_containers(sizes_); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(std::vector sizesInFollowingDirections_, - std::vector topDimensionalCells_) { - this->set_up_containers(sizesInFollowingDirections_); - - size_t numberOfTopDimensionalElements = 1; - for (size_t i = 0; i != sizesInFollowingDirections_.size(); ++i) { - numberOfTopDimensionalElements *= sizesInFollowingDirections_[i]; - } - if (numberOfTopDimensionalElements != topDimensionalCells_.size()) { - std::cerr << "Error in constructor Bitmap_cubical_complex_base( std::vector sizesInFollowingDirections_ , " - "std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from " - "sizesInFollowingDirections vector is different than the size of topDimensionalCells vector." << std::endl; - throw("Error in constructor Bitmap_cubical_complex_base( std::vector sizesInFollowingDirections_ , " - "std::vector topDimensionalCells_ ). Number of top dimensional elements that follow from " - "sizesInFollowingDirections vector is different than the size of topDimensionalCells vector."); - } - - Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - size_t index = 0; - for (it = this->top_dimensional_cells_begin(); it != this->top_dimensional_cells_end(); ++it) { - (*it) = topDimensionalCells_[index]; - ++index; - } - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(char* perseusStyleFile_) { - bool dbg = false; - std::ifstream inFiltration, inIds; - inFiltration.open(perseusStyleFile_); - unsigned dimensionOfData; - inFiltration >> dimensionOfData; - - if (dbg) { - std::cerr << "dimensionOfData : " << dimensionOfData << std::endl; - } - - std::vector sizes; - for (size_t i = 0; i != dimensionOfData; ++i) { - int sizeInThisDimension; - inFiltration >> sizeInThisDimension; - sizeInThisDimension = abs(sizeInThisDimension); - sizes.push_back(sizeInThisDimension); - if (dbg) { - std::cerr << "sizeInThisDimension : " << sizeInThisDimension << std::endl; - } - } - this->set_up_containers(sizes); - - Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - it = this->top_dimensional_cells_begin(); - - // TODO(Pawel Dlotko): Over here we also need to read id's of cell and put them to bitmapElement structure! - while (!inFiltration.eof()) { - double filtrationLevel; - inFiltration >> filtrationLevel; - if (dbg) { - std::cerr << "Cell of an index : " << it.computeIndexInBitmap() << " and dimension: " << - this->get_dimension_of_a_cell(it.computeIndexInBitmap()) << " get the value : " << - filtrationLevel << std::endl; - } - *it = filtrationLevel; - ++it; - } - inFiltration.close(); - this->impose_lower_star_filtration(); -} - -template -std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(size_t cell_) { - bool bdg = false; - // First of all, we need to take the list of coordinates in which the cell has nonzero length. - // We do it by using modified version to compute dimension of a cell: - std::vector< unsigned > dimensionsInWhichCellHasNonzeroLength; - unsigned dimension = 0; - size_t cell1 = cell_; - for (size_t i = this->multipliers.size(); i != 0; --i) { - unsigned position = cell1 / multipliers[i - 1]; - if (position % 2 == 1) { - dimensionsInWhichCellHasNonzeroLength.push_back(i - 1); - dimension++; - } - cell1 = cell1 % multipliers[i - 1]; - } - - if (bdg) { - std::cerr << "dimensionsInWhichCellHasNonzeroLength : \n"; - for (size_t i = 0; i != dimensionsInWhichCellHasNonzeroLength.size(); ++i) { - std::cerr << dimensionsInWhichCellHasNonzeroLength[i] << std::endl; - } - getchar(); - } - - std::vector< size_t > boundaryElements; - if (dimensionsInWhichCellHasNonzeroLength.size() == 0)return boundaryElements; - for (size_t i = 0; i != dimensionsInWhichCellHasNonzeroLength.size(); ++i) { - boundaryElements.push_back(cell_ - multipliers[ dimensionsInWhichCellHasNonzeroLength[i] ]); - boundaryElements.push_back(cell_ + multipliers[ dimensionsInWhichCellHasNonzeroLength[i] ]); - - if (bdg) std::cerr << "multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; - if (bdg) std::cerr << "cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << - cell_ - multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; - if (bdg) std::cerr << "cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] : " << - cell_ + multipliers[dimensionsInWhichCellHasNonzeroLength[i]] << std::endl; - } - return boundaryElements; -} - -template -std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(size_t cell_) { - bool bdg = false; - // First of all, we need to take the list of coordinates in which the cell has nonzero length. - // We do it by using modified version to compute dimension of a cell: - std::vector< unsigned > dimensionsInWhichCellHasZeroLength; - unsigned dimension = 0; - size_t cell1 = cell_; - for (size_t i = this->multipliers.size(); i != 0; --i) { - unsigned position = cell1 / multipliers[i - 1]; - if (position % 2 == 0) { - dimensionsInWhichCellHasZeroLength.push_back(i - 1); - dimension++; - } - cell1 = cell1 % multipliers[i - 1]; - } - - std::vector counter = this->compute_counter_for_given_cell(cell_); - // reverse(counter.begin() , counter.end()); - - if (bdg) { - std::cerr << "dimensionsInWhichCellHasZeroLength : \n"; - for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { - std::cerr << dimensionsInWhichCellHasZeroLength[i] << std::endl; - } - std::cerr << "\n counter : " << std::endl; - for (size_t i = 0; i != counter.size(); ++i) { - std::cerr << counter[i] << std::endl; - } - getchar(); - } - - std::vector< size_t > coboundaryElements; - if (dimensionsInWhichCellHasZeroLength.size() == 0)return coboundaryElements; - for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { - if (bdg) { - std::cerr << "Dimension : " << i << std::endl; - if (counter[dimensionsInWhichCellHasZeroLength[i]] == 0) { - std::cerr << "In dimension : " << i << - " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; - } - if (counter[dimensionsInWhichCellHasZeroLength[i]] == 2 * this->sizes[dimensionsInWhichCellHasZeroLength[i]]) { - std::cerr << "In dimension : " << i << - " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; - } - } - - - if ((cell_ > multipliers[dimensionsInWhichCellHasZeroLength[i]]) && - (counter[dimensionsInWhichCellHasZeroLength[i]] != 0)) { - // if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 0 ) - if (bdg)std::cerr << "Subtracting : " << cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]] << std::endl; - coboundaryElements.push_back(cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]]); - } - if ((cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] < this->data.size()) && - (counter[dimensionsInWhichCellHasZeroLength[i]] != 2 * this->sizes[dimensionsInWhichCellHasZeroLength[i]])) { - // if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 2*this->sizes[dimensionsInWhichCellHasZeroLength[i]] ) - coboundaryElements.push_back(cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]]); - if (bdg)std::cerr << "Adding : " << cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] << std::endl; - } - } - return coboundaryElements; -} - -template -unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell(size_t cell_) { - bool dbg = false; - if (dbg)std::cerr << "\n\n\n Computing position o a cell of an index : " << cell_ << std::endl; - unsigned dimension = 0; - for (size_t i = this->multipliers.size(); i != 0; --i) { - unsigned position = cell_ / multipliers[i - 1]; - - if (dbg)std::cerr << "i-1 :" << i - 1 << std::endl; - if (dbg)std::cerr << "cell_ : " << cell_ << std::endl; - if (dbg)std::cerr << "position : " << position << std::endl; - if (dbg)std::cerr << "multipliers[" << i - 1 << "] = " << multipliers[i - 1] << std::endl; - if (dbg)getchar(); - - if (position % 2 == 1) { - if (dbg)std::cerr << "Nonzero length in this direction \n"; - dimension++; - } - cell_ = cell_ % multipliers[i - 1]; - } - return dimension; -} - -template -T& Bitmap_cubical_complex_base::get_cell_data(size_t cell_) { - return this->data[cell_]; -} - -template -void Bitmap_cubical_complex_base::impose_lower_star_filtration() { - bool dbg = false; - - // this vector will be used to check which elements have already been taken care of in imposing lower star filtration: - std::vector isThisCellConsidered(this->data.size(), false); - - std::vector indicesToConsider; - // we assume here that we already have a filtration on the top dimensional cells - // and we have to extend it to lower ones. - typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - for (it = this->top_dimensional_cells_begin(); it != this->top_dimensional_cells_end(); ++it) { - indicesToConsider.push_back(it.computeIndexInBitmap()); - } - - while (indicesToConsider.size()) { - if (dbg) { - std::cerr << "indicesToConsider in this iteration \n"; - for (size_t i = 0; i != indicesToConsider.size(); ++i) { - std::cout << indicesToConsider[i] << " "; - } - getchar(); - } - std::vector newIndicesToConsider; - for (size_t i = 0; i != indicesToConsider.size(); ++i) { - std::vector bd = this->get_boundary_of_a_cell(indicesToConsider[i]); - for (size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) { - if (this->data[ bd[boundaryIt] ] > this->data[ indicesToConsider[i] ]) { - this->data[ bd[boundaryIt] ] = this->data[ indicesToConsider[i] ]; - } - if (isThisCellConsidered[ bd[boundaryIt] ] == false) { - newIndicesToConsider.push_back(bd[boundaryIt]); - isThisCellConsidered[ bd[boundaryIt] ] = true; - } - } - } - indicesToConsider.swap(newIndicesToConsider); - } -} - -template -std::vector< size_t > -Bitmap_cubical_complex_base::generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions(std::vector< bool > directionsForPeriodicBCond_) { - bool dbg = false; - if (this->sizes.size() != directionsForPeriodicBCond_.size()) - throw ("directionsForPeriodicBCond_ vector size is different from the size of the bitmap. " - "The program will now terminate \n"); - - std::vector sizes(this->sizes.size()); - for (size_t i = 0; i != this->sizes.size(); ++i)sizes[i] = 2 * this->sizes[i]; - - counter c(sizes); - - std::vector< size_t > result; - - for (size_t i = 0; i != this->data.size(); ++i) { - size_t position; - if (!c.isFinal()) { - position = i; - // result.push_back( i ); - } else { - std::vector< bool > finals = c.directionsOfFinals(); - bool jumpInPosition = false; - for (size_t dir = 0; dir != finals.size(); ++dir) { - if (finals[dir] == false)continue; - if (directionsForPeriodicBCond_[dir]) { - jumpInPosition = true; - } - } - if (jumpInPosition == true) { - // in this case this guy is final, so we need to find 'the opposite one' - position = compute_position_in_bitmap(c.findOpposite(directionsForPeriodicBCond_)); - } else { - position = i; - } - } - result.push_back(position); - if (dbg) { - std::cerr << " position : " << position << std::endl; - std::cerr << c << std::endl; - getchar(); - } - - c.increment(); - } - - return result; -} - -#endif // BITMAP_CUBICAL_COMPLEX_BASE_H_ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "counter.h" + + +using namespace std; + +namespace Gudhi +{ + +namespace Cubical_complex +{ + + + +/** + * This is a class implementing a basic bitmap data structure to store cubical complexes. + * It implements only the most basic subroutines. + * The idea of the bitmap is the following. Our aim is to have a memory efficient + * data structure to store d-dimensional cubical complex + * C being a cubical decomposition + * of a rectangular region of a space. This is achieved by storing C as a + * vector of bits (this is where the name 'bitmap' came from). + * Each cell is represented by a single + * bit (in case of black and white bitmaps, or by a single element of a type T + * (here T is a filtration type of a bitmap, typically a double). + * All the informations needed for homology and + * persistent homology computations (like dimension of a cell, boundary and + * coboundary elements of a cell, are then obtained from the + * position of the element in C. + * The default filtration used in this implementation is the lower star filtration. + */ +template +class Bitmap_cubical_complex_base +{ +public: + /** + * There are a few constructors of a Bitmap_cubical_complex_base class. + * First one, that takes vector, creates an empty bitmap of a dimension equal + * the number of elements in the + * input vector and size in the i-th dimension equal the number in the position i-of the input vector. + */ + Bitmap_cubical_complex_base( std::vector& sizes ); + /** + * The second constructor takes as a input a Perseus style file. For more details, + * please consult the documentations of + * Perseus software as well as examples attached to this + * implementation. + **/ + Bitmap_cubical_complex_base( const char* perseus_style_file ); + /** + * The last constructor of a Bitmap_cubical_complex_base class accepts vector of dimensions (as the first one) + * together with vector of filtration values of top dimensional cells. + **/ + Bitmap_cubical_complex_base( std::vector& dimensions , const std::vector& top_dimensional_cells ); + + /** + * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell + * and get_cell_data are the basic + * functions that compute boundary / coboundary / dimension and the filtration + * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a + * non-negative integer, indicating a position of a cube in the data structure. + * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to + * the positions of (co)boundary element of the input cell. + */ + inline std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; + /** + * The functions get_coboundary_of_a_cell, get_coboundary_of_a_cell, + * get_dimension_of_a_cell and get_cell_data are the basic + * functions that compute boundary / coboundary / dimension and the filtration + * value form a position of a cell in the structure of a bitmap. + * The input parameter of all of those function is a non-negative integer, + * indicating a position of a cube in the data structure. + * In the case of functions that compute (co)boundary, the output is a vector if + * non-negative integers pointing to the + * positions of (co)boundary element of the input cell. + **/ + inline std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; + /** + * In the case of get_dimension_of_a_cell function, the output is a non-negative integer + * indicating the dimension of a cell. + **/ + inline unsigned get_dimension_of_a_cell( size_t cell )const; + /** + * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position. + **/ + inline T& get_cell_data( size_t cell ); + + + /** + * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. + * Then, there are a few ways one can pick the filtration of lower dimensional + * cells. The most typical one is by so called lower star filtration. This function is always called by any + * constructor which takes the top dimensional cells. If you use such a constructor, + * then there is no need to call this function. Call it only if you are putting the filtration + * of the cells by your own (for instance by using Top_dimensional_cells_iterator). + **/ + void impose_lower_star_filtration();//assume that top dimensional cells are already set. + + /** + * Returns dimension of a complex. + **/ + inline unsigned dimension()const{ return sizes.size(); } + + /** + * Returns number of all cubes in the data structure. + **/ + inline unsigned size_of_bitmap()const + { + return this->data.size(); + } + + /** + * Writing to stream operator. + **/ + template + friend ostream& operator << ( ostream & os , const Bitmap_cubical_complex_base& b ); + + //ITERATORS + + /** + * Iterator through all cells in the complex (in order they appear in the structure -- i.e. + * in lexicographical order). + **/ + typedef typename std::vector< T >::iterator all_cells_iterator; + all_cells_iterator all_cells_begin()const + { + return this->data.begin(); + } + all_cells_iterator all_cells_end()const + { + return this->data.end(); + } + + + typedef typename std::vector< T >::const_iterator all_cells_const_iterator; + all_cells_const_iterator all_cells_const_begin()const + { + return this->data.begin(); + } + all_cells_const_iterator all_cells_const_end()const + { + return this->data.end(); + } + + /** + * Iterator through top dimensional cells of the complex. The cells appear in order they are stored + * in the structure (i.e. in lexicographical order) + **/ + class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, double > + { + public: + Top_dimensional_cells_iterator( Bitmap_cubical_complex_base& b ):b(b) + { + for ( size_t i = 0 ; i != b.dimension() ; ++i ) + { + this->counter.push_back(0); + } + } + Top_dimensional_cells_iterator operator++() + { + //first find first element of the counter that can be increased: + size_t dim = 0; + while ( ( dim != this->b.dimension() ) && ( this->counter[dim] == this->b.sizes[dim]-1 ) )++dim; + + if ( dim != this->b.dimension() ) + { + ++this->counter[dim]; + for ( size_t i = 0 ; i != dim ; ++i ) + { + this->counter[i] = 0; + } + } + else + { + ++this->counter[0]; + } + return *this; + } + Top_dimensional_cells_iterator operator++(int) + { + Top_dimensional_cells_iterator result = *this; + ++(*this); + return result; + } + Top_dimensional_cells_iterator operator =( const Top_dimensional_cells_iterator& rhs ) + { + this->counter = rhs.counter; + this->b = rhs.b; + return *this; + } + bool operator == ( const Top_dimensional_cells_iterator& rhs )const + { + if ( &this->b != &rhs.b )return false; + if ( this->counter.size() != rhs.counter.size() )return false; + for ( size_t i = 0 ; i != this->counter.size() ; ++i ) + { + if ( this->counter[i] != rhs.counter[i] )return false; + } + return true; + } + bool operator != ( const Top_dimensional_cells_iterator& rhs )const + { + return !(*this == rhs); + } + + T& operator*() + { + //given the counter, compute the index in the array and return this element. + unsigned index = 0; + for ( size_t i = 0 ; i != this->counter.size() ; ++i ) + { + index += (2*this->counter[i]+1)*this->b.multipliers[i]; + } + return this->b.data[index]; + } + + size_t compute_index_in_bitmap()const + { + size_t index = 0; + for ( size_t i = 0 ; i != this->counter.size() ; ++i ) + { + index += (2*this->counter[i]+1)*this->b.multipliers[i]; + } + return index; + } + + void print_counter()const + { + for ( size_t i = 0 ; i != this->counter.size() ; ++i ) + { + cout << this->counter[i] << " "; + } + } + friend class Bitmap_cubical_complex_base; + protected: + std::vector< unsigned > counter; + Bitmap_cubical_complex_base& b; + }; + Top_dimensional_cells_iterator top_dimensional_cells_begin() + { + Top_dimensional_cells_iterator a(*this); + return a; + } + Top_dimensional_cells_iterator top_dimensional_cells_end() + { + Top_dimensional_cells_iterator a(*this); + for ( size_t i = 0 ; i != this->dimension() ; ++i ) + { + a.counter[i] = this->sizes[i]-1; + } + a.counter[0]++; + return a; + } + + +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// + + +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// + +protected: + std::vector sizes; + std::vector multipliers; + std::vector data; + size_t total_number_of_cells; + void set_up_containers( std::vector& sizes ) + { + unsigned multiplier = 1; + for ( size_t i = 0 ; i != sizes.size() ; ++i ) + { + this->sizes.push_back(sizes[i]); + this->multipliers.push_back(multiplier); + //multiplier *= 2*(sizes[i]+1)+1; + multiplier *= 2*sizes[i]+1; + } + //std::reverse( this->sizes.begin() , this->sizes.end() ); + std::vector data(multiplier); + std::fill( data.begin() , data.end() , std::numeric_limits::max() ); + this->total_number_of_cells = multiplier; + this->data = data; + } + + size_t compute_position_in_bitmap( std::vector< unsigned >& counter ) + { + size_t position = 0; + for ( size_t i = 0 ; i != this->multipliers.size() ; ++i ) + { + position += this->multipliers[i]*counter[i]; + } + return position; + } + + std::vector compute_counter_for_given_cell( size_t cell )const + { + std::vector counter; + for ( size_t dim = this->sizes.size() ; dim != 0 ; --dim ) + { + counter.push_back(cell/this->multipliers[dim-1]); + cell = cell%this->multipliers[dim-1]; + } + std::reverse( counter.begin() , counter.end() ); + return counter; + } + + std::vector< size_t > + generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions + ( std::vector< bool >& directions_for_periodic_b_cond ); +}; + + + + +template +ostream& operator << ( ostream & out , const Bitmap_cubical_complex_base& b ) +{ + for ( typename Bitmap_cubical_complex_base::all_cells_const_iterator + it = b.all_cells_const_begin() ; it != b.all_cells_const_end() ; ++it ) + { + out << *it << " "; + } + return out; +} + + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base +( std::vector& sizes ) +{ + this->set_up_containers( sizes ); +} + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base +( std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells ) +{ + this->set_up_containers( sizes_in_following_directions ); + + size_t number_of_top_dimensional_elements = 1; + for ( size_t i = 0 ; i != sizes_in_following_directions.size() ; ++i ) + { + number_of_top_dimensional_elements *= sizes_in_following_directions[i]; + } + if ( number_of_top_dimensional_elements != top_dimensional_cells.size() ) + { + cerr << + "Error in constructor\ + Bitmap_cubical_complex_base\ + ( std::vector sizes_in_following_directions , std::vector top_dimensional_cells ).\ + Number of top dimensional elements that follow from sizes_in_following_directions vector is different\ + than the size of top_dimensional_cells vector." << endl; + throw("Error in constructor Bitmap_cubical_complex_base( std::vector sizes_in_following_directions,\ + std::vector top_dimensional_cells )\ + . Number of top dimensional elements that follow from sizes_in_following_directions vector is different than the\ + size of top_dimensional_cells vector."); + } + + Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + size_t index = 0; + for ( it = this->top_dimensional_cells_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + { + (*it) = top_dimensional_cells[index]; + ++index; + } + this->impose_lower_star_filtration(); +} + + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file ) +{ + bool dbg = false; + ifstream inFiltration, inIds; + inFiltration.open( perseus_style_file ); + unsigned dimensionOfData; + inFiltration >> dimensionOfData; + + if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;} + + std::vector sizes; + for ( size_t i = 0 ; i != dimensionOfData ; ++i ) + { + unsigned size_in_this_dimension; + inFiltration >> size_in_this_dimension; + size_in_this_dimension = abs(size_in_this_dimension); + sizes.push_back( size_in_this_dimension ); + if (dbg){cerr << "size_in_this_dimension : " << size_in_this_dimension << endl;} + } + this->set_up_containers( sizes ); + + Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + it = this->top_dimensional_cells_begin(); + + //TODO -- over here we also need to read id's of cell and put them to bitmapElement structure! + while ( !inFiltration.eof() ) + { + double filtrationLevel; + inFiltration >> filtrationLevel; + if ( dbg ) + { + cerr << "Cell of an index : " + << it.compute_index_in_bitmap() + << " and dimension: " + << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) + << " get the value : " << filtrationLevel << endl; + } + *it = filtrationLevel; + ++it; + } + inFiltration.close(); + this->impose_lower_star_filtration(); +} + + +template +std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( size_t cell )const +{ + bool bdg = false; + //first of all, we need to take the list of coordinates in which the cell has nonzero length. + //We do it by using modified version to compute dimension of a cell: + std::vector< unsigned > dimensions_in_which_cell_has_nonzero_length; + unsigned dimension = 0; + size_t cell1 = cell; + for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) + { + unsigned position = cell1/multipliers[i-1]; + if ( position%2 == 1 ) + { + dimensions_in_which_cell_has_nonzero_length.push_back(i-1); + dimension++; + } + cell1 = cell1%multipliers[i-1]; + } + + if (bdg) + { + cerr << "dimensions_in_which_cell_has_nonzero_length : \n"; + for ( size_t i = 0 ; i != dimensions_in_which_cell_has_nonzero_length.size() ; ++i ) + { + cerr << dimensions_in_which_cell_has_nonzero_length[i] << endl; + } + getchar(); + } + + std::vector< size_t > boundary_elements; + if ( dimensions_in_which_cell_has_nonzero_length.size() == 0 )return boundary_elements; + for ( size_t i = 0 ; i != dimensions_in_which_cell_has_nonzero_length.size() ; ++i ) + { + boundary_elements.push_back( cell - multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); + boundary_elements.push_back( cell + multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); + + if (bdg) cerr << "multipliers[dimensions_in_which_cell_has_nonzero_length[i]] : " + << multipliers[dimensions_in_which_cell_has_nonzero_length[i]] << endl; + if (bdg) cerr << "cell - multipliers[dimensions_in_which_cell_has_nonzero_length[i]] : " + << cell - multipliers[dimensions_in_which_cell_has_nonzero_length[i]] << endl; + if (bdg) cerr << "cell + multipliers[dimensions_in_which_cell_has_nonzero_length[i]] : " + << cell + multipliers[dimensions_in_which_cell_has_nonzero_length[i]] << endl; + } + return boundary_elements; +} + + + + +template +std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( size_t cell )const +{ + bool bdg = false; + //first of all, we need to take the list of coordinates in which the cell has nonzero length. + //We do it by using modified version to compute dimension of a cell: + std::vector< unsigned > dimensions_in_which_cell_has_zero_length; + unsigned dimension = 0; + size_t cell1 = cell; + for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) + { + unsigned position = cell1/multipliers[i-1]; + if ( position%2 == 0 ) + { + dimensions_in_which_cell_has_zero_length.push_back(i-1); + dimension++; + } + cell1 = cell1%multipliers[i-1]; + } + + std::vector counter = this->compute_counter_for_given_cell( cell ); + //reverse(counter.begin() , counter.end()); + + if (bdg) + { + cerr << "dimensions_in_which_cell_has_zero_length : \n"; + for ( size_t i = 0 ; i != dimensions_in_which_cell_has_zero_length.size() ; ++i ) + { + cerr << dimensions_in_which_cell_has_zero_length[i] << endl; + } + cerr << "\n counter : " << endl; + for ( size_t i = 0 ; i != counter.size() ; ++i ) + { + cerr << counter[i] << endl; + } + getchar(); + } + + std::vector< size_t > coboundary_elements; + if ( dimensions_in_which_cell_has_zero_length.size() == 0 )return coboundary_elements; + for ( size_t i = 0 ; i != dimensions_in_which_cell_has_zero_length.size() ; ++i ) + { + if ( bdg ) + { + cerr << "Dimension : " << i << endl; + if (counter[dimensions_in_which_cell_has_zero_length[i]] == 0) + { + cerr << "In dimension : " << i + << " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; + } + if ( counter[dimensions_in_which_cell_has_zero_length[i]] + == + 2*this->sizes[dimensions_in_which_cell_has_zero_length[i]] ) + { + cerr << "In dimension : " << i + << " we cannot substract, since we will jump out of a Bitmap_cubical_complex_base \n"; + } + } + + + if ( (cell > multipliers[dimensions_in_which_cell_has_zero_length[i]]) + && (counter[dimensions_in_which_cell_has_zero_length[i]] != 0) ) + //if ( counter[dimensions_in_which_cell_has_zero_length[i]] != 0 ) + { + if ( bdg ) + { + cerr << "Subtracting : " << cell - multipliers[dimensions_in_which_cell_has_zero_length[i]] << endl; + } + coboundary_elements.push_back( cell - multipliers[dimensions_in_which_cell_has_zero_length[i]] ); + } + if ( + (cell + multipliers[dimensions_in_which_cell_has_zero_length[i]] < this->data.size()) && + (counter[dimensions_in_which_cell_has_zero_length[i]] + != + 2*this->sizes[dimensions_in_which_cell_has_zero_length[i]]) + ) + //if ( counter[dimensions_in_which_cell_has_zero_length[i]] != + //2*this->sizes[dimensions_in_which_cell_has_zero_length[i]] ) + { + coboundary_elements.push_back( cell + multipliers[dimensions_in_which_cell_has_zero_length[i]] ); + if ( bdg )cerr << "Adding : " << cell + multipliers[dimensions_in_which_cell_has_zero_length[i]] << endl; + } + } + return coboundary_elements; +} + + + + + + +template +unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell( size_t cell )const +{ + bool dbg = false; + if (dbg)cerr << "\n\n\n Computing position o a cell of an index : " << cell << endl; + unsigned dimension = 0; + for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) + { + unsigned position = cell/multipliers[i-1]; + + if (dbg)cerr << "i-1 :" << i-1 << endl; + if (dbg)cerr << "cell : " << cell << endl; + if (dbg)cerr << "position : " << position << endl; + if (dbg)cerr << "multipliers["< +T& Bitmap_cubical_complex_base::get_cell_data( size_t cell ) +{ + return this->data[cell]; +} + + +template +void Bitmap_cubical_complex_base::impose_lower_star_filtration() +{ + bool dbg = false; + + //this vector will be used to check which elements have already been taken care of + //in imposing lower star filtration: + std::vector is_this_cell_considered( this->data.size() , false ); + + std::vector indices_to_consider; + //we assume here that we already have a filtration on the top dimensional cells and + //we have to extend it to lower ones. + typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + for ( it = this->top_dimensional_cells_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + { + indices_to_consider.push_back( it.compute_index_in_bitmap() ); + } + + while ( indices_to_consider.size() ) + { + if ( dbg ) + { + cerr << "indices_to_consider in this iteration \n"; + for ( size_t i = 0 ; i != indices_to_consider.size() ; ++i ) + { + cout << indices_to_consider[i] << " "; + } + getchar(); + } + std::vector new_indices_to_consider; + for ( size_t i = 0 ; i != indices_to_consider.size() ; ++i ) + { + std::vector bd = this->get_boundary_of_a_cell( indices_to_consider[i] ); + for ( size_t boundaryIt = 0 ; boundaryIt != bd.size() ; ++boundaryIt ) + { + if ( this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ] ) + { + this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; + } + if ( is_this_cell_considered[ bd[boundaryIt] ] == false ) + { + new_indices_to_consider.push_back( bd[boundaryIt] ); + is_this_cell_considered[ bd[boundaryIt] ] = true; + } + } + } + indices_to_consider.swap(new_indices_to_consider); + } +} + + +template +bool compareFirstElementsOfTuples( const std::pair< std::pair< T , size_t > , char >& first , + const std::pair< std::pair< T , size_t > , char >& second ) +{ + if ( first.first.first < second.first.first ) + { + return true; + } + else + { + if ( first.first.first > second.first.first ) + { + return false; + } + //in this case first.first.first == second.first.first, so we need to compare dimensions + return first.second < second.second; + } +} + + + +template +std::vector< size_t > Bitmap_cubical_complex_base:: +generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions +( std::vector< bool >& directions_for_periodic_b_cond ) +{ + bool dbg = false; + if ( this->sizes.size() != directions_for_periodic_b_cond.size() ) + throw "directions_for_periodic_b_cond vector size is different from the size of the bitmap. Program terminate \n"; + + std::vector sizes( this->sizes.size() ); + for ( size_t i = 0 ; i != this->sizes.size() ; ++i )sizes[i] = 2*this->sizes[i]; + + counter c( sizes ); + + std::vector< size_t > result; + + for ( size_t i = 0 ; i != this->data.size() ; ++i ) + { + size_t position; + if ( !c.isFinal() ) + { + position = i; + //result.push_back( i ); + } + else + { + std::vector< bool > finals = c.directions_of_finals(); + bool jump_in_position = false; + for ( size_t dir = 0 ; dir != finals.size() ; ++dir ) + { + if ( finals[dir] == false )continue; + if ( directions_for_periodic_b_cond[dir] ) + { + jump_in_position = true; + } + } + if ( jump_in_position == true ) + { + //in this case this guy is final, so we need to find 'the opposite one' + position = compute_position_in_bitmap( c.find_opposite( directions_for_periodic_b_cond ) ); + } + else + { + position = i; + } + } + result.push_back( position ); + if ( dbg ) + { + cerr << " position : " << position << endl; + cerr << c << endl; + getchar(); + } + + c.increment(); + } + + return result; +} + +} + +} \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/include/gudhi/counter.h b/src/Bitmap_cubical_complex/include/gudhi/counter.h index 9445a422..a5fda36f 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/counter.h +++ b/src/Bitmap_cubical_complex/include/gudhi/counter.h @@ -1,139 +1,177 @@ -/* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Sophia-Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef COUNTER_H_ -#define COUNTER_H_ - -#include -#include - -/** - * This is an implementation of a simple counter. It is needed for the implementation of a bitmapCubicalComplex. - **/ - -class counter { - public: - /** - * Constructor of a counter class. It takes only the parameter which is the end value of the counter. - * The default beginning value is a vector of the same length as the end, filled-in with zeros. - **/ - counter(std::vector< int > endd) { - for (size_t i = 0; i != endd.size(); ++i) { - this->current.push_back(0); - this->begin.push_back(0); - this->end.push_back(endd[i]); - } - } - - /** - * Constructor of a counter class. It takes as the input beginn and endd vector. It assumes that begin vector is - * lexicographically below the end vector. - **/ - counter(std::vector< int > beginn, std::vector< int > endd) { - if (beginn.size() != endd.size()) - throw("In constructor of a counter, begin and end vectors do not have the same size. Program terminate"); - for (size_t i = 0; i != endd.size(); ++i) { - this->current.push_back(0); - this->begin.push_back(0); - this->end.push_back(endd[i]); - } - } - - /** - * Function to increment the counter. If the value returned by the function is true, then the incrementation process - * was successful. - * If the value of the function is false, that means, that the counter have reached its end-value. - **/ - bool increment() { - size_t i = 0; - while ((i != this->end.size()) && (this->current[i] == this->end[i])) { - ++i; - } - - if (i == this->end.size())return false; - ++this->current[i]; - for (size_t j = 0; j != i; ++j) { - this->current[j] = this->begin[j]; - } - return true; - } - - /** - * Function to check if we are at the end of counter. - **/ - bool isFinal() { - for (size_t i = 0; i != this->current.size(); ++i) { - if (this->current[i] == this->end[i])return true; - } - return false; - } - - /** - * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. - * Its aim is to find an counter corresponding to the element the following boundary element is identified with - * when periodic boundary conditions are imposed. - **/ - std::vector< int > findOpposite(std::vector< bool > directionsForPeriodicBCond) { - std::vector< int > result; - for (size_t i = 0; i != this->current.size(); ++i) { - if ((this->current[i] == this->end[i]) && (directionsForPeriodicBCond[i] == true)) { - result.push_back(this->begin[i]); - } else { - result.push_back(this->current[i]); - } - } - return result; - } - - /** - * Function checking at which positions the current value of a counter is the final value of the counter. - **/ - std::vector< bool > directionsOfFinals() { - std::vector< bool > result; - for (size_t i = 0; i != this->current.size(); ++i) { - if (this->current[i] == this->end[i]) { - result.push_back(true); - } else { - result.push_back(false); - } - } - return result; - } - - /** - * Function to write counter to the stream. - **/ - friend std::ostream& operator<<(std::ostream& out, const counter& c) { - // std::cerr << "c.current.size() : " << c.current.size() << std::endl; - for (size_t i = 0; i != c.current.size(); ++i) { - out << c.current[i] << " "; - } - return out; - } - - private: - std::vector< int > begin; - std::vector< int > end; - std::vector< int > current; -}; - -#endif // COUNTER_H_ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +using namespace std; + +namespace Gudhi +{ + +namespace Cubical_complex +{ + +/** +* This is an implementation of a counter being a vector of integers. +* The constructor of the class takes as an input two vectors W and V. +* It assumes that W < V coordinatewise. +* If the initial counter W is not specified, it is assumed to be vector of zeros. +* The class allows to iterate between W and V by using increment() function. +* The increment() function returns a bool value. +* The current counter reach the end counter V if the value returned by the increment function is FALSE. +* This class is needed for the implementation of a bitmapCubicalComplex. +**/ + +class counter +{ +public: + /** + * Constructor of a counter class. It takes only the parameter which is the end value of the counter. + * The default beginning value is a vector of the same length as the endd, filled-in with zeros. + **/ + counter(std::vector const& endd): begin(endd.size(),0), end(endd), current(endd.size(),0){} + //counter(std::vector< int >& endd) + //{ + // for ( size_t i = 0 ; i != endd.size() ; ++i ) + // { + // this->current.push_back(0); + // this->begin.push_back(0); + // this->end.push_back( endd[i] ); + // } + //} + + + /** + * Constructor of a counter class. It takes as the input beginn and end vector. + * It assumes that begin vector is lexicographically below the end vector. + **/ + counter(std::vector< unsigned >& beginn , std::vector< unsigned >& endd) + { + if ( beginn.size() != endd.size() ) + throw "In constructor of a counter, begin and end vectors do not have the same size. Program terminate"; + for ( size_t i = 0 ; i != endd.size() ; ++i ) + { + this->current.push_back(0); + this->begin.push_back(0); + this->end.push_back( endd[i] ); + } + } + + /** + * Function to increment the counter. If the value returned by the function is true, + * then the incrementation process was successful. + * If the value of the function is false, that means, that the counter have reached its end-value. + **/ + bool increment() + { + size_t i = 0; + while( (i != this->end.size()) && (this->current[i] == this->end[i]) ) + { + ++i; + } + + if ( i == this->end.size() )return false; + ++this->current[i]; + for ( size_t j = 0 ; j != i ; ++j ) + { + this->current[j] = this->begin[j]; + } + return true; + } + + /** + * Function to check if we are at the end of counter. + **/ + bool isFinal() + { + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( this->current[i] == this->end[i] )return true; + } + return false; + } + + /** + * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. + * Its aim is to find an counter corresponding to the element the following + * boundary element is identified with when periodic boundary conditions are imposed. + **/ + std::vector< unsigned > find_opposite( std::vector< bool >& directionsForPeriodicBCond ) + { + std::vector< unsigned > result; + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( (this->current[i] == this->end[i]) && (directionsForPeriodicBCond[i] == true) ) + { + result.push_back( this->begin[i] ); + } + else + { + result.push_back( this->current[i] ); + } + } + return result; + } + + /** + * Function checking at which positions the current value of a counter is the final value of the counter. + **/ + std::vector< bool > directions_of_finals() + { + std::vector< bool > result; + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( this->current[i] == this->end[i] ) + { + result.push_back( true ); + } + else + { + result.push_back( false ); + } + } + return result; + } + + /** + * Function to write counter to the stream. + **/ + friend std::ostream& operator<<(std::ostream& out , const counter& c ) + { + //cerr << "c.current.size() : " << c.current.size() << endl; + for ( size_t i = 0 ; i != c.current.size() ; ++i ) + { + out << c.current[i] << " "; + } + return out; + } +private: + std::vector< unsigned > begin; + std::vector< unsigned > end; + std::vector< unsigned > current; +}; + +} +} \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index 1c204bae..183b856a 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -1,623 +1,638 @@ -#include "gudhi/Bitmap_cubical_complex.h" - -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE "cubical_complex" -#include - -using namespace std; - -BOOST_AUTO_TEST_CASE(check_dimension) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - BOOST_CHECK(increasing.dimension() == 2); -} - -BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { - std::vector< double > expectedFiltrationValues1; - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(100); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - - std::vector< double > expectedFiltrationValues2; - expectedFiltrationValues2.push_back(1); - expectedFiltrationValues2.push_back(2); - expectedFiltrationValues2.push_back(3); - expectedFiltrationValues2.push_back(4); - expectedFiltrationValues2.push_back(5); - expectedFiltrationValues2.push_back(6); - expectedFiltrationValues2.push_back(7); - expectedFiltrationValues2.push_back(8); - expectedFiltrationValues2.push_back(9); - - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector< double > oneDimensionalCycle; - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(100); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle); - - - int i = 0; - for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = increasing.top_dimensional_cells_begin(); it != increasing.top_dimensional_cells_end(); ++it) { - BOOST_CHECK(*it == expectedFiltrationValues2[i]); - ++i; - } - i = 0; - for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = hole.top_dimensional_cells_begin(); it != hole.top_dimensional_cells_end(); ++it) { - BOOST_CHECK(*it == expectedFiltrationValues1[i]); - ++i; - } -} - -BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { - - std::vector boundary0; - std::vector boundary1; - boundary1.push_back(0); - boundary1.push_back(2); - std::vector boundary2; - std::vector boundary3; - boundary3.push_back(2); - boundary3.push_back(4); - std::vector boundary4; - std::vector boundary5; - boundary5.push_back(4); - boundary5.push_back(6); - std::vector boundary6; - std::vector boundary7; - boundary7.push_back(0); - boundary7.push_back(14); - std::vector boundary8; - boundary8.push_back(1); - boundary8.push_back(15); - boundary8.push_back(7); - boundary8.push_back(9); - std::vector boundary9; - boundary9.push_back(2); - boundary9.push_back(16); - std::vector boundary10; - boundary10.push_back(3); - boundary10.push_back(17); - boundary10.push_back(9); - boundary10.push_back(11); - std::vector boundary11; - boundary11.push_back(4); - boundary11.push_back(18); - std::vector boundary12; - boundary12.push_back(5); - boundary12.push_back(19); - boundary12.push_back(11); - boundary12.push_back(13); - std::vector boundary13; - boundary13.push_back(6); - boundary13.push_back(20); - std::vector boundary14; - std::vector boundary15; - boundary15.push_back(14); - boundary15.push_back(16); - std::vector boundary16; - std::vector boundary17; - boundary17.push_back(16); - boundary17.push_back(18); - std::vector boundary18; - std::vector boundary19; - boundary19.push_back(18); - boundary19.push_back(20); - std::vector boundary20; - std::vector boundary21; - boundary21.push_back(14); - boundary21.push_back(28); - std::vector boundary22; - boundary22.push_back(15); - boundary22.push_back(29); - boundary22.push_back(21); - boundary22.push_back(23); - std::vector boundary23; - boundary23.push_back(16); - boundary23.push_back(30); - std::vector boundary24; - boundary24.push_back(17); - boundary24.push_back(31); - boundary24.push_back(23); - boundary24.push_back(25); - std::vector boundary25; - boundary25.push_back(18); - boundary25.push_back(32); - std::vector boundary26; - boundary26.push_back(19); - boundary26.push_back(33); - boundary26.push_back(25); - boundary26.push_back(27); - std::vector boundary27; - boundary27.push_back(20); - boundary27.push_back(34); - std::vector boundary28; - std::vector boundary29; - boundary29.push_back(28); - boundary29.push_back(30); - std::vector boundary30; - std::vector boundary31; - boundary31.push_back(30); - boundary31.push_back(32); - std::vector boundary32; - std::vector boundary33; - boundary33.push_back(32); - boundary33.push_back(34); - std::vector boundary34; - std::vector boundary35; - boundary35.push_back(28); - boundary35.push_back(42); - std::vector boundary36; - boundary36.push_back(29); - boundary36.push_back(43); - boundary36.push_back(35); - boundary36.push_back(37); - std::vector boundary37; - boundary37.push_back(30); - boundary37.push_back(44); - std::vector boundary38; - boundary38.push_back(31); - boundary38.push_back(45); - boundary38.push_back(37); - boundary38.push_back(39); - std::vector boundary39; - boundary39.push_back(32); - boundary39.push_back(46); - std::vector boundary40; - boundary40.push_back(33); - boundary40.push_back(47); - boundary40.push_back(39); - boundary40.push_back(41); - std::vector boundary41; - boundary41.push_back(34); - boundary41.push_back(48); - std::vector boundary42; - std::vector boundary43; - boundary43.push_back(42); - boundary43.push_back(44); - std::vector boundary44; - std::vector boundary45; - boundary45.push_back(44); - boundary45.push_back(46); - std::vector boundary46; - std::vector boundary47; - boundary47.push_back(46); - boundary47.push_back(48); - std::vector boundary48; - std::vector< std::vector > boundaries; - boundaries.push_back(boundary0); - boundaries.push_back(boundary1); - boundaries.push_back(boundary2); - boundaries.push_back(boundary3); - boundaries.push_back(boundary4); - boundaries.push_back(boundary5); - boundaries.push_back(boundary6); - boundaries.push_back(boundary7); - boundaries.push_back(boundary8); - boundaries.push_back(boundary9); - boundaries.push_back(boundary10); - boundaries.push_back(boundary11); - boundaries.push_back(boundary12); - boundaries.push_back(boundary13); - boundaries.push_back(boundary14); - boundaries.push_back(boundary15); - boundaries.push_back(boundary16); - boundaries.push_back(boundary17); - boundaries.push_back(boundary18); - boundaries.push_back(boundary19); - boundaries.push_back(boundary20); - boundaries.push_back(boundary21); - boundaries.push_back(boundary22); - boundaries.push_back(boundary23); - boundaries.push_back(boundary24); - boundaries.push_back(boundary25); - boundaries.push_back(boundary26); - boundaries.push_back(boundary27); - boundaries.push_back(boundary28); - boundaries.push_back(boundary29); - boundaries.push_back(boundary30); - boundaries.push_back(boundary31); - boundaries.push_back(boundary32); - boundaries.push_back(boundary33); - boundaries.push_back(boundary34); - boundaries.push_back(boundary35); - boundaries.push_back(boundary36); - boundaries.push_back(boundary37); - boundaries.push_back(boundary38); - boundaries.push_back(boundary39); - boundaries.push_back(boundary40); - boundaries.push_back(boundary41); - boundaries.push_back(boundary42); - boundaries.push_back(boundary43); - boundaries.push_back(boundary44); - boundaries.push_back(boundary45); - boundaries.push_back(boundary46); - boundaries.push_back(boundary47); - boundaries.push_back(boundary48); - - - - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { - std::vector< size_t > bd = increasing.get_boundary_of_a_cell(i); - for (size_t j = 0; j != bd.size(); ++j) { - BOOST_CHECK(boundaries[i][j] == bd[j]); - } - } -} - -BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - - - std::vector coboundaryElements; - coboundaryElements.push_back(7); - coboundaryElements.push_back(1); - coboundaryElements.push_back(8); - coboundaryElements.push_back(9); - coboundaryElements.push_back(1); - coboundaryElements.push_back(3); - coboundaryElements.push_back(10); - coboundaryElements.push_back(11); - coboundaryElements.push_back(3); - coboundaryElements.push_back(5); - coboundaryElements.push_back(12); - coboundaryElements.push_back(13); - coboundaryElements.push_back(5); - coboundaryElements.push_back(8); - coboundaryElements.push_back(8); - coboundaryElements.push_back(10); - coboundaryElements.push_back(10); - coboundaryElements.push_back(12); - coboundaryElements.push_back(12); - coboundaryElements.push_back(7); - coboundaryElements.push_back(21); - coboundaryElements.push_back(15); - coboundaryElements.push_back(8); - coboundaryElements.push_back(22); - coboundaryElements.push_back(9); - coboundaryElements.push_back(23); - coboundaryElements.push_back(15); - coboundaryElements.push_back(17); - coboundaryElements.push_back(10); - coboundaryElements.push_back(24); - coboundaryElements.push_back(11); - coboundaryElements.push_back(25); - coboundaryElements.push_back(17); - coboundaryElements.push_back(19); - coboundaryElements.push_back(12); - coboundaryElements.push_back(26); - coboundaryElements.push_back(13); - coboundaryElements.push_back(27); - coboundaryElements.push_back(19); - coboundaryElements.push_back(22); - coboundaryElements.push_back(22); - coboundaryElements.push_back(24); - coboundaryElements.push_back(24); - coboundaryElements.push_back(26); - coboundaryElements.push_back(26); - coboundaryElements.push_back(21); - coboundaryElements.push_back(35); - coboundaryElements.push_back(29); - coboundaryElements.push_back(22); - coboundaryElements.push_back(36); - coboundaryElements.push_back(23); - coboundaryElements.push_back(37); - coboundaryElements.push_back(29); - coboundaryElements.push_back(31); - coboundaryElements.push_back(24); - coboundaryElements.push_back(38); - coboundaryElements.push_back(25); - coboundaryElements.push_back(39); - coboundaryElements.push_back(31); - coboundaryElements.push_back(33); - coboundaryElements.push_back(26); - coboundaryElements.push_back(40); - coboundaryElements.push_back(27); - coboundaryElements.push_back(41); - coboundaryElements.push_back(33); - coboundaryElements.push_back(36); - coboundaryElements.push_back(36); - coboundaryElements.push_back(38); - coboundaryElements.push_back(38); - coboundaryElements.push_back(40); - coboundaryElements.push_back(40); - coboundaryElements.push_back(35); - coboundaryElements.push_back(43); - coboundaryElements.push_back(36); - coboundaryElements.push_back(37); - coboundaryElements.push_back(43); - coboundaryElements.push_back(45); - coboundaryElements.push_back(38); - coboundaryElements.push_back(39); - coboundaryElements.push_back(45); - coboundaryElements.push_back(47); - coboundaryElements.push_back(40); - coboundaryElements.push_back(41); - coboundaryElements.push_back(47); - size_t number = 0; - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { - std::vector< size_t > bd = increasing.get_coboundary_of_a_cell(i); - for (size_t j = 0; j != bd.size(); ++j) { - BOOST_CHECK(coboundaryElements[number] == bd[j]); - ++number; - } - - } -} - -BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - - std::vector dim; - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(2); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - dim.push_back(1); - dim.push_back(0); - - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { - BOOST_CHECK(increasing.get_dimension_of_a_cell(i) == dim[i]); - } -} - -BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - - std::vector< unsigned > dim; - dim.push_back(0); - dim.push_back(0); - dim.push_back(0); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - dim.push_back(0); - dim.push_back(1); - dim.push_back(1); - dim.push_back(2); - - std::vector fil; - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(1); - fil.push_back(2); - fil.push_back(2); - fil.push_back(2); - fil.push_back(2); - fil.push_back(2); - fil.push_back(2); - fil.push_back(3); - fil.push_back(3); - fil.push_back(3); - fil.push_back(3); - fil.push_back(3); - fil.push_back(3); - fil.push_back(4); - fil.push_back(4); - fil.push_back(4); - fil.push_back(4); - fil.push_back(4); - fil.push_back(4); - fil.push_back(5); - fil.push_back(5); - fil.push_back(5); - fil.push_back(5); - fil.push_back(6); - fil.push_back(6); - fil.push_back(6); - fil.push_back(6); - fil.push_back(7); - fil.push_back(7); - fil.push_back(7); - fil.push_back(7); - fil.push_back(7); - fil.push_back(7); - fil.push_back(8); - fil.push_back(8); - fil.push_back(8); - fil.push_back(8); - fil.push_back(9); - fil.push_back(9); - fil.push_back(9); - fil.push_back(9); - - - Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range(); - size_t position = 0; - for (Bitmap_cubical_complex::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) { - BOOST_CHECK(increasing.dimension(*it) == dim[position]); - BOOST_CHECK(increasing.filtration(*it) == fil[position]); - ++position; - } -} +#include +#include +#include +#include + +// standard stuff +#include +#include + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "cubical_complex" +#include + + +using namespace std; +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + + + +BOOST_AUTO_TEST_CASE(check_dimension) { + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + BOOST_CHECK(increasing.dimension() == 2); +} + +BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { + std::vector< double > expectedFiltrationValues1; + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(100); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + expectedFiltrationValues1.push_back(0); + + std::vector< double > expectedFiltrationValues2; + expectedFiltrationValues2.push_back(1); + expectedFiltrationValues2.push_back(2); + expectedFiltrationValues2.push_back(3); + expectedFiltrationValues2.push_back(4); + expectedFiltrationValues2.push_back(5); + expectedFiltrationValues2.push_back(6); + expectedFiltrationValues2.push_back(7); + expectedFiltrationValues2.push_back(8); + expectedFiltrationValues2.push_back(9); + + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector< double > oneDimensionalCycle; + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(100); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + oneDimensionalCycle.push_back(0); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle); + + + int i = 0; + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator + it = increasing.top_dimensional_cells_begin(); it != increasing.top_dimensional_cells_end(); ++it) { + BOOST_CHECK(*it == expectedFiltrationValues2[i]); + ++i; + } + i = 0; + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator + it = hole.top_dimensional_cells_begin(); it != hole.top_dimensional_cells_end(); ++it) { + BOOST_CHECK(*it == expectedFiltrationValues1[i]); + ++i; + } +} + +BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { + + std::vector boundary0; + std::vector boundary1; + boundary1.push_back(0); + boundary1.push_back(2); + std::vector boundary2; + std::vector boundary3; + boundary3.push_back(2); + boundary3.push_back(4); + std::vector boundary4; + std::vector boundary5; + boundary5.push_back(4); + boundary5.push_back(6); + std::vector boundary6; + std::vector boundary7; + boundary7.push_back(0); + boundary7.push_back(14); + std::vector boundary8; + boundary8.push_back(1); + boundary8.push_back(15); + boundary8.push_back(7); + boundary8.push_back(9); + std::vector boundary9; + boundary9.push_back(2); + boundary9.push_back(16); + std::vector boundary10; + boundary10.push_back(3); + boundary10.push_back(17); + boundary10.push_back(9); + boundary10.push_back(11); + std::vector boundary11; + boundary11.push_back(4); + boundary11.push_back(18); + std::vector boundary12; + boundary12.push_back(5); + boundary12.push_back(19); + boundary12.push_back(11); + boundary12.push_back(13); + std::vector boundary13; + boundary13.push_back(6); + boundary13.push_back(20); + std::vector boundary14; + std::vector boundary15; + boundary15.push_back(14); + boundary15.push_back(16); + std::vector boundary16; + std::vector boundary17; + boundary17.push_back(16); + boundary17.push_back(18); + std::vector boundary18; + std::vector boundary19; + boundary19.push_back(18); + boundary19.push_back(20); + std::vector boundary20; + std::vector boundary21; + boundary21.push_back(14); + boundary21.push_back(28); + std::vector boundary22; + boundary22.push_back(15); + boundary22.push_back(29); + boundary22.push_back(21); + boundary22.push_back(23); + std::vector boundary23; + boundary23.push_back(16); + boundary23.push_back(30); + std::vector boundary24; + boundary24.push_back(17); + boundary24.push_back(31); + boundary24.push_back(23); + boundary24.push_back(25); + std::vector boundary25; + boundary25.push_back(18); + boundary25.push_back(32); + std::vector boundary26; + boundary26.push_back(19); + boundary26.push_back(33); + boundary26.push_back(25); + boundary26.push_back(27); + std::vector boundary27; + boundary27.push_back(20); + boundary27.push_back(34); + std::vector boundary28; + std::vector boundary29; + boundary29.push_back(28); + boundary29.push_back(30); + std::vector boundary30; + std::vector boundary31; + boundary31.push_back(30); + boundary31.push_back(32); + std::vector boundary32; + std::vector boundary33; + boundary33.push_back(32); + boundary33.push_back(34); + std::vector boundary34; + std::vector boundary35; + boundary35.push_back(28); + boundary35.push_back(42); + std::vector boundary36; + boundary36.push_back(29); + boundary36.push_back(43); + boundary36.push_back(35); + boundary36.push_back(37); + std::vector boundary37; + boundary37.push_back(30); + boundary37.push_back(44); + std::vector boundary38; + boundary38.push_back(31); + boundary38.push_back(45); + boundary38.push_back(37); + boundary38.push_back(39); + std::vector boundary39; + boundary39.push_back(32); + boundary39.push_back(46); + std::vector boundary40; + boundary40.push_back(33); + boundary40.push_back(47); + boundary40.push_back(39); + boundary40.push_back(41); + std::vector boundary41; + boundary41.push_back(34); + boundary41.push_back(48); + std::vector boundary42; + std::vector boundary43; + boundary43.push_back(42); + boundary43.push_back(44); + std::vector boundary44; + std::vector boundary45; + boundary45.push_back(44); + boundary45.push_back(46); + std::vector boundary46; + std::vector boundary47; + boundary47.push_back(46); + boundary47.push_back(48); + std::vector boundary48; + std::vector< std::vector > boundaries; + boundaries.push_back(boundary0); + boundaries.push_back(boundary1); + boundaries.push_back(boundary2); + boundaries.push_back(boundary3); + boundaries.push_back(boundary4); + boundaries.push_back(boundary5); + boundaries.push_back(boundary6); + boundaries.push_back(boundary7); + boundaries.push_back(boundary8); + boundaries.push_back(boundary9); + boundaries.push_back(boundary10); + boundaries.push_back(boundary11); + boundaries.push_back(boundary12); + boundaries.push_back(boundary13); + boundaries.push_back(boundary14); + boundaries.push_back(boundary15); + boundaries.push_back(boundary16); + boundaries.push_back(boundary17); + boundaries.push_back(boundary18); + boundaries.push_back(boundary19); + boundaries.push_back(boundary20); + boundaries.push_back(boundary21); + boundaries.push_back(boundary22); + boundaries.push_back(boundary23); + boundaries.push_back(boundary24); + boundaries.push_back(boundary25); + boundaries.push_back(boundary26); + boundaries.push_back(boundary27); + boundaries.push_back(boundary28); + boundaries.push_back(boundary29); + boundaries.push_back(boundary30); + boundaries.push_back(boundary31); + boundaries.push_back(boundary32); + boundaries.push_back(boundary33); + boundaries.push_back(boundary34); + boundaries.push_back(boundary35); + boundaries.push_back(boundary36); + boundaries.push_back(boundary37); + boundaries.push_back(boundary38); + boundaries.push_back(boundary39); + boundaries.push_back(boundary40); + boundaries.push_back(boundary41); + boundaries.push_back(boundary42); + boundaries.push_back(boundary43); + boundaries.push_back(boundary44); + boundaries.push_back(boundary45); + boundaries.push_back(boundary46); + boundaries.push_back(boundary47); + boundaries.push_back(boundary48); + + + + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + std::vector< size_t > bd = increasing.get_boundary_of_a_cell(i); + for (size_t j = 0; j != bd.size(); ++j) { + BOOST_CHECK(boundaries[i][j] == bd[j]); + } + } +} + +BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + + + std::vector coboundaryElements; + coboundaryElements.push_back(7); + coboundaryElements.push_back(1); + coboundaryElements.push_back(8); + coboundaryElements.push_back(9); + coboundaryElements.push_back(1); + coboundaryElements.push_back(3); + coboundaryElements.push_back(10); + coboundaryElements.push_back(11); + coboundaryElements.push_back(3); + coboundaryElements.push_back(5); + coboundaryElements.push_back(12); + coboundaryElements.push_back(13); + coboundaryElements.push_back(5); + coboundaryElements.push_back(8); + coboundaryElements.push_back(8); + coboundaryElements.push_back(10); + coboundaryElements.push_back(10); + coboundaryElements.push_back(12); + coboundaryElements.push_back(12); + coboundaryElements.push_back(7); + coboundaryElements.push_back(21); + coboundaryElements.push_back(15); + coboundaryElements.push_back(8); + coboundaryElements.push_back(22); + coboundaryElements.push_back(9); + coboundaryElements.push_back(23); + coboundaryElements.push_back(15); + coboundaryElements.push_back(17); + coboundaryElements.push_back(10); + coboundaryElements.push_back(24); + coboundaryElements.push_back(11); + coboundaryElements.push_back(25); + coboundaryElements.push_back(17); + coboundaryElements.push_back(19); + coboundaryElements.push_back(12); + coboundaryElements.push_back(26); + coboundaryElements.push_back(13); + coboundaryElements.push_back(27); + coboundaryElements.push_back(19); + coboundaryElements.push_back(22); + coboundaryElements.push_back(22); + coboundaryElements.push_back(24); + coboundaryElements.push_back(24); + coboundaryElements.push_back(26); + coboundaryElements.push_back(26); + coboundaryElements.push_back(21); + coboundaryElements.push_back(35); + coboundaryElements.push_back(29); + coboundaryElements.push_back(22); + coboundaryElements.push_back(36); + coboundaryElements.push_back(23); + coboundaryElements.push_back(37); + coboundaryElements.push_back(29); + coboundaryElements.push_back(31); + coboundaryElements.push_back(24); + coboundaryElements.push_back(38); + coboundaryElements.push_back(25); + coboundaryElements.push_back(39); + coboundaryElements.push_back(31); + coboundaryElements.push_back(33); + coboundaryElements.push_back(26); + coboundaryElements.push_back(40); + coboundaryElements.push_back(27); + coboundaryElements.push_back(41); + coboundaryElements.push_back(33); + coboundaryElements.push_back(36); + coboundaryElements.push_back(36); + coboundaryElements.push_back(38); + coboundaryElements.push_back(38); + coboundaryElements.push_back(40); + coboundaryElements.push_back(40); + coboundaryElements.push_back(35); + coboundaryElements.push_back(43); + coboundaryElements.push_back(36); + coboundaryElements.push_back(37); + coboundaryElements.push_back(43); + coboundaryElements.push_back(45); + coboundaryElements.push_back(38); + coboundaryElements.push_back(39); + coboundaryElements.push_back(45); + coboundaryElements.push_back(47); + coboundaryElements.push_back(40); + coboundaryElements.push_back(41); + coboundaryElements.push_back(47); + size_t number = 0; + for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + std::vector< size_t > bd = increasing.get_coboundary_of_a_cell(i); + for (size_t j = 0; j != bd.size(); ++j) { + BOOST_CHECK(coboundaryElements[number] == bd[j]); + ++number; + } + + } +} + +BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + + std::vector dim; + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(2); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + dim.push_back(1); + dim.push_back(0); + + for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + BOOST_CHECK(increasing.get_dimension_of_a_cell(i) == dim[i]); + } +} + +BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { + std::vector< double > increasingFiltrationOfTopDimensionalCells; + increasingFiltrationOfTopDimensionalCells.push_back(1); + increasingFiltrationOfTopDimensionalCells.push_back(2); + increasingFiltrationOfTopDimensionalCells.push_back(3); + increasingFiltrationOfTopDimensionalCells.push_back(4); + increasingFiltrationOfTopDimensionalCells.push_back(5); + increasingFiltrationOfTopDimensionalCells.push_back(6); + increasingFiltrationOfTopDimensionalCells.push_back(7); + increasingFiltrationOfTopDimensionalCells.push_back(8); + increasingFiltrationOfTopDimensionalCells.push_back(9); + + std::vector dimensions; + dimensions.push_back(3); + dimensions.push_back(3); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + + std::vector< unsigned > dim; + dim.push_back(0); + dim.push_back(0); + dim.push_back(0); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + dim.push_back(0); + dim.push_back(1); + dim.push_back(1); + dim.push_back(2); + + std::vector fil; + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(1); + fil.push_back(2); + fil.push_back(2); + fil.push_back(2); + fil.push_back(2); + fil.push_back(2); + fil.push_back(2); + fil.push_back(3); + fil.push_back(3); + fil.push_back(3); + fil.push_back(3); + fil.push_back(3); + fil.push_back(3); + fil.push_back(4); + fil.push_back(4); + fil.push_back(4); + fil.push_back(4); + fil.push_back(4); + fil.push_back(4); + fil.push_back(5); + fil.push_back(5); + fil.push_back(5); + fil.push_back(5); + fil.push_back(6); + fil.push_back(6); + fil.push_back(6); + fil.push_back(6); + fil.push_back(7); + fil.push_back(7); + fil.push_back(7); + fil.push_back(7); + fil.push_back(7); + fil.push_back(7); + fil.push_back(8); + fil.push_back(8); + fil.push_back(8); + fil.push_back(8); + fil.push_back(9); + fil.push_back(9); + fil.push_back(9); + fil.push_back(9); + + + Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range(); + size_t position = 0; + for (Bitmap_cubical_complex::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) { + BOOST_CHECK(increasing.dimension(*it) == dim[position]); + BOOST_CHECK(increasing.filtration(*it) == fil[position]); + ++position; + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a66d90b6..2ef89f84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,10 +44,10 @@ else() # Gudhi compilation part include_directories(include) - add_subdirectory(example/Simplex_tree) - add_subdirectory(example/Persistent_cohomology) - add_subdirectory(example/Skeleton_blocker) - add_subdirectory(example/Contraction) + #add_subdirectory(example/Simplex_tree) + #add_subdirectory(example/Persistent_cohomology) + #add_subdirectory(example/Skeleton_blocker) + #add_subdirectory(example/Contraction) add_subdirectory(example/Bitmap_cubical_complex) # data points generator -- cgit v1.2.3 From d9f8f2d006c1c57c05eeb6eddbc625e44ebd8831 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 11 Dec 2015 10:11:32 +0000 Subject: Adding corecntions suggested by the Editorial Board to the Bitmap_cubical_complex class. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@942 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 81338409d0c6dc3435474f08f499dd5b72812ad6 --- .../doc/Gudhi_Cubical_Complex_doc.h | 106 +++++ src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf | Bin 0 -> 13940 bytes src/Bitmap_cubical_complex/doc/exampleBitmap.pdf | Bin 0 -> 11122 bytes .../example/Bitmap_cubical_complex.cpp | 5 +- .../include/gudhi/Bitmap_cubical_complex.h | 455 +++++++-------------- .../include/gudhi/Bitmap_cubical_complex/counter.h | 171 ++++++++ .../include/gudhi/Bitmap_cubical_complex_base.h | 22 +- src/Bitmap_cubical_complex/include/gudhi/counter.h | 177 -------- 8 files changed, 440 insertions(+), 496 deletions(-) create mode 100644 src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h create mode 100644 src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf create mode 100644 src/Bitmap_cubical_complex/doc/exampleBitmap.pdf create mode 100644 src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/counter.h (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h new file mode 100644 index 00000000..4acf2b3a --- /dev/null +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -0,0 +1,106 @@ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#pragma once + +namespace Gudhi +{ + +namespace Cubical_complex +{ + +/** \defgroup cubical_complex Cubical complex +* +* \author Pawel Dlotko +* +* @{ +* + +*Cubical complex is an example of a structured complex useful in computational mathematics (specially rigorous numerics) and image analysis. The presented implementation of cubical complexes is based on the following definition. +* +* An \emph{elementary interval} is an interval of a form $[n,n+1]$, or $[n,n]$, for $n \in \mathcal{Z}$. The first one is called \emph{non-degenerated}, while the second one is \emph{degenerated} interval. A \emph{boundary of a elementary +*interval} is a chain $\partial [n,n+1] = [n+1,n+1]-[n,n]$ in case of non-degenerated elementary interval and $\partial [n,n] = 0$ in case of degenerated elementary interval. An \emph{elementary cube} $C$ is a +*product of elementary intervals, $C=I_1 \times \ldots \times I_n$. \emph{Embedding dimension} of a cube is n, the number of elementary intervals (degenerated or not) in the product. A \emph{dimension of a cube} $C=I_1 \times ... \times I_n$ is the +*number of non degenerated elementary intervals in the product. A \emph{boundary of a cube} $C=I_1 \times \ldots \times I_n$ is a chain obtained in the following way: +*\[\partial C = (\partial I_1 \times \ldots \times I_n) + (I_1 \times \partial I_2 \times \ldots \times I_n) + \ldots + (I_1 \times I_2 \times \ldots \times \partial I_n).\] +*A \emph{cubical complex} $\mathcal{K}$ is a collection of cubes closed under operation of taking boundary (i.e. boundary of every cube from the collection is in the collection). A cube $C$ in cubical complex $\mathcal{K}$ is \emph{maximal} if it is not in +*a boundary of any other cube in $\mathcal{K}$. A \emph{support} of a cube $C$ is the set in $\mathbb{R}^n$ occupied by $C$ ($n$ is the embedding dimension of $C$). +* +*Cubes may be equipped with a filtration values in which case we have filtered cubical complex. All the cubical complexes considered in this implementation are filtered cubical complexes (although, the range of a filtration may be a set of two elements). +* +*For further details and theory of cubical complexes, please consult a book:\\ +*Computational homology, by Tomasz Kaczynski, Konstantin Mischaikow, and Marion Mrozek, Appl. Math. Sci., vol. 157, Springer-Verlag, New York, 2004 +* +*as well as the paper: +*Efficient computation of persistent homology for cubical data by Hubert Wagner, Chao Chen, Erald Vuçini (published in the proceedings of Workshop on Topology-based Methods in Data +*Analysis and Visualization) +* +*\section{Data structure.} +* +*The implementation of Cubical complex provides a representation of complexes that occupy a rectangular region in $\mathbb{R}^n$. This extra +*assumption allows for a memory efficient way of storing cubical complexes in a form of so called bitmaps. Let $R = [b_1,e_1] \times \ldots \times [b_n,e_n]$, for $b_1,...b_n,e_1,...,e_n \in \mathbb{Z}$ +*, $b_i \leq d_i$ be the considered rectangular region and let $\mathcal{K}$ be a filtered cubical complex having the rectangle $R$ as its support. Note that the structure of the coordinate system gives a way +*a lexicographical ordering of cells of $\mathcal{K}$. This ordering is a base of the presented bitmap-based implementation. In this implementation, the whole cubical complex is stored as a vector +*of the values of filtration. This, together with dimension of $\mathcal{K}$ and the sizes of $\mathcal{K}$ in all directions, allows to determine, dimension, neighborhood, boundary and coboundary of every cube $C \in \mathcal{K}$. +* +*\image html "bitmapAllCubes.pdf" "Cubical complex in $\mathbb{R}^2". +* +*Note that the cubical complex in the figure above is, in a natural way, a product of one dimensional cubical complexes in $\mathbb{R}$. The number of all cubes in each direction is +*equal $2n+1$, where $n$ is the number of maximal cubes in the considered direction. Let us consider a cube at the position $k$ in the bitmap. Knowing the sizes of the bitmap, +*by a series of modulo operation, we can determine which elementary intervals are present in the product that gives the cube $C$. In a similar way, we can compute boundary +*and the coboundary of each cube. Further details can be found in the literature. +* +*\section{Input Format.} +* +*In the current implantation, filtration is given at the maximal cubes, and it is then extended by the lower star filtration to all cubes. There are a number of constructors +*that can be used to construct cubical complex by users who want to use the code directly. They can be found in the \emph{Bitmap\_cubical\_complex} class. +*Currently one input from a text file is used. It uses a format used already in Perseus software $(http://www.sas.upenn.edu/~vnanda/perseus/)$ by Vidit Nanda. +*Below we are providing a description of the format. +* +*\begin{enumerate} +*\item The first line of the file is $d$, the embedding dimension of a complex. +*\item The next $d$ lines consist of positive numbers being the numbers of top dimensional cubes in the given direction. Let us call those numbers $n_1,\ldots,n_d$. +*\item Later there is a sequence of $n_1 \dot \ldots \dot n_d$ numbers in a lexicographical ordering. Those numbers are filtrations of top dimensional cubes. +*\end{enumerate} +* +*\image html "exampleBitmap.pdf" "Example of a input data." +* +*The input file for the following complex is: +*\begin{verbatim} +*2 +*3 +*3 +*1 +*2 +*3 +*8 +*20 +*4 +*7 +*6 +*5 +*\end{verbatim} +* +* +} +} diff --git a/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf new file mode 100644 index 00000000..694105e4 Binary files /dev/null and b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf differ diff --git a/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf b/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf new file mode 100644 index 00000000..ef930c0c Binary files /dev/null and b/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf differ diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index 31da3609..e56428b6 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -59,16 +59,13 @@ lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for exam Bitmap_cubical_complex b( argv[1] ); - // Compute the persistence diagram of the complex persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); pcoh.init_coefficients( p ); //initilizes the coefficient field for homology pcoh.compute_persistent_cohomology( min_persistence ); - - stringstream ss; ss << argv[1] << "_persistence"; - std::ofstream out((char*)ss.str().c_str()); + std::ofstream out(ss.str().c_str()); pcoh.output_diagram(out); out.close(); diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index f2c753d9..b8887e71 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -34,7 +34,9 @@ namespace Cubical_complex { //global variable, was used just for debugging. -const bool globalDbg = false; +const bool globalDbg = false; + +template class is_before_in_filtration; template class Bitmap_cubical_complex : public Bitmap_cubical_complex_base @@ -45,71 +47,8 @@ public: //*********************************************// friend class Simplex_handle; typedef size_t Simplex_key; - typedef T Filtration_value; - - -//*********************************************// -//Simplex handle class -//*********************************************// - /** - * Handle of a cell, required for compatibility with the function to compute persistence in Gudhi. - * Elements of this class are: the pointer to the bitmap B in which the considered cell is - * together with a position of this cell in B. Given this data, - * one can get all the information about the considered cell. - **/ - class Simplex_handle - { - public: - Simplex_handle() - { - if ( globalDbg ){cerr << "Simplex_handle()\n";} - this->b = 0; - this->position = 0; - } - - Simplex_handle(Bitmap_cubical_complex* b) - { - if ( globalDbg ) - { - cerr << "Simplex_handle(Bitmap_cubical_complex* b)\n"; - } - this->b = b; - this->position = 0; - } - - //Simplex_handle( const Simplex_handle& org ):b(org.b) - //{ - // if ( globalDbg ){cerr << "Simplex_handle( const Simplex_handle& org )\n";} - // this->position = org.position; - //} - - Simplex_handle operator = ( const Simplex_handle& rhs ) - { - if ( globalDbg ){cerr << "Simplex_handle operator = \n";} - this->position = rhs.position; - this->b = rhs.b; - return *this; - } - - Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position) - { - if ( globalDbg ) - { - cerr << "Simplex_handle(Bitmap_cubical_complex* b , Simplex_key position)\n"; - cerr << "Position : " << position << endl; - } - this->b = b; - this->position = position; - } - friend class Bitmap_cubical_complex; - private: - Bitmap_cubical_complex* b; - Simplex_key position; - //Assumption -- field above always keep the REAL position of simplex in the bitmap, - //no matter what keys have been. - //to deal with the keys, the class Bitmap_cubical_complex have extra vectors: key_associated_to_simplex and - //simplex_associated_to_key that allow to move between actual cell and the key assigned to it. - }; + typedef T Filtration_value; + typedef Simplex_key Simplex_handle; //*********************************************// @@ -125,39 +64,37 @@ public: * Constructor form a Perseus-style file. **/ Bitmap_cubical_complex( const char* perseus_style_file ): - Bitmap_cubical_complex_base(perseus_style_file),key_associated_to_simplex(this->total_number_of_cells+1), - simplex_associated_to_key(this->total_number_of_cells+1) + Bitmap_cubical_complex_base(perseus_style_file),key_associated_to_simplex(this->total_number_of_cells+1) { if ( globalDbg ){cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n";} for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) { - this->key_associated_to_simplex[i] = this->simplex_associated_to_key[i] = i; + this->key_associated_to_simplex[i] = i; } - //we initialize this only once, in each constructor, when the bitmap is constructed. + //we initialize this only once, in each constructor, when the bitmap is constructed. //If the user decide to change some elements of the bitmap, then this procedure need //to be called again. - this->initialize_elements_ordered_according_to_filtration(); + this->initialize_simplex_associated_to_key(); } /** - * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells + * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells * in the following directions and vector of element of a type T * with filtration on top dimensional cells. **/ Bitmap_cubical_complex( std::vector& dimensions , std::vector& top_dimensional_cells ): Bitmap_cubical_complex_base(dimensions,top_dimensional_cells), - key_associated_to_simplex(this->total_number_of_cells+1), - simplex_associated_to_key(this->total_number_of_cells+1) + key_associated_to_simplex(this->total_number_of_cells+1) { for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) { - this->key_associated_to_simplex[i] = this->simplex_associated_to_key[i] = i; + this->key_associated_to_simplex[i] = i; } - //we initialize this only once, in each constructor, when the bitmap is constructed. + //we initialize this only once, in each constructor, when the bitmap is constructed. //If the user decide to change some elements of the bitmap, then this procedure need //to be called again. - this->initialize_elements_ordered_according_to_filtration(); + this->initialize_simplex_associated_to_key(); } //*********************************************// @@ -174,15 +111,17 @@ public: /** * Returns a Simplex_handle to a cube that do not exist in this complex. **/ - Simplex_handle null_simplex() - { - return Simplex_handle(this,this->data.size()); - } + static Simplex_handle null_simplex() + { + if ( globalDbg ){cerr << "Simplex_handle null_simplex()\n";} + return std::numeric_limits::max(); + } + /** * Returns dimension of the complex. **/ - size_t dimension() + inline size_t dimension()const { return this->sizes.size(); } @@ -190,10 +129,10 @@ public: /** * Return dimension of a cell pointed by the Simplex_handle. **/ - unsigned dimension(const Simplex_handle& sh) + inline unsigned dimension(const Simplex_handle& sh)const { if ( globalDbg ){cerr << "unsigned dimension(const Simplex_handle& sh)\n";} - if ( sh.position != this->data.size() ) return sh.b->get_dimension_of_a_cell( sh.position ); + if ( sh != std::numeric_limits::max() ) return this->get_dimension_of_a_cell( sh ); return -1; } @@ -204,26 +143,30 @@ public: { if ( globalDbg ){cerr << "T filtration(const Simplex_handle& sh)\n";} //Returns the filtration value of a simplex. - if ( sh.position != this->data.size() ) return sh.b->data[ sh.position ]; + if ( sh != std::numeric_limits::max() ) return this->data[sh]; return std::numeric_limits::max(); } /** * Return a key which is not a key of any cube in the considered data structure. **/ - Simplex_key null_key() + static Simplex_key null_key() { if ( globalDbg ){cerr << "Simplex_key null_key()\n";} - return this->data.size(); + return std::numeric_limits::max(); } /** * Return the key of a cube pointed by the Simplex_handle. **/ - Simplex_key key(const Simplex_handle& sh) + Simplex_key key(const Simplex_handle& sh)const { - if ( globalDbg ){cerr << "Simplex_key key(const Simplex_handle& sh)\n";} - return sh.b->key_associated_to_simplex[ sh.position ]; + if ( globalDbg ){cerr << "Simplex_key key(const Simplex_handle& sh)\n";} + if ( sh != std::numeric_limits::max() ) + { + return this->key_associated_to_simplex[sh]; + } + return this->null_key(); } /** @@ -231,8 +174,12 @@ public: **/ Simplex_handle simplex(Simplex_key key) { - if ( globalDbg ){cerr << "Simplex_handle simplex(Simplex_key key)\n";} - return Simplex_handle( this , this->simplex_associated_to_key[ key ] ); + if ( globalDbg ){cerr << "Simplex_handle simplex(Simplex_key key)\n";} + if ( key != std::numeric_limits::max() ) + { + return this->simplex_associated_to_key[ key ]; + } + return null_simplex(); } /** @@ -240,15 +187,29 @@ public: **/ void assign_key(Simplex_handle& sh, Simplex_key key) { - if ( globalDbg ){cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";} - this->key_associated_to_simplex[sh.position] = key; - this->simplex_associated_to_key[key] = sh.position; + if ( globalDbg ){cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";} + + + + + + + + +if ( key == std::numeric_limits::max() ) return;//TODO FAKE!!! CHEATING!!! + + + + + + this->key_associated_to_simplex[sh] = key; + this->simplex_associated_to_key[key] = sh; } /** * Function called from a constructor. It is needed for Filtration_simplex_iterator to work. **/ - void initialize_elements_ordered_according_to_filtration(); + void initialize_simplex_associated_to_key(); @@ -256,104 +217,42 @@ public: //Iterators //*********************************************// - /** - * Boundary_simplex_iterator class allows iteration on boundary of each cube. - **/ - class Boundary_simplex_range; - class Boundary_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > - { - //Iterator on the simplices belonging to the boundary of a simplex. - //value_type must be 'Simplex_handle'. - public: - Boundary_simplex_iterator( Simplex_handle& sh ):sh(sh) - { - if ( globalDbg ){cerr << "Boundary_simplex_iterator( Simplex_handle& sh )\n";} - this->position = 0; - this->boundary_elements = this->sh.b->get_boundary_of_a_cell( this->sh.position ); - } - Boundary_simplex_iterator operator++() - { - if ( globalDbg ){cerr << "Boundary_simplex_iterator operator++()\n";} - ++this->position; - return *this; - } - Boundary_simplex_iterator operator++(int) - { - Boundary_simplex_iterator result = *this; - ++(*this); - return result; - } - Boundary_simplex_iterator operator =( const Boundary_simplex_iterator& rhs ) - { - if ( globalDbg ){cerr << "Boundary_simplex_iterator operator =\n";} - this->sh = rhs.sh; - this->boundary_elements.clear(); - this->boundary_elementsinsert - (this->boundary_elements.end(), rhs.boundary_elements.begin(), rhs.boundary_elements.end()); - } - bool operator == ( const Boundary_simplex_iterator& rhs ) - { - if ( globalDbg ){cerr << "bool operator ==\n";} - if ( this->position == rhs.position ) - { - if ( this->boundary_elements.size() != rhs.boundary_elements.size() )return false; - for ( size_t i = 0 ; i != this->boundary_elements.size() ; ++i ) - { - if ( this->boundary_elements[i] != rhs.boundary_elements[i] )return false; - } - return true; - } - return false; - } - - bool operator != ( const Boundary_simplex_iterator& rhs ) - { - if ( globalDbg ){cerr << "bool operator != \n";} - return !(*this == rhs); - } - Simplex_handle operator*() - { - if ( globalDbg ){cerr << "Simplex_handle operator*\n";} - return Simplex_handle( this->sh.b , this->boundary_elements[this->position] ); - } - - friend class Boundary_simplex_range; - private: - Simplex_handle sh; - std::vector< size_t > boundary_elements; - size_t position; - }; /** * Boundary_simplex_range class provides ranges for boundary iterators. - **/ + **/ + typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; class Boundary_simplex_range { //Range giving access to the simplices in the boundary of a simplex. //.begin() and .end() return type Boundary_simplex_iterator. - public: - Boundary_simplex_range(const Simplex_handle& sh):sh(sh){}; - Boundary_simplex_iterator begin() - { - if ( globalDbg ){cerr << "Boundary_simplex_iterator begin\n";} - Boundary_simplex_iterator it( this->sh ); - return it; - } - Boundary_simplex_iterator end() - { - if ( globalDbg ){cerr << "Boundary_simplex_iterator end()\n";} - Boundary_simplex_iterator it( this->sh ); - it.position = it.boundary_elements.size(); - return it; - } - private: - Simplex_handle sh; - }; + public: + typedef Boundary_simplex_iterator const_iterator; + Boundary_simplex_range(const Simplex_handle& sh , Bitmap_cubical_complex* CC_):sh(sh),CC(CC_) + { + this->boundary_elements = this->CC->get_boundary_of_a_cell( sh ); + } + Boundary_simplex_iterator begin() + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator begin\n";} + return this->boundary_elements.begin(); + + } + Boundary_simplex_iterator end() + { + if ( globalDbg ){cerr << "Boundary_simplex_iterator end()\n";} + return this->boundary_elements.end(); + } + private: + Simplex_handle sh; + Bitmap_cubical_complex* CC; + std::vector< Simplex_handle > boundary_elements; + }; /** - * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. + * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. * Secondary criteria for filtration are: * (1) Dimension of a cube (lower dimensional comes first). * (2) Position in the data structure (the ones that are earlies in the data structure comes first). @@ -385,17 +284,13 @@ public: this->b = rhs.b; this->position = rhs.position; } - bool operator == ( const Filtration_simplex_iterator& rhs ) + bool operator == ( const Filtration_simplex_iterator& rhs )const { if ( globalDbg ){cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n";} - if ( this->position == rhs.position ) - { - return true; - } - return false; + return ( this->position == rhs.position ); } - bool operator != ( const Filtration_simplex_iterator& rhs ) + bool operator != ( const Filtration_simplex_iterator& rhs )const { if ( globalDbg ){cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n";} return !(*this == rhs); @@ -403,7 +298,7 @@ public: Simplex_handle operator*() { if ( globalDbg ){cerr << "Simplex_handle operator*()\n";} - return Simplex_handle( this->b , this->b->elements_ordered_according_to_filtration[ this->position ] ); + return this->b->simplex_associated_to_key[ this->position ]; } friend class Filtration_simplex_range; @@ -420,7 +315,8 @@ public: { //Range over the simplices of the complex in the order of the filtration. //.begin() and .end() return type Filtration_simplex_iterator. - public: + public: + typedef Filtration_simplex_iterator const_iterator; Filtration_simplex_range(Bitmap_cubical_complex* b):b(b){}; Filtration_simplex_iterator begin() { @@ -431,7 +327,7 @@ public: { if ( globalDbg ){cerr << "Filtration_simplex_iterator end()\n";} Filtration_simplex_iterator it( this->b ); - it.position = this->b->elements_ordered_according_to_filtration.size(); + it.position = this->b->simplex_associated_to_key.size(); return it; } private: @@ -443,19 +339,19 @@ public: //*********************************************// //Methods to access iterators from the container: /** - * boundary_simplex_range creates an object of a Boundary_simplex_range class + * boundary_simplex_range creates an object of a Boundary_simplex_range class * that provides ranges for the Boundary_simplex_iterator. **/ Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh) { if ( globalDbg ){cerr << "Boundary_simplex_range boundary_simplex_range(Simplex_handle& sh)\n";} - //Returns a range giving access to all simplices of the boundary of a simplex, + //Returns a range giving access to all simplices of the boundary of a simplex, //i.e. the set of codimension 1 subsimplices of the Simplex. - return Boundary_simplex_range(sh); + return Boundary_simplex_range(sh,this); } /** - * filtration_simplex_range creates an object of a Filtration_simplex_range class + * filtration_simplex_range creates an object of a Filtration_simplex_range class * that provides ranges for the Filtration_simplex_iterator. **/ Filtration_simplex_range filtration_simplex_range() @@ -470,9 +366,9 @@ public: //*********************************************// //Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are there. - //TODO -- the file IndexingTag.h in the Gudhi library contains an empty structure, so + //TODO -- the file IndexingTag.h in the Gudhi library contains an empty structure, so //I understand that this is something that was planned (for simplicial maps?) - //but was never finished. The only idea I have here is to use the same empty structure from + //but was never finished. The only idea I have here is to use the same empty structure from //IndexingTag.h file, but only if the compiler needs it. If the compiler //do not need it, then I would rather not add here elements which I do not understand. //typedef Indexing_tag @@ -481,7 +377,7 @@ public: **/ std::pair endpoints( Simplex_handle sh ) { - std::vector< size_t > bdry = this->get_boundary_of_a_cell( sh.position ); + std::vector< size_t > bdry = this->get_boundary_of_a_cell( sh ); if ( globalDbg ) { cerr << "std::pair endpoints( Simplex_handle sh )\n"; @@ -490,7 +386,7 @@ public: //this method returns two first elements from the boundary of sh. if ( bdry.size() < 2 ) throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the boundary."); - return std::make_pair( Simplex_handle(this,bdry[0]) , Simplex_handle(this,bdry[1]) ); + return std::make_pair( bdry[0] , bdry[1] ); } @@ -508,9 +404,9 @@ public: if ( globalDbg ){cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n";} //find the position of the first simplex of a dimension d this->position = 0; - while ( - (this->position != b->data.size()) && - ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) + while ( + (this->position != b->data.size()) && + ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) ) { ++this->position; @@ -523,9 +419,9 @@ public: if ( globalDbg ){cerr << "Skeleton_simplex_iterator operator++()\n";} //increment the position as long as you did not get to the next element of the dimension dimension. ++this->position; - while ( - (this->position != this->b->data.size()) && - ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) + while ( + (this->position != this->b->data.size()) && + ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) ) { ++this->position; @@ -544,17 +440,13 @@ public: this->b = rhs.b; this->position = rhs.position; } - bool operator == ( const Skeleton_simplex_iterator& rhs ) + bool operator == ( const Skeleton_simplex_iterator& rhs )const { if ( globalDbg ){cerr << "bool operator ==\n";} - if ( this->position == rhs.position ) - { - return true; - } - return false; + return ( this->position == rhs.position ); } - bool operator != ( const Skeleton_simplex_iterator& rhs ) + bool operator != ( const Skeleton_simplex_iterator& rhs )const { if ( globalDbg ){cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n";} return !(*this == rhs); @@ -562,7 +454,7 @@ public: Simplex_handle operator*() { if ( globalDbg ){cerr << "Simplex_handle operator*() \n";} - return Simplex_handle( this->b , this->position ); + return this->position; } friend class Skeleton_simplex_range; @@ -578,7 +470,8 @@ public: { //Range over the simplices of the complex in the order of the filtration. //.begin() and .end() return type Filtration_simplex_iterator. - public: + public: + typedef Skeleton_simplex_iterator const_iterator; Skeleton_simplex_range(Bitmap_cubical_complex* b , unsigned dimension):b(b),dimension(dimension){}; Skeleton_simplex_iterator begin() { @@ -606,107 +499,59 @@ public: return Skeleton_simplex_range( this , dimension ); } + friend class is_before_in_filtration; -//*********************************************// -//functions used for debugging: - /** - * Function used for debugging purposes. - **/ - //void printkey_associated_to_simplex() - //{ - // for ( size_t i = 0 ; i != this->data.size() ; ++i ) - // { - // cerr << i << " -> " << this->simplex_associated_to_key[i] << endl; - // } - //} - - /** - * Function used for debugging purposes. - **/ - size_t printRealPosition( const Simplex_handle& sh ) - { - return sh.position; - } - -private: +protected: std::vector< size_t > key_associated_to_simplex; std::vector< size_t > simplex_associated_to_key; - std::vector< size_t > elements_ordered_according_to_filtration; - //filed above is needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. };//Bitmap_cubical_complex - + template -bool compare_elements_for_elements_ordered_according_to_filtration -( const std::pair< size_t , std::pair< T , char > >& f , const std::pair< size_t , std::pair< T , char > >& s ) +void Bitmap_cubical_complex::initialize_simplex_associated_to_key() { - if ( globalDbg ){cerr << "compare_elements_for_elements_ordered_according_to_filtration\n";} - if ( f.second.first < s.second.first ) - { - return true; - } - else + if ( globalDbg ) { - if ( f.second.first > s.second.first ) - { - return false; - } - else - { - //in this case f.second.first == s.second.first, and we use dimension to compare: - if ( f.second.second < s.second.second ) - { - return true; - } - else - { - if ( f.second.second > s.second.second ) - { - return false; - } - else - { - //in this case, both the filtration value and the dimensions for those cells are the same. - //Since it may be nice to have a stable sorting procedure, in this case, - //we compare positions in the bitmap: - return ( f.first < s.first ); - } - } - } + cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; } + std::vector data_of_elements_from_bitmap( this->data.size() ); + std::iota (std::begin(data_of_elements_from_bitmap), std::end(data_of_elements_from_bitmap), 0); + std::sort( data_of_elements_from_bitmap.begin() , + data_of_elements_from_bitmap.end() , + is_before_in_filtration(this) ); + this->simplex_associated_to_key = data_of_elements_from_bitmap; } - + + template -void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() +class is_before_in_filtration { - if ( globalDbg ) - { - cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; - } - //( position , (filtration , dimension) ) - std::vector< std::pair< size_t , std::pair< T , char > > > data_of_elements_from_bitmap( this->data.size() ); - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - //TODO -- this can be optimized by having a counter here. - //We do not need to re-compute the dimension for every cell from scratch - data_of_elements_from_bitmap[i] = - std::make_pair( i , std::make_pair( this->data[i] , this->get_dimension_of_a_cell(i) ) ); - } - std::sort( data_of_elements_from_bitmap.begin() , - data_of_elements_from_bitmap.end() , - compare_elements_for_elements_ordered_according_to_filtration ); - - std::vector< size_t > - elements_ordered_according_to_filtration_then_to_dimension_then_to_position - ( this->data.size() ); - for ( size_t i = 0 ; i != data_of_elements_from_bitmap.size() ; ++i ) +public: + explicit is_before_in_filtration(Bitmap_cubical_complex * CC) + : CC_(CC) { } + + bool operator()( const typename Bitmap_cubical_complex::Simplex_handle sh1, const typename Bitmap_cubical_complex::Simplex_handle sh2) const { - elements_ordered_according_to_filtration_then_to_dimension_then_to_position[i] - = data_of_elements_from_bitmap[i].first; - } - this->elements_ordered_according_to_filtration = - elements_ordered_according_to_filtration_then_to_dimension_then_to_position; -} + // Not using st_->filtration(sh1) because it uselessly tests for null_simplex. + T fil1 = CC_->data[sh1]; + T fil2 = CC_->data[sh2]; + if ( fil1 != fil2 ) + { + return fil1 < fil2; + } + //in this case they are on the same filtration level, so the dimension decide. + size_t dim1 = CC_->get_dimension_of_a_cell(sh1); + size_t dim2 = CC_->get_dimension_of_a_cell(sh2); + if ( dim1 != dim2 ) + { + return dim1 < dim2; + } + //in this case both filtration and dimensions of the considered cubes are the same. To have stable sort, we simply compare their positions in the bitmap: + return sh1 < sh2; + } +protected: + Bitmap_cubical_complex* CC_; + }; //****************************************************************************************************************// @@ -716,4 +561,4 @@ void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtrat } -} \ No newline at end of file +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h new file mode 100644 index 00000000..3a17b4a0 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h @@ -0,0 +1,171 @@ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Sophia-Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +using namespace std; + +namespace Gudhi +{ + +namespace Cubical_complex +{ + +/** +* This is an implementation of a counter being a vector of integers. +* The constructor of the class takes as an input two vectors W and V. +* It assumes that W < V coordinatewise. +* If the initial counter W is not specified, it is assumed to be vector of zeros. +* The class allows to iterate between W and V by using increment() function. +* The increment() function returns a bool value. +* The current counter reach the end counter V if the value returned by the increment function is FALSE. +* This class is needed for the implementation of a bitmapCubicalComplex. +**/ + +class counter +{ +public: + /** + * Constructor of a counter class. It takes only the parameter which is the end value of the counter. + * The default beginning value is a vector of the same length as the endd, filled-in with zeros. + **/ + counter(std::vector const& endd): begin(endd.size(),0), end(endd), current(endd.size(),0){} + //counter(std::vector< int >& endd) + //{ + // for ( size_t i = 0 ; i != endd.size() ; ++i ) + // { + // this->current.push_back(0); + // this->begin.push_back(0); + // this->end.push_back( endd[i] ); + // } + //} + + + /** + * Constructor of a counter class. It takes as the input beginn and end vector. + * It assumes that begin vector is lexicographically below the end vector. + **/ + counter(std::vector< unsigned >& beginn , std::vector< unsigned >& endd):begin(beginn),end(endd),current(endd.size(),0) + { + if ( beginn.size() != endd.size() ) + throw "In constructor of a counter, begin and end vectors do not have the same size. Program terminate"; + } + + /** + * Function to increment the counter. If the value returned by the function is true, + * then the incrementation process was successful. + * If the value of the function is false, that means, that the counter have reached its end-value. + **/ + bool increment() + { + size_t i = 0; + while( (i != this->end.size()) && (this->current[i] == this->end[i]) ) + { + ++i; + } + + if ( i == this->end.size() )return false; + ++this->current[i]; + for ( size_t j = 0 ; j != i ; ++j ) + { + this->current[j] = this->begin[j]; + } + return true; + } + + /** + * Function to check if we are at the end of counter. + **/ + bool isFinal() + { + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( this->current[i] == this->end[i] )return true; + } + return false; + } + + /** + * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. + * Its aim is to find an counter corresponding to the element the following + * boundary element is identified with when periodic boundary conditions are imposed. + **/ + std::vector< unsigned > find_opposite( std::vector< bool >& directionsForPeriodicBCond ) + { + std::vector< unsigned > result; + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( (this->current[i] == this->end[i]) && (directionsForPeriodicBCond[i] == true) ) + { + result.push_back( this->begin[i] ); + } + else + { + result.push_back( this->current[i] ); + } + } + return result; + } + + /** + * Function checking at which positions the current value of a counter is the final value of the counter. + **/ + std::vector< bool > directions_of_finals() + { + std::vector< bool > result; + for ( size_t i = 0 ; i != this->current.size() ; ++i ) + { + if ( this->current[i] == this->end[i] ) + { + result.push_back( true ); + } + else + { + result.push_back( false ); + } + } + return result; + } + + /** + * Function to write counter to the stream. + **/ + friend std::ostream& operator<<(std::ostream& out , const counter& c ) + { + //cerr << "c.current.size() : " << c.current.size() << endl; + for ( size_t i = 0 ; i != c.current.size() ; ++i ) + { + out << c.current[i] << " "; + } + return out; + } +private: + std::vector< unsigned > begin; + std::vector< unsigned > end; + std::vector< unsigned > current; +}; + +} +} \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index 2c2bd481..4e63b9c3 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -30,7 +30,7 @@ #include #include #include -#include "counter.h" +#include "Bitmap_cubical_complex/counter.h" using namespace std; @@ -182,11 +182,9 @@ public: public: Top_dimensional_cells_iterator( Bitmap_cubical_complex_base& b ):b(b) { - for ( size_t i = 0 ; i != b.dimension() ; ++i ) - { - this->counter.push_back(0); - } - } + this->counter = std::vector(b.dimension()); + std::fill( this->counter.begin() , this->counter.end() , 0 ); + } Top_dimensional_cells_iterator operator++() { //first find first element of the counter that can be increased: @@ -264,7 +262,7 @@ public: } friend class Bitmap_cubical_complex_base; protected: - std::vector< unsigned > counter; + std::vector< size_t > counter; Bitmap_cubical_complex_base& b; }; Top_dimensional_cells_iterator top_dimensional_cells_begin() @@ -478,12 +476,16 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( si getchar(); } - std::vector< size_t > boundary_elements; + std::vector< size_t > boundary_elements( 2*dimensions_in_which_cell_has_nonzero_length.size() ); if ( dimensions_in_which_cell_has_nonzero_length.size() == 0 )return boundary_elements; for ( size_t i = 0 ; i != dimensions_in_which_cell_has_nonzero_length.size() ; ++i ) { - boundary_elements.push_back( cell - multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); - boundary_elements.push_back( cell + multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); + //boundary_elements.push_back( cell - multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); + //boundary_elements.push_back( cell + multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ] ); + boundary_elements[2*i] = cell - multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ]; + boundary_elements[2*i+1] = cell + multipliers[ dimensions_in_which_cell_has_nonzero_length[i] ]; + + if (bdg) cerr << "multipliers[dimensions_in_which_cell_has_nonzero_length[i]] : " << multipliers[dimensions_in_which_cell_has_nonzero_length[i]] << endl; diff --git a/src/Bitmap_cubical_complex/include/gudhi/counter.h b/src/Bitmap_cubical_complex/include/gudhi/counter.h deleted file mode 100644 index a5fda36f..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/counter.h +++ /dev/null @@ -1,177 +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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Sophia-Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -using namespace std; - -namespace Gudhi -{ - -namespace Cubical_complex -{ - -/** -* This is an implementation of a counter being a vector of integers. -* The constructor of the class takes as an input two vectors W and V. -* It assumes that W < V coordinatewise. -* If the initial counter W is not specified, it is assumed to be vector of zeros. -* The class allows to iterate between W and V by using increment() function. -* The increment() function returns a bool value. -* The current counter reach the end counter V if the value returned by the increment function is FALSE. -* This class is needed for the implementation of a bitmapCubicalComplex. -**/ - -class counter -{ -public: - /** - * Constructor of a counter class. It takes only the parameter which is the end value of the counter. - * The default beginning value is a vector of the same length as the endd, filled-in with zeros. - **/ - counter(std::vector const& endd): begin(endd.size(),0), end(endd), current(endd.size(),0){} - //counter(std::vector< int >& endd) - //{ - // for ( size_t i = 0 ; i != endd.size() ; ++i ) - // { - // this->current.push_back(0); - // this->begin.push_back(0); - // this->end.push_back( endd[i] ); - // } - //} - - - /** - * Constructor of a counter class. It takes as the input beginn and end vector. - * It assumes that begin vector is lexicographically below the end vector. - **/ - counter(std::vector< unsigned >& beginn , std::vector< unsigned >& endd) - { - if ( beginn.size() != endd.size() ) - throw "In constructor of a counter, begin and end vectors do not have the same size. Program terminate"; - for ( size_t i = 0 ; i != endd.size() ; ++i ) - { - this->current.push_back(0); - this->begin.push_back(0); - this->end.push_back( endd[i] ); - } - } - - /** - * Function to increment the counter. If the value returned by the function is true, - * then the incrementation process was successful. - * If the value of the function is false, that means, that the counter have reached its end-value. - **/ - bool increment() - { - size_t i = 0; - while( (i != this->end.size()) && (this->current[i] == this->end[i]) ) - { - ++i; - } - - if ( i == this->end.size() )return false; - ++this->current[i]; - for ( size_t j = 0 ; j != i ; ++j ) - { - this->current[j] = this->begin[j]; - } - return true; - } - - /** - * Function to check if we are at the end of counter. - **/ - bool isFinal() - { - for ( size_t i = 0 ; i != this->current.size() ; ++i ) - { - if ( this->current[i] == this->end[i] )return true; - } - return false; - } - - /** - * Function required in the implementation of bitmapCubicalComplexWPeriodicBoundaryCondition. - * Its aim is to find an counter corresponding to the element the following - * boundary element is identified with when periodic boundary conditions are imposed. - **/ - std::vector< unsigned > find_opposite( std::vector< bool >& directionsForPeriodicBCond ) - { - std::vector< unsigned > result; - for ( size_t i = 0 ; i != this->current.size() ; ++i ) - { - if ( (this->current[i] == this->end[i]) && (directionsForPeriodicBCond[i] == true) ) - { - result.push_back( this->begin[i] ); - } - else - { - result.push_back( this->current[i] ); - } - } - return result; - } - - /** - * Function checking at which positions the current value of a counter is the final value of the counter. - **/ - std::vector< bool > directions_of_finals() - { - std::vector< bool > result; - for ( size_t i = 0 ; i != this->current.size() ; ++i ) - { - if ( this->current[i] == this->end[i] ) - { - result.push_back( true ); - } - else - { - result.push_back( false ); - } - } - return result; - } - - /** - * Function to write counter to the stream. - **/ - friend std::ostream& operator<<(std::ostream& out , const counter& c ) - { - //cerr << "c.current.size() : " << c.current.size() << endl; - for ( size_t i = 0 ; i != c.current.size() ; ++i ) - { - out << c.current[i] << " "; - } - return out; - } -private: - std::vector< unsigned > begin; - std::vector< unsigned > end; - std::vector< unsigned > current; -}; - -} -} \ No newline at end of file -- cgit v1.2.3 From 28d0848f733f0dc6a019b3328c80168d10e0a5ae Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 8 Jan 2016 13:26:27 +0000 Subject: Adding a first vesion of a functionality that provide periodic boundary codnitions. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@955 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ae60d98a6b2c15c2f7152663c3b05d40f0a56e86 --- .../example/Bitmap_cubical_complex.cpp | 146 ++++++++++----------- ...ubical_complex_periodic_boundary_conditions.cpp | 72 ++++++++++ src/Bitmap_cubical_complex/example/CMakeLists.txt | 3 + 3 files changed, 148 insertions(+), 73 deletions(-) create mode 100644 src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index e56428b6..ed141ed9 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -1,73 +1,73 @@ - /* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -//for persistence algorithm -#include -#include -#include - - -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; - -//standard stuff -#include -#include - -using namespace std; - -int main( int argc , char** argv ) -{ - cout << "This program computes persistent homology, by using bitmap_cubical_complex class,\ - of cubical complexes provided in text files in Perseus style (the only numbered in \ -the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are\ - numbers of top dimensional cells in the direction I. Let N denote product \ -of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are\ - filtrations of top dimensional cells. We assume that the cells are in the \ -lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; - - int p = 2; - double min_persistence = 0; - - if ( argc != 2 ) - { - cout << "Wrong number of parameters. Please provide the name of a file with a\ - Perseus style bitmap at the input. The program will now terminate.\n"; - return 1; - } - - Bitmap_cubical_complex b( argv[1] ); - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); - pcoh.init_coefficients( p ); //initilizes the coefficient field for homology - pcoh.compute_persistent_cohomology( min_persistence ); - stringstream ss; - ss << argv[1] << "_persistence"; - std::ofstream out(ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include +#include + +using namespace std; + + +int main( int argc , char** argv ) +{ + cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbered in \ +the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ +of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ +lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + + int p = 2; + double min_persistence = 0; + + if ( argc != 2 ) + { + cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; + return 1; + } + + Bitmap_cubical_complex b( argv[1] ); + + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + pcoh.compute_persistent_cohomology( min_persistence ); + + + stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out((char*)ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp new file mode 100644 index 00000000..fa60d4f3 --- /dev/null +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp @@ -0,0 +1,72 @@ + /* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include +#include + +using namespace std; + +int main( int argc , char** argv ) +{ + cout << "This program computes persistent homology, by using Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in Perseus style (the only numbered in \ +the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ +of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ +lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + + int p = 2; + double min_persistence = 0; + + if ( argc != 2 ) + { + cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; + return 1; + } + + Bitmap_cubical_complex_periodic_boundary_conditions b( argv[1] ); + + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex_periodic_boundary_conditions, Field_Zp > pcoh(b,true); + pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + pcoh.compute_persistent_cohomology( min_persistence ); + + + stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out((char*)ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index dd252a79..26796e9d 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -10,3 +10,6 @@ add_executable ( Random_bitmap_cubical_complex Random_bitmap_cubical_complex.cpp target_link_libraries(Random_bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY}) add_test(Random_bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Random_bitmap_cubical_complex 2 100 100) +add_executable ( Bitmap_cubical_complex_periodic_boundary_conditions Bitmap_cubical_complex_periodic_boundary_conditions.cpp ) +target_link_libraries(Bitmap_cubical_complex_periodic_boundary_conditions ${Boost_SYSTEM_LIBRARY}) + -- cgit v1.2.3 From 0181c1f8c6122c50f991abea1ec8c4ec6bf392b4 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Wed, 13 Jan 2016 07:39:34 +0000 Subject: First version of a code changed so that it computes persistence of cubical complexes with or without periodic boundary conditions, but do not require duplication of code that link it to Gudhi persistence engine. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@961 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 506db0edd18818287fe110dcd04c15e369b28171 --- src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp | 4 ++-- .../Bitmap_cubical_complex_periodic_boundary_conditions.cpp | 11 +++++++---- .../example/Random_bitmap_cubical_complex.cpp | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index ed141ed9..39a55f24 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -54,11 +54,11 @@ lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for exam return 1; } - Bitmap_cubical_complex b( argv[1] ); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( argv[1] ); // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); pcoh.init_coefficients( p ); //initilizes the coefficient field for homology pcoh.compute_persistent_cohomology( min_persistence ); diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp index fa60d4f3..3d80c96d 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp @@ -22,10 +22,10 @@ #include -#include +#include +#include #include - using namespace Gudhi; using namespace Gudhi::Cubical_complex; using namespace Gudhi::persistent_cohomology; @@ -53,11 +53,14 @@ lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for exam return 1; } - Bitmap_cubical_complex_periodic_boundary_conditions b( argv[1] ); + Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > b( argv[1] ); // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex_periodic_boundary_conditions, Field_Zp > pcoh(b,true); + persistent_cohomology::Persistent_cohomology< + Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > + , Field_Zp + > pcoh(b,true); pcoh.init_coefficients( p ); //initilizes the coefficient field for homology pcoh.compute_persistent_cohomology( min_persistence ); diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp index 36c22344..97347162 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -74,11 +74,11 @@ The program will create random cubical complex of that sizes and compute persist - Bitmap_cubical_complex b( sizes , data ); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( sizes , data ); // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex, Field_Zp > pcoh(b); + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); pcoh.init_coefficients( p ); //initilizes the coefficient field for homology pcoh.compute_persistent_cohomology( min_persistence ); -- cgit v1.2.3 From 5389d8969d8386bb4c74dbef4b7c7992e9130f13 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Mon, 14 Mar 2016 12:59:53 +0000 Subject: Answers to Marc's comments. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1042 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 481841d609bae68df85a93527e6d3cc20f1b06e2 --- .../example/Bitmap_cubical_complex.cpp | 146 ++++----- src/Bitmap_cubical_complex/example/CMakeLists.txt | 4 +- .../include/gudhi/Bitmap_cubical_complex.h | 8 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 355 ++++++++++++--------- ...cal_complex_periodic_boundary_conditions_base.h | 10 + 5 files changed, 288 insertions(+), 235 deletions(-) (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index 39a55f24..4c30ee85 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -1,73 +1,73 @@ - /* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include - - -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; - -//standard stuff -#include -#include -#include - -using namespace std; - - -int main( int argc , char** argv ) -{ - cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbered in \ -the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ -of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ -lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; - - int p = 2; - double min_persistence = 0; - - if ( argc != 2 ) - { - cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; - return 1; - } - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( argv[1] ); - - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); - pcoh.init_coefficients( p ); //initilizes the coefficient field for homology - pcoh.compute_persistent_cohomology( min_persistence ); - - - stringstream ss; - ss << argv[1] << "_persistence"; - std::ofstream out((char*)ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; +using namespace Gudhi::persistent_cohomology; + +//standard stuff +#include +#include +#include + +using namespace std; + + +int main( int argc , char** argv ) +{ + cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbered in \ +the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ +of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ +lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + + int p = 2; + double min_persistence = 0; + + if ( argc != 2 ) + { + cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; + return 1; + } + + Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( argv[1] ); + + // Compute the persistence diagram of the complex + persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); + pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + + pcoh.compute_persistent_cohomology( min_persistence ); + + stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out((char*)ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; +} diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index fbd1b28b..14c94e8e 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -13,5 +13,5 @@ add_test(Random_bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Random_bitmap add_executable ( Bitmap_cubical_complex_periodic_boundary_conditions Bitmap_cubical_complex_periodic_boundary_conditions.cpp ) target_link_libraries(Bitmap_cubical_complex_periodic_boundary_conditions ${Boost_SYSTEM_LIBRARY}) -add_executable ( Compute_persistence_with_phat Compute_persistence_with_phat.cpp ) -target_link_libraries(Compute_persistence_with_phat ${Boost_SYSTEM_LIBRARY}) \ No newline at end of file +#add_executable ( Compute_persistence_with_phat Compute_persistence_with_phat.cpp ) +#target_link_libraries(Compute_persistence_with_phat ${Boost_SYSTEM_LIBRARY}) \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index 70f19e03..4dd295e7 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -23,6 +23,7 @@ #pragma once #include +#include #include "Bitmap_cubical_complex_base.h" #include "Bitmap_cubical_complex_periodic_boundary_conditions_base.h" @@ -127,7 +128,12 @@ public: //If the user decide to change some elements of the bitmap, then this procedure need //to be called again. this->initialize_simplex_associated_to_key(); - } + } + + /** + * Destructor of the Bitmap_cubical_complex class. + **/ + virtual ~Bitmap_cubical_complex(){} //*********************************************// diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index 22b703a9..807be335 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -23,13 +23,14 @@ #pragma once #include +#include #include #include #include #include #include #include -#include +#include #include #include "Bitmap_cubical_complex/counter.h" @@ -43,7 +44,11 @@ namespace Cubical_complex { - +/** + *@class Bitmap_cubical_complex_base + *@brief Cubical complex represented as a bitmap, class with basic implementation. + *@ingroup cubical_complex + */ /** * This is a class implementing a basic bitmap data structure to store cubical complexes. * It implements only the most basic subroutines. @@ -64,13 +69,13 @@ namespace Cubical_complex template class Bitmap_cubical_complex_base { -public: - typedef T filtration_type; - /** - *Default constructor - **/ - Bitmap_cubical_complex_base() - { +public: + typedef T filtration_type; + /** + *Default constructor + **/ + Bitmap_cubical_complex_base() + { } /** * There are a few constructors of a Bitmap_cubical_complex_base class. @@ -92,6 +97,11 @@ public: **/ Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells ); + /** + * Destructor of the Bitmap_cubical_complex_base class. + **/ + virtual ~Bitmap_cubical_complex_base(){} + /** * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell * and get_cell_data are the basic @@ -152,18 +162,27 @@ public: * Writing to stream operator. **/ template - friend ostream& operator << ( ostream & os , const Bitmap_cubical_complex_base& b ); - - + friend ostream& operator << ( ostream & os , const Bitmap_cubical_complex_base& b ); + + /** - * Functions that put the input data to bins. + * Function that put the input data to bins. Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute persistence gets + * worst. When dealing with this type of data, one may want to put different values on cells to some number of bins. The function put_data_toBins( size_t number_of_bins ) + * ais designed for that purpose. The parameter of the function is the number of bins (distinct values) we want to have in the cubical complex. **/ void put_data_toBins( size_t number_of_bins ); - void put_data_toBins( T diameter_of_bin ); - + + /** + * Function that put the input data to bins. Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute persistence gets + * worst. When dealing with this type of data, one may want to put different values on cells to some number of bins. The function put_data_toBins( T diameter_of_bin ) is + * designed for that purpose. The parameter of it is the diameter of each bin. Note that the bottleneck distance between the persistence diagram of the cubical complex + * before and after using such a function will be bounded by the parameter diameter_of_bin. + **/ + void put_data_toBins( T diameter_of_bin ); + /** * Functions to find min and max values of filtration. - **/ + **/ std::pair< T ,T > min_max_filtration(); //ITERATORS @@ -172,42 +191,60 @@ public: * Iterator through all cells in the complex (in order they appear in the structure -- i.e. * in lexicographical order). **/ - typedef typename std::vector< T >::iterator all_cells_iterator; - + typedef typename std::vector< T >::iterator all_cells_iterator; + + /** - * Function returning an iterator to the first cell of the bitmap. + * Constant iterator through all cells in the complex (in order they appear in the structure -- i.e. + * in lexicographical order). **/ - all_cells_iterator all_cells_begin() + typedef typename std::vector< T >::const_iterator all_cells_const_iterator; + + /** + * Function returning a constant iterator to the first cell of the bitmap. + **/ + all_cells_const_iterator all_cells_const_begin()const { return this->data.begin(); - } - - /** - * Function returning an iterator to the last cell of the bitmap. + } + + + /** + * Function returning a constant iterator to the last cell of the bitmap. **/ - all_cells_iterator all_cells_end()const + all_cells_const_iterator all_cells_const_end()const { return this->data.end(); } /** - * Constant iterator through all cells in the complex (in order they appear in the structure -- i.e. - * in lexicographical order). + * Function returning an iterator to the first cell of the bitmap. **/ - typedef typename std::vector< T >::const_iterator all_cells_const_iterator; - + all_cells_iterator all_cells_begin() + { + return this->data.begin(); + } + /** * Function returning a constant iterator to the first cell of the bitmap. **/ - all_cells_const_iterator all_cells_const_begin()const + all_cells_const_iterator all_cells_begin() const { return this->data.begin(); - } - + } + + /** + * Function returning an iterator to the last cell of the bitmap. + **/ + all_cells_iterator all_cells_end() + { + return this->data.end(); + } + /** * Function returning a constant iterator to the last cell of the bitmap. **/ - all_cells_const_iterator all_cells_const_end()const + all_cells_const_iterator all_cells_end() const { return this->data.end(); } @@ -303,8 +340,8 @@ public: protected: std::vector< size_t > counter; Bitmap_cubical_complex_base& b; - }; - + }; + /** * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell cell of the bitmap. **/ @@ -312,8 +349,8 @@ public: { Top_dimensional_cells_iterator a(*this); return a; - } - + } + /** * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell cell of the bitmap. **/ @@ -333,11 +370,11 @@ public: //****************************************************************************************************************// //****************************************************************************************************************// //****************************************************************************************************************// - - -inline size_t number_cells()const -{ - return this->total_number_of_cells; + + +inline size_t number_cells()const +{ + return this->total_number_of_cells; } //****************************************************************************************************************// @@ -375,7 +412,7 @@ protected: std::vector compute_counter_for_given_cell( size_t cell )const { - std::vector counter; + std::vector counter; counter.reserve( this->sizes.size() ); for ( size_t dim = this->sizes.size() ; dim != 0 ; --dim ) { @@ -384,59 +421,59 @@ protected: } std::reverse( counter.begin() , counter.end() ); return counter; - } - void read_perseus_style_file( const char* perseus_style_file ); - void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells); - Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ); - Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ); + } + void read_perseus_style_file( const char* perseus_style_file ); + void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells); + Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ); + Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ); Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells , std::vector directions ); }; -template -void Bitmap_cubical_complex_base::put_data_toBins( size_t number_of_bins ) -{ - bool bdg = false; - - std::pair< T ,T > min_max = this->min_max_filtration(); - T dx = (min_max.second-min_max.first)/(T)number_of_bins; - - //now put the data into the appropriate bins: - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} - this->data[i] = min_max.first + dx*(this->data[i]-min_max.first)/number_of_bins; - if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} - } -} - template -void Bitmap_cubical_complex_base::put_data_toBins( T diameter_of_bin ) -{ - bool bdg = false; - std::pair< T ,T > min_max = this->min_max_filtration(); - - size_t number_of_bins = (min_max.second - min_max.first)/diameter_of_bin; - //now put the data into the appropriate bins: - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} - this->data[i] = min_max.first + diameter_of_bin*(this->data[i]-min_max.first)/number_of_bins; - if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} - } -} - -template -std::pair< T ,T > Bitmap_cubical_complex_base::min_max_filtration() -{ - std::pair< T ,T > min_max( std::numeric_limits::max() , std::numeric_limits::min() ); - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( this->data[i] < min_max.first )min_max.first = this->data[i]; - if ( this->data[i] > min_max.second )min_max.second = this->data[i]; - } - return min_max; -} +void Bitmap_cubical_complex_base::put_data_toBins( size_t number_of_bins ) +{ + bool bdg = false; + + std::pair< T ,T > min_max = this->min_max_filtration(); + T dx = (min_max.second-min_max.first)/(T)number_of_bins; + + //now put the data into the appropriate bins: + for ( size_t i = 0 ; i != this->data.size() ; ++i ) + { + if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} + this->data[i] = min_max.first + dx*(this->data[i]-min_max.first)/number_of_bins; + if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} + } +} + +template +void Bitmap_cubical_complex_base::put_data_toBins( T diameter_of_bin ) +{ + bool bdg = false; + std::pair< T ,T > min_max = this->min_max_filtration(); + + size_t number_of_bins = (min_max.second - min_max.first)/diameter_of_bin; + //now put the data into the appropriate bins: + for ( size_t i = 0 ; i != this->data.size() ; ++i ) + { + if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} + this->data[i] = min_max.first + diameter_of_bin*(this->data[i]-min_max.first)/number_of_bins; + if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} + } +} + +template +std::pair< T ,T > Bitmap_cubical_complex_base::min_max_filtration() +{ + std::pair< T ,T > min_max( std::numeric_limits::max() , std::numeric_limits::min() ); + for ( size_t i = 0 ; i != this->data.size() ; ++i ) + { + if ( this->data[i] < min_max.first )min_max.first = this->data[i]; + if ( this->data[i] > min_max.second )min_max.second = this->data[i]; + } + return min_max; +} template @@ -457,10 +494,10 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base { this->set_up_containers( sizes ); } - -template -void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells) -{ + +template +void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells) +{ this->set_up_containers( sizes_in_following_directions ); size_t number_of_top_dimensional_elements = 1; @@ -489,19 +526,19 @@ void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells (*it) = top_dimensional_cells[index]; ++index; } - this->impose_lower_star_filtration(); -} + this->impose_lower_star_filtration(); +} template Bitmap_cubical_complex_base::Bitmap_cubical_complex_base ( const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells ) { this->setup_bitmap_based_on_top_dimensional_cells_list( sizes_in_following_directions , top_dimensional_cells ); -} - -template -void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseus_style_file ) -{ +} + +template +void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseus_style_file ) +{ bool dbg = false; ifstream inFiltration, inIds; inFiltration.open( perseus_style_file ); @@ -510,7 +547,7 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;getchar();} - std::vector sizes; + std::vector sizes; sizes.reserve( dimensionOfData ); for ( size_t i = 0 ; i != dimensionOfData ; ++i ) { @@ -541,31 +578,31 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu ++it; } inFiltration.close(); - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->read_perseus_style_file( perseus_style_file ); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->set_up_containers( sizes ); -} - -template + this->impose_lower_star_filtration(); +} + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ) +{ + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->read_perseus_style_file( perseus_style_file ); +} + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ) +{ + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->set_up_containers( sizes ); +} + +template Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->setup_bitmap_based_on_top_dimensional_cells_list( dimensions , top_dimensional_cells ); +{ + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->setup_bitmap_based_on_top_dimensional_cells_list( dimensions , top_dimensional_cells ); } template @@ -578,29 +615,29 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus template std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( size_t cell )const { - std::vector< size_t > boundary_elements; - - //Speed traded of for memory. Check if it is better in practice. - boundary_elements.reserve( this->dimension()*2 ); + std::vector< size_t > boundary_elements; + + //Speed traded of for memory. Check if it is better in practice. + boundary_elements.reserve( this->dimension()*2 ); size_t cell1 = cell; for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) { unsigned position = cell1/this->multipliers[i-1]; if ( position%2 == 1 ) - { - boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); + { + boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); boundary_elements.push_back( cell + this->multipliers[ i-1 ] ); } cell1 = cell1%this->multipliers[i-1]; } return boundary_elements; -} +} + + + - - - template std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( size_t cell )const { @@ -625,8 +662,8 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( cell1 = cell1%this->multipliers[i-1]; } return coboundary_elements; -} - +} + @@ -675,14 +712,14 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() //this vector will be used to check which elements have already been taken care of //in imposing lower star filtration: std::vector is_this_cell_considered( this->data.size() , false ); - - size_t size_to_reserve = 1; - for ( size_t i = 0 ; i != this->multipliers.size() ; ++i ) - { - size_to_reserve *= (size_t)((this->multipliers[i]-1)/2); - } - - std::vector indices_to_consider; + + size_t size_to_reserve = 1; + for ( size_t i = 0 ; i != this->multipliers.size() ; ++i ) + { + size_to_reserve *= (size_t)((this->multipliers[i]-1)/2); + } + + std::vector indices_to_consider; indices_to_consider.reserve( size_to_reserve ); //we assume here that we already have a filtration on the top dimensional cells and //we have to extend it to lower ones. @@ -708,20 +745,20 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() { std::vector bd = this->get_boundary_of_a_cell( indices_to_consider[i] ); for ( size_t boundaryIt = 0 ; boundaryIt != bd.size() ; ++boundaryIt ) - { - if ( dbg ) - { - cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ] << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ] << endl; - getchar(); - + { + if ( dbg ) + { + cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ] << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ] << endl; + getchar(); + } if ( this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ] ) { - this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; - if ( dbg ) - { - cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " << this->data[ indices_to_consider[i] ] << endl; - getchar(); + this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; + if ( dbg ) + { + cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " << this->data[ indices_to_consider[i] ] << endl; + getchar(); } } if ( is_this_cell_considered[ bd[boundaryIt] ] == false ) @@ -760,4 +797,4 @@ bool compareFirstElementsOfTuples( const std::pair< std::pair< T , size_t > , ch } -} +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h index f0fd785f..8c1254db 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h @@ -37,6 +37,11 @@ namespace Cubical_complex //right / top are not in the Bitmap_cubical_complex_periodic_boundary_conditions_base +/** + *@class Bitmap_cubical_complex_periodic_boundary_conditions_base + *@brief Cubical complex with periodic boundary conditions represented as a bitmap. + *@ingroup cubical_complex + */ /** * This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the functions are identical to the functions from Bitmap_cubical_complex_base. * The ones that needed to be updated are the constructors and get_boundary_of_a_cell and get_coboundary_of_a_cell. @@ -64,6 +69,11 @@ public: */ Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& dimensions , const std::vector& topDimensionalCells , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ); + /** + * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class. + **/ + virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base(){} + //overwritten methods co compute boundary and coboundary /** * A version of a function that return boundary of a given cell for an object of Bitmap_cubical_complex_periodic_boundary_conditions_base class. -- cgit v1.2.3 From d1a3b2267b7e638b5d868720cf46987641b22132 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 29 Mar 2016 16:05:12 +0000 Subject: Merge VR_bitmap git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1074 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4c9ac225ffcfb924371c72fccc44cbd6ecb3d6e3 --- .../doc/Gudhi_Cubical_Complex_doc.h | 160 +- .../example/Bitmap_cubical_complex.cpp | 107 +- ...ubical_complex_periodic_boundary_conditions.cpp | 134 +- src/Bitmap_cubical_complex/example/CMakeLists.txt | 11 +- .../example/Random_bitmap_cubical_complex.cpp | 159 +- .../include/gudhi/Bitmap_cubical_complex.h | 1060 +++++------ .../include/gudhi/Bitmap_cubical_complex_base.h | 1499 ++++++++-------- ...cal_complex_periodic_boundary_conditions_base.h | 625 +++---- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 1837 +++++++++----------- 9 files changed, 2663 insertions(+), 2929 deletions(-) (limited to 'src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp') diff --git a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h index 00b39f01..cde0b2fc 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -21,64 +21,87 @@ */ -#pragma once +#ifndef DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_ +#define DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_ -namespace Gudhi -{ +namespace Gudhi { -namespace Cubical_complex -{ +namespace Cubical_complex { /** \defgroup cubical_complex Cubical complex -* -* \author Pawel Dlotko -* -* @{ -* - -*Bitmap_cubical_complex is an example of a structured complex useful in computational mathematics (specially rigorous numerics) and image analysis. The presented implementation of cubical complexes is based on the following definition. -* -* An elementary interval is an interval of a form \f$ [n,n+1] \f$, or \f$[n,n]\f$, for \f$ n \in \mathcal{Z} \f$. The first one is called non-degenerate, while the second one is \a degenerate interval. A boundary of a elementary -*interval is a chain \f$\partial [n,n+1] = [n+1,n+1]-[n,n] \f$ in case of non-degenerate elementary interval and \f$\partial [n,n] = 0 \f$ in case of degenerate elementary interval. An elementary cube \f$ C \f$ is a + * + * \author Pawel Dlotko + * + * @{ + * -*product of elementary intervals, \f$C=I_1 \times \ldots \times I_n\f$. Embedding dimension of a cube is n, the number of elementary intervals (degenerate or not) in the product. A dimension of a cube \f$C=I_1 \times ... \times I_n\f$ is the -*number of non degenerate elementary intervals in the product. A boundary of a cube \f$C=I_1 \times \ldots \times I_n\f$ is a chain obtained in the following way: -*\f[\partial C = (\partial I_1 \times \ldots \times I_n) + (I_1 \times \partial I_2 \times \ldots \times I_n) + \ldots + (I_1 \times I_2 \times \ldots \times \partial I_n).\f] -*A cubical complex \f$\mathcal{K}\f$ is a collection of cubes closed under operation of taking boundary (i.e. boundary of every cube from the collection is in the collection). A cube \f$C\f$ in cubical complex \f$\mathcal{K}\f$ is maximal if it is not in -*a boundary of any other cube in \f$\mathcal{K}\f$. A \a support of a cube \f$C\f$ is the set in \f$\mathbb{R}^n\f$ occupied by \f$C\f$ (\f$n\f$ is the embedding dimension of \f$C\f$). -* -*Cubes may be equipped with a filtration values in which case we have filtered cubical complex. All the cubical complexes considered in this implementation are filtered cubical complexes (although, the range of a filtration may be a set of two elements). -* -*For further details and theory of cubical complexes, please consult \cite kaczynski2004computational as well as the following paper \cite peikert2012topological . -* -*\section datastructure Data structure. -* -*The implementation of Cubical complex provides a representation of complexes that occupy a rectangular region in \f$\mathbb{R}^n\f$. This extra -*assumption allows for a memory efficient way of storing cubical complexes in a form of so called bitmaps. Let \f$R = [b_1,e_1] \times \ldots \times [b_n,e_n]\f$, for \f$b_1,...b_n,e_1,...,e_n \in \mathbb{Z}\f$ -*, \f$b_i \leq d_i\f$ be the considered rectangular region and let \f$\mathcal{K}\f$ be a filtered cubical complex having the rectangle \f$R\f$ as its support. Note that the structure of the coordinate system gives a way -*a lexicographical ordering of cells of \f$\mathcal{K}\f$. This ordering is a base of the presented bitmap-based implementation. In this implementation, the whole cubical complex is stored as a vector -*of the values of filtration. This, together with dimension of \f$\mathcal{K}\f$ and the sizes of \f$\mathcal{K}\f$ in all directions, allows to determine, dimension, neighborhood, boundary and coboundary of every cube \f$C \in \mathcal{K}\f$. -* -*\image html "bitmapAllCubes.png" "Cubical complex. -* -*Note that the cubical complex in the figure above is, in a natural way, a product of one dimensional cubical complexes in \f$\mathbb{R}\f$. The number of all cubes in each direction is -*equal \f$2n+1\f$, where \f$n\f$ is the number of maximal cubes in the considered direction. Let us consider a cube at the position \f$k\f$ in the bitmap. Knowing the sizes of the bitmap, -*by a series of modulo operation, we can determine which elementary intervals are present in the product that gives the cube \f$C\f$. In a similar way, we can compute boundary -*and the coboundary of each cube. Further details can be found in the literature. -* -*\section inputformat Input Format. -* -*In the current implantation, filtration is given at the maximal cubes, and it is then extended by the lower star filtration to all cubes. There are a number of constructors -*that can be used to construct cubical complex by users who want to use the code directly. They can be found in the \a Bitmap_cubical_complex class. -*Currently one input from a text file is used. It uses a format used already in Perseus software (http://www.sas.upenn.edu/~vnanda/perseus/) by Vidit Nanda. -*Below we are providing a description of the format. The first line contains a number d begin the dimension of the bitmap (2 in the example below). Next d lines are the numbers of -*top dimensional cubes in each dimensions (3 and 3 in the example below). Next, in lexicographical order, the filtration of top dimensional cubes is given (1 4 6 8 20 4 7 6 5 in the example below). -* -* -*\image html "exampleBitmap.png" "Example of a input data." -* -*The input file for the following complex is: -*\verbatim + * Bitmap_cubical_complex is an example of a structured complex useful in computational mathematics (specially rigorous + * numerics) and image analysis. The presented implementation of cubical complexes is based on the following + * definition. + * + * An elementary interval is an interval of a form \f$ [n,n+1] \f$, or \f$[n,n]\f$, for \f$ n \in \mathcal{Z} + * \f$. The first one is called non-degenerate, while the second one is \a degenerate interval. A + * boundary of a elementary interval is a chain \f$\partial [n,n+1] = [n+1,n+1]-[n,n] \f$ in case of + * non-degenerated elementary interval and \f$\partial [n,n] = 0 \f$ in case of degenerate elementary interval. An + * elementary cube \f$ C \f$ is a product of elementary intervals, \f$C=I_1 \times \ldots \times I_n\f$. + * Embedding dimension of a cube is n, the number of elementary intervals (degenerate or not) in the product. + * A dimension of a cube \f$C=I_1 \times ... \times I_n\f$ is the number of non degenerate elementary + * intervals in the product. A boundary of a cube \f$C=I_1 \times \ldots \times I_n\f$ is a chain obtained + * in the following way: + * \f[\partial C = (\partial I_1 \times \ldots \times I_n) + (I_1 \times \partial I_2 \times \ldots \times I_n) + + * \ldots + (I_1 \times I_2 \times \ldots \times \partial I_n).\f] + * A cubical complex \f$\mathcal{K}\f$ is a collection of cubes closed under operation of taking boundary + * (i.e. boundary of every cube from the collection is in the collection). A cube \f$C\f$ in cubical complex + * \f$\mathcal{K}\f$ is maximal if it is not in a boundary of any other cube in \f$\mathcal{K}\f$. A \a + * support of a cube \f$C\f$ is the set in \f$\mathbb{R}^n\f$ occupied by \f$C\f$ (\f$n\f$ is the embedding dimension + * of \f$C\f$). + * + * Cubes may be equipped with a filtration values in which case we have filtered cubical complex. All the cubical + * complexes considered in this implementation are filtered cubical complexes (although, the range of a filtration may + * be a set of two elements). + * + * For further details and theory of cubical complexes, please consult \cite kaczynski2004computational as well as the + * following paper \cite peikert2012topological . + * + * \section datastructure Data structure. + * + * The implementation of Cubical complex provides a representation of complexes that occupy a rectangular region in + * \f$\mathbb{R}^n\f$. This extra assumption allows for a memory efficient way of storing cubical complexes in a form + * of so called bitmaps. Let \f$R = [b_1,e_1] \times \ldots \times [b_n,e_n]\f$, for \f$b_1,...b_n,e_1,...,e_n \in + * \mathbb{Z}\f$, \f$b_i \leq d_i\f$ be the considered rectangular region and let \f$\mathcal{K}\f$ be a filtered + * cubical complex having the rectangle \f$R\f$ as its support. Note that the structure of the coordinate system gives + * a way a lexicographical ordering of cells of \f$\mathcal{K}\f$. This ordering is a base of the presented + * bitmap-based implementation. In this implementation, the whole cubical complex is stored as a vector of the values + * of filtration. This, together with dimension of \f$\mathcal{K}\f$ and the sizes of \f$\mathcal{K}\f$ in all + * directions, allows to determine, dimension, neighborhood, boundary and coboundary of every cube \f$C \in + * \mathcal{K}\f$. + * + * \image html "bitmapAllCubes.png" "Cubical complex. + * + * Note that the cubical complex in the figure above is, in a natural way, a product of one dimensional cubical + * complexes in \f$\mathbb{R}\f$. The number of all cubes in each direction is equal \f$2n+1\f$, where \f$n\f$ is the + * number of maximal cubes in the considered direction. Let us consider a cube at the position \f$k\f$ in the bitmap. + * Knowing the sizes of the bitmap, by a series of modulo operation, we can determine which elementary intervals are + * present in the product that gives the cube \f$C\f$. In a similar way, we can compute boundary and the coboundary of + * each cube. Further details can be found in the literature. + * + * \section inputformat Input Format. + * + * In the current implantation, filtration is given at the maximal cubes, and it is then extended by the lower star + * filtration to all cubes. There are a number of constructors that can be used to construct cubical complex by users + * who want to use the code directly. They can be found in the \a Bitmap_cubical_complex class. + * Currently one input from a text file is used. It uses a format used already in Perseus software + * (http://www.sas.upenn.edu/~vnanda/perseus/) by Vidit Nanda. + * Below we are providing a description of the format. The first line contains a number d begin the dimension of the + * bitmap (2 in the example below). Next d lines are the numbers of top dimensional cubes in each dimensions (3 and 3 + * in the example below). Next, in lexicographical order, the filtration of top dimensional cubes is given (1 4 6 8 + * 20 4 7 6 5 in the example below). + * + * + * \image html "exampleBitmap.png" "Example of a input data." + * + * The input file for the following complex is: + * \verbatim 2 3 3 @@ -93,15 +116,17 @@ namespace Cubical_complex 5 \endverbatim -\section PeriodicBoundaryConditions Periodic boundary conditions -Often one would like to impose periodic boundary conditions to the cubical complex. Let \f$ I_1\times ... \times I_n \f$ be a box -that is decomposed with a cubical complex \f$ \mathcal{K} \f$. Imposing periodic boundary conditions in the direction i, means that the left and the right side of a complex -\f$ \mathcal{K} \f$ are considered the same. In particular, if for a bitmap \f$ \mathcal{K} \f$ periodic boundary conditions are imposed in all directions, then complex -\f$ \mathcal{K} \f$ became n-dimensional torus. One can use various constructors from the file Bitmap_cubical_complex_periodic_boundary_conditions_base.h to construct cubical -complex with periodic boundary conditions. One can also use Perseus style input files. To indicate periodic boundary conditions in a given direction, then number of top dimensional cells -in this direction have to be multiplied by -1. For instance: + * \section PeriodicBoundaryConditions Periodic boundary conditions + * Often one would like to impose periodic boundary conditions to the cubical complex. Let \f$ I_1\times ... \times + * I_n \f$ be a box that is decomposed with a cubical complex \f$ \mathcal{K} \f$. Imposing periodic boundary + * conditions in the direction i, means that the left and the right side of a complex \f$ \mathcal{K} \f$ are + * considered the same. In particular, if for a bitmap \f$ \mathcal{K} \f$ periodic boundary conditions are imposed + * in all directions, then complex \f$ \mathcal{K} \f$ became n-dimensional torus. One can use various constructors + * from the file Bitmap_cubical_complex_periodic_boundary_conditions_base.h to construct cubical complex with periodic + * boundary conditions. One can also use Perseus style input files. To indicate periodic boundary conditions in a + * given direction, then number of top dimensional cells in this direction have to be multiplied by -1. For instance: -*\verbatim + *\verbatim 2 -3 3 @@ -116,15 +141,16 @@ in this direction have to be multiplied by -1. For instance: 5 \endverbatim -Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. + * Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. * \section BitmapExamples Examples * End user programs are available in example/Bitmap_cubical_complex folder. - -*/ + */ /** @} */ // end defgroup cubical_complex -*@}//end of the group -} -} +} // namespace Cubical_complex + +} // namespace Gudhi + +#endif // DOC_GUDHI_CUBICAL_COMPLEX_COMPLEX_H_ diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp index 4c30ee85..7c7e8ac5 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp @@ -1,73 +1,72 @@ - /* 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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include -#include #include #include - -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; - -//standard stuff +// standard stuff #include #include #include -using namespace std; +int main(int argc, char** argv) { + std::cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " << + "complexes provided in text files in Perseus style (the only numbered in the first line is a dimension D of a" << + "bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let " << + "N denote product of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are " << + "filtrations of top dimensional cells. We assume that the cells are in the lexicographical order. See " << + "CubicalOneSphere.txt or CubicalTwoSphere.txt for example.\n" << std::endl; + int p = 2; + double min_persistence = 0; -int main( int argc , char** argv ) -{ - cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes provided in text files in Perseus style (the only numbered in \ -the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ -of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ -lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; + if (argc != 2) { + std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " << + "the input. The program will now terminate.\n"; + return 1; + } - int p = 2; - double min_persistence = 0; + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base Bitmap_cubical_complex_base; + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex Bitmap_cubical_complex; + typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp; + typedef Gudhi::persistent_cohomology::Persistent_cohomology Persistent_cohomology; - if ( argc != 2 ) - { - cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; - return 1; - } + Bitmap_cubical_complex b(argv[1]); - Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( argv[1] ); + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(b); + pcoh.init_coefficients(p); // initializes the coefficient field for homology + pcoh.compute_persistent_cohomology(min_persistence); - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); - pcoh.init_coefficients( p ); //initilizes the coefficient field for homology + std::stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out(ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); - pcoh.compute_persistent_cohomology( min_persistence ); + std::cout << "Result in file: " << ss.str().c_str() << "\n"; - stringstream ss; - ss << argv[1] << "_persistence"; - std::ofstream out((char*)ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 0; + return 0; } + diff --git a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp index df01240b..2c5d7fd3 100644 --- a/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp +++ b/src/Bitmap_cubical_complex/example/Bitmap_cubical_complex_periodic_boundary_conditions.cpp @@ -1,24 +1,24 @@ - /* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include @@ -26,59 +26,49 @@ #include #include -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; - -//standard stuff +// standard stuff #include #include #include -using namespace std; - -int main( int argc , char** argv ) -{ - clock_t beginOfProgram = clock(); - - cout << "This program computes persistent homology, by using Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in Perseus style (the only numbered in \ -the first line is a dimension D of a bitmap. In the lines I between 2 and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product \ -of the numbers in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We assume that the cells are in the \ -lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for example." << endl; - - int p = 2; - double min_persistence = 0; - - if ( argc != 2 ) - { - cout << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at the input. The program will now terminate.\n"; - return 1; - } - - Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > b( argv[1] ); - - cerr << "Here \n"; - - clock_t endCreateBitmap = clock(); - double elapsed_secsCreateBitmap = double(endCreateBitmap - beginOfProgram) / CLOCKS_PER_SEC; - cerr << "Time of creation of bitmap : " << elapsed_secsCreateBitmap << endl; - - - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base >, Field_Zp > pcoh(b,true); - pcoh.init_coefficients( p ); //initilizes the coefficient field for homology - pcoh.compute_persistent_cohomology( min_persistence ); - - - stringstream ss; - ss << argv[1] << "_persistence"; - std::ofstream out((char*)ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - clock_t endOfProgram = clock(); - double elapsed_secsOfProgram = double(endOfProgram - beginOfProgram) / CLOCKS_PER_SEC; - cerr << "Overall execution time : " << elapsed_secsOfProgram << endl; - return 0; +int main(int argc, char** argv) { + std::cout << "This program computes persistent homology, by using " << + "Bitmap_cubical_complex_periodic_boundary_conditions class, of cubical complexes provided in text files in " << + "Perseus style (the only numbered in the first line is a dimension D of a bitmap. In the lines I between 2 " << + "and D+1 there are numbers of top dimensional cells in the direction I. Let N denote product of the numbers " << + "in the lines between 2 and D. In the lines D+2 to D+2+N there are filtrations of top dimensional cells. We " << + "assume that the cells are in the lexicographical order. See CubicalOneSphere.txt or CubicalTwoSphere.txt for" << + " example.\n" << std::endl; + + int p = 2; + double min_persistence = 0; + + if (argc != 2) { + std::cerr << "Wrong number of parameters. Please provide the name of a file with a Perseus style bitmap at " << + "the input. The program will now terminate.\n"; + return 1; + } + + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base Bitmap_base; + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex< Bitmap_base > Bitmap_cubical_complex; + + Bitmap_cubical_complex b(argv[1]); + + typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp; + typedef Gudhi::persistent_cohomology::Persistent_cohomology Persistent_cohomology; + // Compute the persistence diagram of the complex + Persistent_cohomology pcoh(b, true); + pcoh.init_coefficients(p); // initializes the coefficient field for homology + pcoh.compute_persistent_cohomology(min_persistence); + + std::stringstream ss; + ss << argv[1] << "_persistence"; + std::ofstream out(ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + std::cout << "Result in file: " << ss.str().c_str() << "\n"; + + return 0; } + diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index 088e6fbd..8f9cfa80 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -3,8 +3,8 @@ project(GUDHIBitmap) add_executable ( Bitmap_cubical_complex Bitmap_cubical_complex.cpp ) target_link_libraries(Bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY}) -add_test(Bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalOneSphere.txt) -add_test(Bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) +add_test(Bitmap_cubical_complex_one_sphere ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalOneSphere.txt) +add_test(Bitmap_cubical_complex_two_sphere ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) add_executable ( Random_bitmap_cubical_complex Random_bitmap_cubical_complex.cpp ) target_link_libraries(Random_bitmap_cubical_complex ${Boost_SYSTEM_LIBRARY}) @@ -12,9 +12,6 @@ add_test(Random_bitmap_cubical_complex ${CMAKE_CURRENT_BINARY_DIR}/Random_bitmap add_executable ( Bitmap_cubical_complex_periodic_boundary_conditions Bitmap_cubical_complex_periodic_boundary_conditions.cpp ) target_link_libraries(Bitmap_cubical_complex_periodic_boundary_conditions ${Boost_SYSTEM_LIBRARY}) +add_test(Bitmap_cubical_complex_periodic_2d_torus ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex_periodic_boundary_conditions ${CMAKE_SOURCE_DIR}/data/bitmap/2d_torus.txt) +add_test(Bitmap_cubical_complex_periodic_3d_torus ${CMAKE_CURRENT_BINARY_DIR}/Bitmap_cubical_complex_periodic_boundary_conditions ${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt) -#add_executable ( Compute_persistence_with_phat Compute_persistence_with_phat.cpp ) -#target_link_libraries(Compute_persistence_with_phat ${Boost_SYSTEM_LIBRARY}) - -#add_executable ( periodic_boundary_conditions_phat periodic_boundary_conditions_phat.cpp ) -#target_link_libraries(periodic_boundary_conditions_phat ${Boost_SYSTEM_LIBRARY}) \ No newline at end of file diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp index 8b7f6a04..416ad8f2 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -1,94 +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): Pawel Dlotko - * - * Copyright (C) 2015 INRIA Saclay (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -//for persistence algorithm +/* 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): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +// for persistence algorithm #include #include #include - -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; - -//standard stuff +// standard stuff #include #include #include -using namespace std; - -int main( int argc , char** argv ) -{ - srand( time(0) ); - - cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical complexes. \ -The first parameter of the program is the dimension D of the bitmap. \ -The next D parameters are number of top dimensional cubes in each dimension of the bitmap.\ -The program will create random cubical complex of that sizes and compute persistent homology of it." << endl; - - int p = 2; - double min_persistence = 0; - - if ( argc < 3 ) - { - cerr << "Wrong number of parameters, the program will now terminate\n"; - return 1; - } - - size_t dimensionOfBitmap = (size_t)atoi( argv[1] ); - std::vector< unsigned > sizes; - size_t multipliers = 1; - for ( size_t dim = 0 ; dim != dimensionOfBitmap ; ++dim ) - { - unsigned sizeInThisDimension = (unsigned)atoi( argv[2+dim] ); - sizes.push_back( sizeInThisDimension ); - multipliers *= sizeInThisDimension; - } - - std::vector< double > data; - for ( size_t i = 0 ; i != multipliers ; ++i ) - { - data.push_back( rand()/(double)RAND_MAX ); - } - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( sizes , data ); - - - - - - // Compute the persistence diagram of the complex - persistent_cohomology::Persistent_cohomology< Bitmap_cubical_complex< Bitmap_cubical_complex_base >, Field_Zp > pcoh(b); - pcoh.init_coefficients( p ); //initilizes the coefficient field for homology - pcoh.compute_persistent_cohomology( min_persistence ); - - - stringstream ss; - ss << "randomComplex_persistence"; - std::ofstream out(ss.str().c_str()); - pcoh.output_diagram(out); - out.close(); - - return 0; +int main(int argc, char** argv) { + srand(time(0)); + + std::cout << "This program computes persistent homology, by using bitmap_cubical_complex class, of cubical " << + "complexes. The first parameter of the program is the dimension D of the bitmap. The next D parameters are " << + "number of top dimensional cubes in each dimension of the bitmap. The program will create random cubical " << + "complex of that sizes and compute persistent homology of it." << std::endl; + + int p = 2; + double min_persistence = 0; + + if (argc < 3) { + std::cerr << "Wrong number of parameters, the program will now terminate\n"; + return 1; + } + + size_t dimensionOfBitmap = (size_t) atoi(argv[1]); + std::vector< unsigned > sizes; + size_t multipliers = 1; + for (size_t dim = 0; dim != dimensionOfBitmap; ++dim) { + unsigned sizeInThisDimension = (unsigned) atoi(argv[2 + dim]); + sizes.push_back(sizeInThisDimension); + multipliers *= sizeInThisDimension; + } + + std::vector< double > data; + for (size_t i = 0; i != multipliers; ++i) { + data.push_back(rand() / static_cast(RAND_MAX)); + } + + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base Bitmap_cubical_complex_base; + typedef Gudhi::Cubical_complex::Bitmap_cubical_complex Bitmap_cubical_complex; + Bitmap_cubical_complex b(sizes, data); + + // Compute the persistence diagram of the complex + typedef Gudhi::persistent_cohomology::Field_Zp Field_Zp; + typedef Gudhi::persistent_cohomology::Persistent_cohomology Persistent_cohomology; + Persistent_cohomology pcoh(b); + pcoh.init_coefficients(p); // initializes the coefficient field for homology + pcoh.compute_persistent_cohomology(min_persistence); + + std::stringstream ss; + ss << "randomComplex_persistence"; + std::ofstream out(ss.str().c_str()); + pcoh.output_diagram(out); + out.close(); + + return 0; } + diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h index 4dd295e7..1fd36914 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -20,28 +20,28 @@ * along with this program. If not, see . */ +#ifndef BITMAP_CUBICAL_COMPLEX_H_ +#define BITMAP_CUBICAL_COMPLEX_H_ -#pragma once -#include -#include -#include "Bitmap_cubical_complex_base.h" -#include "Bitmap_cubical_complex_periodic_boundary_conditions_base.h" - +#include +#include +#include +#include // for pair<> +#include // for sort +#include -namespace Gudhi -{ +namespace Gudhi { -namespace Cubical_complex -{ +namespace Cubical_complex { -//global variable, was used just for debugging. +// global variable, was used just for debugging. const bool globalDbg = false; -template class is_before_in_filtration; - +template class is_before_in_filtration; + /** -* This is a Bitmap_cubical_complex class. It joints a functionalities of Bitmap_cubical_complex_base and Bitmap_cubical_complex_periodic_boundary_conditions_base classes into +* This is a Bitmap_cubical_complex class. It joints a functionalities of Bitmap_cubical_complex_base and Bitmap_cubical_complex_periodic_boundary_conditions_base classes into * Gudhi persistent homology engine. It is a template class that inherit from its template parameter. The template parameter is supposed to be either Bitmap_cubical_complex_base or Bitmap_cubical_complex_periodic_boundary_conditions_base class. **/ @@ -51,529 +51,533 @@ template class is_before_in_filtration; *@ingroup cubical_complex */ template -class Bitmap_cubical_complex : public T -{ -public: -//*********************************************// -//Typedefs and typenames -//*********************************************// - typedef size_t Simplex_key; - typedef typename T::filtration_type Filtration_value; - typedef Simplex_key Simplex_handle; - - -//*********************************************// -//Constructors -//*********************************************// - //Over here we need to definie various input types. I am proposing the following ones: - //Perseus style - //H5 files? TODO - //binary files with little endiangs / big endians? TODO - //constructor from a vector of elements of a type T. TODO - - /** - * Constructor form a Perseus-style file. - **/ - Bitmap_cubical_complex( const char* perseus_style_file ): - T(perseus_style_file),key_associated_to_simplex(this->total_number_of_cells+1) - { - //clock_t begin = clock(); - if ( globalDbg ){cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n";} - for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) - { - this->key_associated_to_simplex[i] = i; - } - //we initialize this only once, in each constructor, when the bitmap is constructed. - //If the user decide to change some elements of the bitmap, then this procedure need - //to be called again. - this->initialize_simplex_associated_to_key(); - //cerr << "Time of running Bitmap_cubical_complex( const char* perseus_style_file ) constructor : " << double(clock() - begin) / CLOCKS_PER_SEC << endl; - } - - - /** - * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells - * in the following directions and vector of element of a type T - * with filtration on top dimensional cells. - **/ - Bitmap_cubical_complex( const std::vector& dimensions , const std::vector& top_dimensional_cells ): - T(dimensions,top_dimensional_cells), - key_associated_to_simplex(this->total_number_of_cells+1) - { - for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) - { - this->key_associated_to_simplex[i] = i; - } - //we initialize this only once, in each constructor, when the bitmap is constructed. - //If the user decide to change some elements of the bitmap, then this procedure need - //to be called again. - this->initialize_simplex_associated_to_key(); - } - - /** - * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells - * in the following directions and vector of element of a type T::filtration_type - * with filtration on top dimensional cells. The last parameter of the constructor is a vector of bools of a length equal to the dimension of cubical complex. - * If the position i on this vector is true, then we impose periodic boundary conditions in this direction. - **/ - Bitmap_cubical_complex( const std::vector& dimensions , const std::vector& top_dimensional_cells , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ): - T(dimensions,top_dimensional_cells,directions_in_which_periodic_b_cond_are_to_be_imposed), - key_associated_to_simplex(this->total_number_of_cells+1) - { - for ( size_t i = 0 ; i != this->total_number_of_cells ; ++i ) - { - this->key_associated_to_simplex[i] = i; - } - //we initialize this only once, in each constructor, when the bitmap is constructed. - //If the user decide to change some elements of the bitmap, then this procedure need - //to be called again. - this->initialize_simplex_associated_to_key(); - } - - /** - * Destructor of the Bitmap_cubical_complex class. - **/ - virtual ~Bitmap_cubical_complex(){} - - -//*********************************************// -//Other 'easy' functions -//*********************************************// - /** - * Returns number of all cubes in the complex. - **/ - size_t num_simplices()const - { - return this->total_number_of_cells; - } - - /** - * Returns a Simplex_handle to a cube that do not exist in this complex. - **/ - static Simplex_handle null_simplex() - { - if ( globalDbg ){cerr << "Simplex_handle null_simplex()\n";} - return std::numeric_limits::max(); - } - - - /** - * Returns dimension of the complex. - **/ - inline size_t dimension()const - { - return this->sizes.size(); - } - - /** - * Return dimension of a cell pointed by the Simplex_handle. - **/ - inline unsigned dimension(Simplex_handle sh)const - { - if ( globalDbg ){cerr << "unsigned dimension(const Simplex_handle& sh)\n";} - if ( sh != std::numeric_limits::max() ) return this->get_dimension_of_a_cell( sh ); - return -1; - } - - /** - * Return the filtration of a cell pointed by the Simplex_handle. - **/ - typename T::filtration_type filtration(Simplex_handle sh) - { - if ( globalDbg ){cerr << "T::filtration_type filtration(const Simplex_handle& sh)\n";} - //Returns the filtration value of a simplex. - if ( sh != std::numeric_limits::max() ) return this->data[sh]; - return std::numeric_limits::max(); - } - - /** - * Return a key which is not a key of any cube in the considered data structure. - **/ - static Simplex_key null_key() - { - if ( globalDbg ){cerr << "Simplex_key null_key()\n";} - return std::numeric_limits::max(); - } - - /** - * Return the key of a cube pointed by the Simplex_handle. - **/ - Simplex_key key(Simplex_handle sh)const - { - if ( globalDbg ){cerr << "Simplex_key key(const Simplex_handle& sh)\n";} - if ( sh != std::numeric_limits::max() ) - { - return this->key_associated_to_simplex[sh]; - } - return this->null_key(); - } - - /** - * Return the Simplex_handle given the key of the cube. - **/ - Simplex_handle simplex(Simplex_key key) - { - if ( globalDbg ){cerr << "Simplex_handle simplex(Simplex_key key)\n";} - if ( key != std::numeric_limits::max() ) - { - return this->simplex_associated_to_key[ key ]; - } - return null_simplex(); - } - - /** - * Assign key to a cube pointed by the Simplex_handle - **/ - void assign_key(Simplex_handle sh, Simplex_key key) - { - if ( globalDbg ){cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n";} - if ( key == std::numeric_limits::max() ) return; - this->key_associated_to_simplex[sh] = key; - this->simplex_associated_to_key[key] = sh; - } - - /** - * Function called from a constructor. It is needed for Filtration_simplex_iterator to work. - **/ - void initialize_simplex_associated_to_key(); - - - -//*********************************************// -//Iterators -//*********************************************// - - - - /** - * Boundary_simplex_range class provides ranges for boundary iterators. - **/ - typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; - typedef typename std::vector< Simplex_handle > Boundary_simplex_range; - - - - /** - * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. - * Secondary criteria for filtration are: - * (1) Dimension of a cube (lower dimensional comes first). - * (2) Position in the data structure (the ones that are earlies in the data structure comes first). - **/ - class Filtration_simplex_range; - class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > - { - //Iterator over all simplices of the complex in the order of the indexing scheme. - //'value_type' must be 'Simplex_handle'. - public: - Filtration_simplex_iterator( Bitmap_cubical_complex* b ):b(b),position(0){}; - Filtration_simplex_iterator():b(NULL){}; - - Filtration_simplex_iterator operator++() - { - if ( globalDbg ){cerr << "Filtration_simplex_iterator operator++\n";} - ++this->position; - return (*this); - } - Filtration_simplex_iterator operator++(int) - { - Filtration_simplex_iterator result = *this; - ++(*this); - return result; - } - Filtration_simplex_iterator operator =( const Filtration_simplex_iterator& rhs ) - { - if ( globalDbg ){cerr << "Filtration_simplex_iterator operator =\n";} - this->b = rhs.b; - this->position = rhs.position; - } - bool operator == ( const Filtration_simplex_iterator& rhs )const - { - if ( globalDbg ){cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n";} - return ( this->position == rhs.position ); - } - - bool operator != ( const Filtration_simplex_iterator& rhs )const - { - if ( globalDbg ){cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n";} - return !(*this == rhs); - } - Simplex_handle operator*() - { - if ( globalDbg ){cerr << "Simplex_handle operator*()\n";} - return this->b->simplex_associated_to_key[ this->position ]; - } - - friend class Filtration_simplex_range; - private: - Bitmap_cubical_complex* b; - size_t position; - }; - - - /** - * Filtration_simplex_range provides the ranges for Filtration_simplex_iterator. - **/ - class Filtration_simplex_range - { - //Range over the simplices of the complex in the order of the filtration. - //.begin() and .end() return type Filtration_simplex_iterator. - public: - typedef Filtration_simplex_iterator const_iterator; - typedef Filtration_simplex_iterator iterator; - Filtration_simplex_range(Bitmap_cubical_complex* b):b(b){}; - Filtration_simplex_iterator begin() - { - if ( globalDbg ){cerr << "Filtration_simplex_iterator begin() \n";} - return Filtration_simplex_iterator( this->b ); - } - Filtration_simplex_iterator end() - { - if ( globalDbg ){cerr << "Filtration_simplex_iterator end()\n";} - Filtration_simplex_iterator it( this->b ); - it.position = this->b->simplex_associated_to_key.size(); - return it; - } - private: - Bitmap_cubical_complex* b; - }; - - - -//*********************************************// -//Methods to access iterators from the container: - /** - * boundary_simplex_range creates an object of a Boundary_simplex_range class - * that provides ranges for the Boundary_simplex_iterator. - **/ - Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) - { - /* - std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh); - Boundary_simplex_range result( bdry.size() ); - for ( size_t i = 0 ; i != bdry.size() ; ++i ) - { - result[i] = this->simplex_associated_to_key[ bdry[i] ]; - } - return result; - */ - return this->get_boundary_of_a_cell(sh); - } - - /** - * filtration_simplex_range creates an object of a Filtration_simplex_range class - * that provides ranges for the Filtration_simplex_iterator. - **/ - Filtration_simplex_range filtration_simplex_range() - { - if ( globalDbg ){cerr << "Filtration_simplex_range filtration_simplex_range()\n";} - //Returns a range over the simplices of the complex in the order of the filtration - return Filtration_simplex_range(this); - } -//*********************************************// - - - -//*********************************************// -//Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are there. - //TODO -- the file IndexingTag.h in the Gudhi library contains an empty structure, so - //I understand that this is something that was planned (for simplicial maps?) - //but was never finished. The only idea I have here is to use the same empty structure from - //IndexingTag.h file, but only if the compiler needs it. If the compiler - //do not need it, then I would rather not add here elements which I do not understand. - //typedef Indexing_tag - /** - * Function needed for compatibility with Gudhi. Not useful for other purposes. - **/ - std::pair endpoints( Simplex_handle sh ) - { - std::vector< size_t > bdry = this->get_boundary_of_a_cell( sh ); - if ( globalDbg ) - { - cerr << "std::pair endpoints( Simplex_handle sh )\n"; - cerr << "bdry.size() : " << bdry.size() << endl; - } - //this method returns two first elements from the boundary of sh. - if ( bdry.size() < 2 ) - throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the boundary."); - return std::make_pair( bdry[0] , bdry[1] ); - } - - - /** - * Class needed for compatibility with Gudhi. Not useful for other purposes. - **/ - class Skeleton_simplex_range; - class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > - { - //Iterator over all simplices of the complex in the order of the indexing scheme. - //'value_type' must be 'Simplex_handle'. - public: - Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d ):b(b),dimension(d) - { - if ( globalDbg ){cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n";} - //find the position of the first simplex of a dimension d - this->position = 0; - while ( - (this->position != b->data.size()) && - ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) - ) - { - ++this->position; - } - }; - Skeleton_simplex_iterator ():b(NULL),dimension(0){}; - - Skeleton_simplex_iterator operator++() - { - if ( globalDbg ){cerr << "Skeleton_simplex_iterator operator++()\n";} - //increment the position as long as you did not get to the next element of the dimension dimension. - ++this->position; - while ( - (this->position != this->b->data.size()) && - ( this->b->get_dimension_of_a_cell( this->position ) != this->dimension ) - ) - { - ++this->position; - } - return (*this); - } - Skeleton_simplex_iterator operator++(int) - { - Skeleton_simplex_iterator result = *this; - ++(*this); - return result; - } - Skeleton_simplex_iterator operator =( const Skeleton_simplex_iterator& rhs ) - { - if ( globalDbg ){cerr << "Skeleton_simplex_iterator operator =\n";} - this->b = rhs.b; - this->position = rhs.position; - } - bool operator == ( const Skeleton_simplex_iterator& rhs )const - { - if ( globalDbg ){cerr << "bool operator ==\n";} - return ( this->position == rhs.position ); - } - - bool operator != ( const Skeleton_simplex_iterator& rhs )const - { - if ( globalDbg ){cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n";} - return !(*this == rhs); - } - Simplex_handle operator*() - { - if ( globalDbg ){cerr << "Simplex_handle operator*() \n";} - return this->position; - } - - friend class Skeleton_simplex_range; - private: - Bitmap_cubical_complex* b; - size_t position; - unsigned dimension; - }; - /** - * Class needed for compatibility with Gudhi. Not useful for other purposes. - **/ - class Skeleton_simplex_range - { - //Range over the simplices of the complex in the order of the filtration. - //.begin() and .end() return type Filtration_simplex_iterator. - public: - typedef Skeleton_simplex_iterator const_iterator; - typedef Skeleton_simplex_iterator iterator; - Skeleton_simplex_range(Bitmap_cubical_complex* b , unsigned dimension):b(b),dimension(dimension){}; - Skeleton_simplex_iterator begin() - { - if ( globalDbg ){cerr << "Skeleton_simplex_iterator begin()\n";} - return Skeleton_simplex_iterator( this->b , this->dimension ); - } - Skeleton_simplex_iterator end() - { - if ( globalDbg ){cerr << "Skeleton_simplex_iterator end()\n";} - Skeleton_simplex_iterator it( this->b , this->dimension ); - it.position = this->b->data.size(); - return it; - } - private: - Bitmap_cubical_complex* b; - unsigned dimension; - }; - - /** - * Function needed for compatibility with Gudhi. Not useful for other purposes. - **/ - Skeleton_simplex_range skeleton_simplex_range( unsigned dimension ) - { - if ( globalDbg ){cerr << "Skeleton_simplex_range skeleton_simplex_range( unsigned dimension )\n";} - return Skeleton_simplex_range( this , dimension ); - } - - friend class is_before_in_filtration; - - -protected: - std::vector< size_t > key_associated_to_simplex; - std::vector< size_t > simplex_associated_to_key; -};//Bitmap_cubical_complex +class Bitmap_cubical_complex : public T { + public: + //*********************************************// + // Typedefs and typenames + //*********************************************// + typedef size_t Simplex_key; + typedef typename T::filtration_type Filtration_value; + typedef Simplex_key Simplex_handle; + + + //*********************************************// + // Constructors + //*********************************************// + // Over here we need to define various input types. I am proposing the following ones: + // Perseus style + // TODO(PD) H5 files? + // TODO(PD) binary files with little endiangs / big endians ? + // TODO(PD) constructor from a vector of elements of a type T. ? + + /** + * Constructor form a Perseus-style file. + **/ + Bitmap_cubical_complex(const char* perseus_style_file) : + T(perseus_style_file), key_associated_to_simplex(this->total_number_of_cells + 1) { + if (globalDbg) { + std::cerr << "Bitmap_cubical_complex( const char* perseus_style_file )\n"; + } + for (size_t i = 0; i != this->total_number_of_cells; ++i) { + this->key_associated_to_simplex[i] = i; + } + // we initialize this only once, in each constructor, when the bitmap is constructed. + // If the user decide to change some elements of the bitmap, then this procedure need + // to be called again. + this->initialize_simplex_associated_to_key(); + } + + /** + * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells + * in the following directions and vector of element of a type T + * with filtration on top dimensional cells. + **/ + Bitmap_cubical_complex(const std::vector& dimensions, + const std::vector& top_dimensional_cells) : + T(dimensions, top_dimensional_cells), + key_associated_to_simplex(this->total_number_of_cells + 1) { + for (size_t i = 0; i != this->total_number_of_cells; ++i) { + this->key_associated_to_simplex[i] = i; + } + // we initialize this only once, in each constructor, when the bitmap is constructed. + // If the user decide to change some elements of the bitmap, then this procedure need + // to be called again. + this->initialize_simplex_associated_to_key(); + } + + /** + * Constructor that requires vector of elements of type unsigned, which gives number of top dimensional cells + * in the following directions and vector of element of a type T::filtration_type + * with filtration on top dimensional cells. The last parameter of the constructor is a vector of bools of a length equal to the dimension of cubical complex. + * If the position i on this vector is true, then we impose periodic boundary conditions in this direction. + **/ + Bitmap_cubical_complex(const std::vector& dimensions, + const std::vector& top_dimensional_cells, + std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed) : + T(dimensions, top_dimensional_cells, directions_in_which_periodic_b_cond_are_to_be_imposed), + key_associated_to_simplex(this->total_number_of_cells + 1) { + for (size_t i = 0; i != this->total_number_of_cells; ++i) { + this->key_associated_to_simplex[i] = i; + } + // we initialize this only once, in each constructor, when the bitmap is constructed. + // If the user decide to change some elements of the bitmap, then this procedure need + // to be called again. + this->initialize_simplex_associated_to_key(); + } + + /** + * Destructor of the Bitmap_cubical_complex class. + **/ + virtual ~Bitmap_cubical_complex(){} + + //*********************************************// + // Other 'easy' functions + //*********************************************// + + /** + * Returns number of all cubes in the complex. + **/ + size_t num_simplices()const { + return this->total_number_of_cells; + } + + /** + * Returns a Simplex_handle to a cube that do not exist in this complex. + **/ + static Simplex_handle null_simplex() { + if (globalDbg) { + std::cerr << "Simplex_handle null_simplex()\n"; + } + return std::numeric_limits::max(); + } + + /** + * Returns dimension of the complex. + **/ + inline size_t dimension()const { + return this->sizes.size(); + } + + /** + * Return dimension of a cell pointed by the Simplex_handle. + **/ + inline unsigned dimension(Simplex_handle sh)const { + if (globalDbg) { + std::cerr << "unsigned dimension(const Simplex_handle& sh)\n"; + } + if (sh != std::numeric_limits::max()) return this->get_dimension_of_a_cell(sh); + return -1; + } + + /** + * Return the filtration of a cell pointed by the Simplex_handle. + **/ + typename T::filtration_type filtration(Simplex_handle sh) { + if (globalDbg) { + std::cerr << "T::filtration_type filtration(const Simplex_handle& sh)\n"; + } + // Returns the filtration value of a simplex. + if (sh != std::numeric_limits::max()) return this->data[sh]; + return std::numeric_limits::max(); + } + + /** + * Return a key which is not a key of any cube in the considered data structure. + **/ + static Simplex_key null_key() { + if (globalDbg) { + std::cerr << "Simplex_key null_key()\n"; + } + return std::numeric_limits::max(); + } + + /** + * Return the key of a cube pointed by the Simplex_handle. + **/ + Simplex_key key(Simplex_handle sh)const { + if (globalDbg) { + std::cerr << "Simplex_key key(const Simplex_handle& sh)\n"; + } + if (sh != std::numeric_limits::max()) { + return this->key_associated_to_simplex[sh]; + } + return this->null_key(); + } + + /** + * Return the Simplex_handle given the key of the cube. + **/ + Simplex_handle simplex(Simplex_key key) { + if (globalDbg) { + std::cerr << "Simplex_handle simplex(Simplex_key key)\n"; + } + if (key != std::numeric_limits::max()) { + return this->simplex_associated_to_key[ key ]; + } + return null_simplex(); + } + + /** + * Assign key to a cube pointed by the Simplex_handle + **/ + void assign_key(Simplex_handle sh, Simplex_key key) { + if (globalDbg) { + std::cerr << "void assign_key(Simplex_handle& sh, Simplex_key key)\n"; + } + if (key == std::numeric_limits::max()) return; + this->key_associated_to_simplex[sh] = key; + this->simplex_associated_to_key[key] = sh; + } + + /** + * Function called from a constructor. It is needed for Filtration_simplex_iterator to work. + **/ + void initialize_simplex_associated_to_key(); + + //*********************************************// + // Iterators + //*********************************************// + + /** + * Boundary_simplex_range class provides ranges for boundary iterators. + **/ + typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; + typedef typename std::vector< Simplex_handle > Boundary_simplex_range; + + /** + * Filtration_simplex_iterator class provides an iterator though the whole structure in the order of filtration. + * Secondary criteria for filtration are: + * (1) Dimension of a cube (lower dimensional comes first). + * (2) Position in the data structure (the ones that are earlies in the data structure comes first). + **/ + class Filtration_simplex_range; + + class Filtration_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { + // Iterator over all simplices of the complex in the order of the indexing scheme. + // 'value_type' must be 'Simplex_handle'. + public: + Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { } + + Filtration_simplex_iterator() : b(NULL) { } + + Filtration_simplex_iterator operator++() { + if (globalDbg) { + std::cerr << "Filtration_simplex_iterator operator++\n"; + } + ++this->position; + return (*this); + } -template -void Bitmap_cubical_complex::initialize_simplex_associated_to_key() -{ - if ( globalDbg ) - { - cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; - } - this->simplex_associated_to_key = std::vector( this->data.size() ); - std::iota (std::begin(simplex_associated_to_key), std::end(simplex_associated_to_key), 0); - std::sort( simplex_associated_to_key.begin() , - simplex_associated_to_key.end() , - is_before_in_filtration(this) ); - - //we still need to deal here with a key_associated_to_simplex: - for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) - { - this->key_associated_to_simplex[ simplex_associated_to_key[i] ] = i; + Filtration_simplex_iterator operator++(int) { + Filtration_simplex_iterator result = *this; + ++(*this); + return result; } -} + Filtration_simplex_iterator& operator=(const Filtration_simplex_iterator& rhs) { + if (globalDbg) { + std::cerr << "Filtration_simplex_iterator operator =\n"; + } + this->b = rhs.b; + this->position = rhs.position; + } -template -class is_before_in_filtration -{ -public: - explicit is_before_in_filtration(Bitmap_cubical_complex * CC) - : CC_(CC) { } - - bool operator()( const typename Bitmap_cubical_complex::Simplex_handle sh1, const typename Bitmap_cubical_complex::Simplex_handle sh2) const - { - // Not using st_->filtration(sh1) because it uselessly tests for null_simplex. - typename T::filtration_type fil1 = CC_->data[sh1]; - typename T::filtration_type fil2 = CC_->data[sh2]; - if ( fil1 != fil2 ) - { - return fil1 < fil2; + bool operator==(const Filtration_simplex_iterator& rhs)const { + if (globalDbg) { + std::cerr << "bool operator == ( const Filtration_simplex_iterator& rhs )\n"; + } + return ( this->position == rhs.position); + } + + bool operator!=(const Filtration_simplex_iterator& rhs)const { + if (globalDbg) { + std::cerr << "bool operator != ( const Filtration_simplex_iterator& rhs )\n"; + } + return !(*this == rhs); + } + + Simplex_handle operator*() { + if (globalDbg) { + std::cerr << "Simplex_handle operator*()\n"; + } + return this->b->simplex_associated_to_key[ this->position ]; + } + + friend class Filtration_simplex_range; + + private: + Bitmap_cubical_complex* b; + size_t position; + }; + + /** + * Filtration_simplex_range provides the ranges for Filtration_simplex_iterator. + **/ + class Filtration_simplex_range { + // Range over the simplices of the complex in the order of the filtration. + // .begin() and .end() return type Filtration_simplex_iterator. + public: + typedef Filtration_simplex_iterator const_iterator; + typedef Filtration_simplex_iterator iterator; + + Filtration_simplex_range(Bitmap_cubical_complex* b) : b(b) { } + + Filtration_simplex_iterator begin() { + if (globalDbg) { + std::cerr << "Filtration_simplex_iterator begin() \n"; } - //in this case they are on the same filtration level, so the dimension decide. - size_t dim1 = CC_->get_dimension_of_a_cell(sh1); - size_t dim2 = CC_->get_dimension_of_a_cell(sh2); - if ( dim1 != dim2 ) - { - return dim1 < dim2; + return Filtration_simplex_iterator(this->b); + } + + Filtration_simplex_iterator end() { + if (globalDbg) { + std::cerr << "Filtration_simplex_iterator end()\n"; } - //in this case both filtration and dimensions of the considered cubes are the same. To have stable sort, we simply compare their positions in the bitmap: - return sh1 < sh2; - } -protected: - Bitmap_cubical_complex* CC_; + Filtration_simplex_iterator it(this->b); + it.position = this->b->simplex_associated_to_key.size(); + return it; + } + + private: + Bitmap_cubical_complex* b; }; -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// + //*********************************************// + // Methods to access iterators from the container: + /** + * boundary_simplex_range creates an object of a Boundary_simplex_range class + * that provides ranges for the Boundary_simplex_iterator. + **/ + Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) { + return this->get_boundary_of_a_cell(sh); + } + + /** + * filtration_simplex_range creates an object of a Filtration_simplex_range class + * that provides ranges for the Filtration_simplex_iterator. + **/ + Filtration_simplex_range filtration_simplex_range() { + if (globalDbg) { + std::cerr << "Filtration_simplex_range filtration_simplex_range()\n"; + } + // Returns a range over the simplices of the complex in the order of the filtration + return Filtration_simplex_range(this); + } + //*********************************************// + + + + //*********************************************// + // Elements which are in Gudhi now, but I (and in all the cases I asked also Marc) do not understand why they are + // there. + // TODO(PD) the file IndexingTag.h in the Gudhi library contains an empty structure, so + // I understand that this is something that was planned (for simplicial maps?) + // but was never finished. The only idea I have here is to use the same empty structure from + // IndexingTag.h file, but only if the compiler needs it. If the compiler + // do not need it, then I would rather not add here elements which I do not understand. + // typedef Indexing_tag + + /** + * Function needed for compatibility with Gudhi. Not useful for other purposes. + **/ + std::pair endpoints(Simplex_handle sh) { + std::vector< size_t > bdry = this->get_boundary_of_a_cell(sh); + if (globalDbg) { + std::cerr << "std::pair endpoints( Simplex_handle sh )\n"; + std::cerr << "bdry.size() : " << bdry.size() << std::endl; + } + // this method returns two first elements from the boundary of sh. + if (bdry.size() < 2) + throw("Error in endpoints in Bitmap_cubical_complex class. The cell have less than two elements in the boundary."); + return std::make_pair(bdry[0], bdry[1]); + } + + + /** + * Class needed for compatibility with Gudhi. Not useful for other purposes. + **/ + class Skeleton_simplex_range; + + class Skeleton_simplex_iterator : std::iterator< std::input_iterator_tag, Simplex_handle > { + // Iterator over all simplices of the complex in the order of the indexing scheme. + // 'value_type' must be 'Simplex_handle'. + public: + Skeleton_simplex_iterator(Bitmap_cubical_complex* b, size_t d) : b(b), dimension(d) { + if (globalDbg) { + std::cerr << "Skeleton_simplex_iterator ( Bitmap_cubical_complex* b , size_t d )\n"; + } + // find the position of the first simplex of a dimension d + this->position = 0; + while ( + (this->position != b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension) + ) { + ++this->position; + } + } + + Skeleton_simplex_iterator() : b(NULL), position(0), dimension(0) { } + + Skeleton_simplex_iterator operator++() { + if (globalDbg) { + std::cerr << "Skeleton_simplex_iterator operator++()\n"; + } + // increment the position as long as you did not get to the next element of the dimension dimension. + ++this->position; + while ( + (this->position != this->b->data.size()) && + (this->b->get_dimension_of_a_cell(this->position) != this->dimension) + ) { + ++this->position; + } + return (*this); + } + + Skeleton_simplex_iterator operator++(int) { + Skeleton_simplex_iterator result = *this; + ++(*this); + return result; + } + + Skeleton_simplex_iterator& operator=(const Skeleton_simplex_iterator& rhs) { + if (globalDbg) { + std::cerr << "Skeleton_simplex_iterator operator =\n"; + } + this->b = rhs.b; + this->position = rhs.position; + this->dimension = rhs.dimension; + } + + bool operator==(const Skeleton_simplex_iterator& rhs)const { + if (globalDbg) { + std::cerr << "bool operator ==\n"; + } + return ( this->position == rhs.position); + } + + bool operator!=(const Skeleton_simplex_iterator& rhs)const { + if (globalDbg) { + std::cerr << "bool operator != ( const Skeleton_simplex_iterator& rhs )\n"; + } + return !(*this == rhs); + } + + Simplex_handle operator*() { + if (globalDbg) { + std::cerr << "Simplex_handle operator*() \n"; + } + return this->position; + } + + friend class Skeleton_simplex_range; + private: + Bitmap_cubical_complex* b; + size_t position; + unsigned dimension; + }; + + /** + * Class needed for compatibility with Gudhi. Not useful for other purposes. + **/ + class Skeleton_simplex_range { + // Range over the simplices of the complex in the order of the filtration. + // .begin() and .end() return type Filtration_simplex_iterator. + public: + typedef Skeleton_simplex_iterator const_iterator; + typedef Skeleton_simplex_iterator iterator; + + Skeleton_simplex_range(Bitmap_cubical_complex* b, unsigned dimension) : b(b), dimension(dimension) { } + + Skeleton_simplex_iterator begin() { + if (globalDbg) { + std::cerr << "Skeleton_simplex_iterator begin()\n"; + } + return Skeleton_simplex_iterator(this->b, this->dimension); + } + + Skeleton_simplex_iterator end() { + if (globalDbg) { + std::cerr << "Skeleton_simplex_iterator end()\n"; + } + Skeleton_simplex_iterator it(this->b, this->dimension); + it.position = this->b->data.size(); + return it; + } + + private: + Bitmap_cubical_complex* b; + unsigned dimension; + }; + + /** + * Function needed for compatibility with Gudhi. Not useful for other purposes. + **/ + Skeleton_simplex_range skeleton_simplex_range(unsigned dimension) { + if (globalDbg) { + std::cerr << "Skeleton_simplex_range skeleton_simplex_range( unsigned dimension )\n"; + } + return Skeleton_simplex_range(this, dimension); + } + + friend class is_before_in_filtration; + + protected: + std::vector< size_t > key_associated_to_simplex; + std::vector< size_t > simplex_associated_to_key; +}; // Bitmap_cubical_complex + +template +void Bitmap_cubical_complex::initialize_simplex_associated_to_key() { + if (globalDbg) { + std::cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; + } + this->simplex_associated_to_key = std::vector(this->data.size()); + std::iota(std::begin(simplex_associated_to_key), std::end(simplex_associated_to_key), 0); + std::sort(simplex_associated_to_key.begin(), + simplex_associated_to_key.end(), + is_before_in_filtration(this)); + + // we still need to deal here with a key_associated_to_simplex: + for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) + { + this->key_associated_to_simplex[ simplex_associated_to_key[i] ] = i; + } } -} + +template +class is_before_in_filtration { + public: + explicit is_before_in_filtration(Bitmap_cubical_complex * CC) + : CC_(CC) { } + + bool operator()(const typename Bitmap_cubical_complex::Simplex_handle& sh1, + const typename Bitmap_cubical_complex::Simplex_handle& sh2) const { + // Not using st_->filtration(sh1) because it uselessly tests for null_simplex. + typename T::filtration_type fil1 = CC_->data[sh1]; + typename T::filtration_type fil2 = CC_->data[sh2]; + if (fil1 != fil2) { + return fil1 < fil2; + } + // in this case they are on the same filtration level, so the dimension decide. + size_t dim1 = CC_->get_dimension_of_a_cell(sh1); + size_t dim2 = CC_->get_dimension_of_a_cell(sh2); + if (dim1 != dim2) { + return dim1 < dim2; + } + // in this case both filtration and dimensions of the considered cubes are the same. To have stable sort, we simply + // compare their positions in the bitmap: + return sh1 < sh2; + } + + protected: + Bitmap_cubical_complex* CC_; +}; + +} // namespace Cubical_complex + +} // namespace Gudhi + +#endif // BITMAP_CUBICAL_COMPLEX_H_ diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index f0517a86..62776019 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -20,35 +20,30 @@ * along with this program. If not, see . */ -#pragma once +#ifndef BITMAP_CUBICAL_COMPLEX_BASE_H_ +#define BITMAP_CUBICAL_COMPLEX_BASE_H_ -#include -#include -#include +#include + +#include #include #include #include #include #include -#include -#include -#include "Bitmap_cubical_complex/counter.h" - - -using namespace std; +#include +#include // for pair<> -namespace Gudhi -{ - -namespace Cubical_complex -{ +namespace Gudhi { +namespace Cubical_complex { /** - *@class Bitmap_cubical_complex_base - *@brief Cubical complex represented as a bitmap, class with basic implementation. - *@ingroup cubical_complex + * @class Bitmap_cubical_complex_base + * @brief Cubical complex represented as a bitmap, class with basic implementation. + * @ingroup cubical_complex */ + /** * This is a class implementing a basic bitmap data structure to store cubical complexes. * It implements only the most basic subroutines. @@ -67,844 +62,750 @@ namespace Cubical_complex * The default filtration used in this implementation is the lower star filtration. */ template -class Bitmap_cubical_complex_base -{ -public: - typedef T filtration_type; - /** - *Default constructor - **/ - Bitmap_cubical_complex_base() - { - } - /** - * There are a few constructors of a Bitmap_cubical_complex_base class. - * First one, that takes vector, creates an empty bitmap of a dimension equal - * the number of elements in the - * input vector and size in the i-th dimension equal the number in the position i-of the input vector. - */ - Bitmap_cubical_complex_base( const std::vector& sizes ); - /** - * The second constructor takes as a input a Perseus style file. For more details, - * please consult the documentations of - * Perseus software as well as examples attached to this - * implementation. - **/ - Bitmap_cubical_complex_base( const char* perseus_style_file ); - /** - * The last constructor of a Bitmap_cubical_complex_base class accepts vector of dimensions (as the first one) - * together with vector of filtration values of top dimensional cells. - **/ - Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells ); - - /** - * Destructor of the Bitmap_cubical_complex_base class. - **/ - virtual ~Bitmap_cubical_complex_base(){} - - /** - * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell - * and get_cell_data are the basic - * functions that compute boundary / coboundary / dimension and the filtration - * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a - * non-negative integer, indicating a position of a cube in the data structure. - * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to - * the positions of (co)boundary element of the input cell. - */ - virtual inline std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; - /** - * The functions get_coboundary_of_a_cell, get_coboundary_of_a_cell, - * get_dimension_of_a_cell and get_cell_data are the basic - * functions that compute boundary / coboundary / dimension and the filtration - * value form a position of a cell in the structure of a bitmap. - * The input parameter of all of those function is a non-negative integer, - * indicating a position of a cube in the data structure. - * In the case of functions that compute (co)boundary, the output is a vector if - * non-negative integers pointing to the - * positions of (co)boundary element of the input cell. - **/ - virtual inline std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; - /** - * In the case of get_dimension_of_a_cell function, the output is a non-negative integer - * indicating the dimension of a cell. - **/ - inline unsigned get_dimension_of_a_cell( size_t cell )const; - /** - * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position. This allows reading and changing the value of filtration. - * Note that if the value of a filtration is changed, the code do not check if we have a filtration or not. i.e. it do not check if the value of a filtration of a cell is - * not smaller than the value of a filtration of its boundary and not greater than the value of its coboundary. - **/ - inline T& get_cell_data( size_t cell ); - - - /** - * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. - * Then, there are a few ways one can pick the filtration of lower dimensional - * cells. The most typical one is by so called lower star filtration. This function is always called by any - * constructor which takes the top dimensional cells. If you use such a constructor, - * then there is no need to call this function. Call it only if you are putting the filtration - * of the cells by your own (for instance by using Top_dimensional_cells_iterator). - **/ - void impose_lower_star_filtration();//assume that top dimensional cells are already set. - - /** - * Returns dimension of a complex. - **/ - inline unsigned dimension()const{ return sizes.size(); } - - /** - * Returns number of all cubes in the data structure. - **/ - inline unsigned size()const - { - return this->data.size(); - } - - /** - * Writing to stream operator. By using it we get the values T of cells in order in which they are stored in the structure. This procedure is used for debugging purposes. - **/ - template - friend ostream& operator << ( ostream & os , const Bitmap_cubical_complex_base& b ); - - - /** - * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values equally distributed in the range of data. - * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute persistence gets - * worst. When dealing with this type of data, one may want to put different values on cells to some number of bins. The function put_data_to_bins( size_t number_of_bins ) - * ais designed for that purpose. The parameter of the function is the number of bins (distinct values) we want to have in the cubical complex. - **/ - void put_data_to_bins( size_t number_of_bins ); - - /** - * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values equally distributed in the range of data. - * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute persistence gets - * worst. When dealing with this type of data, one may want to put different values on cells to some number of bins. The function put_data_to_bins( T diameter_of_bin ) is - * designed for that purpose. The parameter of it is the diameter of each bin. Note that the bottleneck distance between the persistence diagram of the cubical complex - * before and after using such a function will be bounded by the parameter diameter_of_bin. - **/ - void put_data_to_bins( T diameter_of_bin ); - - /** - * Functions to find min and max values of filtration. - **/ - std::pair< T ,T > min_max_filtration(); - - //ITERATORS - /** - * Iterator through all cells in the complex (in order they appear in the structure -- i.e. - * in lexicographical order). - **/ - class All_cells_iterator : std::iterator< std::input_iterator_tag, T > - { - public: - All_cells_iterator() - { - this->counter = 0; - } - All_cells_iterator operator++() - { - //first find first element of the counter that can be increased: - ++this->counter; - return *this; - } - All_cells_iterator operator++(int) - { - All_cells_iterator result = *this; - ++(*this); - return result; - } - All_cells_iterator operator =( const All_cells_iterator& rhs ) - { - this->counter = rhs.counter; - return *this; - } - bool operator == ( const All_cells_iterator& rhs )const - { - if ( this->counter != rhs.counter )return false; - return true; - } - bool operator != ( const All_cells_iterator& rhs )const - { - return !(*this == rhs); - } - - /* - * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as an argument of the following functions: - * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell boundary and coboundary and dimension - * and in function get_cell_data to get a filtration of a cell. - */ - size_t operator*() - { - return this->counter; - } - friend class Bitmap_cubical_complex_base; - protected: - size_t counter; - }; - - /** - * Function returning a All_cells_iterator to the first cell of the bitmap. - **/ - All_cells_iterator all_cells_iterator_begin() - { - All_cells_iterator a; - return a; - } - - /** - * Function returning a All_cells_iterator to the last cell of the bitmap. - **/ - All_cells_iterator all_cells_iterator_end() - { - All_cells_iterator a; - a.counter = this->data.size(); - return a; - } - - - /** - * All_cells_range class provides ranges for All_cells_iterator - **/ - class All_cells_range - { - public: - All_cells_range(Bitmap_cubical_complex_base* b):b(b){}; - All_cells_iterator begin() - { - return b->all_cells_iterator_begin(); - } - All_cells_iterator end() - { - return b->all_cells_iterator_end(); - } - private: - Bitmap_cubical_complex_base* b; - }; - - All_cells_range all_cells_range() - { - return All_cells_range(this); - } - - - /** - * Boundary_range class provides ranges for boundary iterators. - **/ - typedef typename std::vector< size_t >::const_iterator Boundary_iterator; - typedef typename std::vector< size_t > Boundary_range; - - /** - * boundary_simplex_range creates an object of a Boundary_simplex_range class - * that provides ranges for the Boundary_simplex_iterator. - **/ - Boundary_range boundary_range(size_t sh) - { - return this->get_boundary_of_a_cell(sh); - } - - /** - * Coboundary_range class provides ranges for boundary iterators. - **/ - typedef typename std::vector< size_t >::const_iterator Coboundary_iterator; - typedef typename std::vector< size_t > Coboundary_range; - - /** - * boundary_simplex_range creates an object of a Boundary_simplex_range class - * that provides ranges for the Boundary_simplex_iterator. - **/ - Coboundary_range coboundary_range(size_t sh) - { - return this->get_coboundary_of_a_cell(sh); - } - - - - - - - - - /** - * Iterator through top dimensional cells of the complex. The cells appear in order they are stored - * in the structure (i.e. in lexicographical order) - **/ - class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, T > - { - public: - Top_dimensional_cells_iterator( Bitmap_cubical_complex_base& b ):b(b) - { - this->counter = std::vector(b.dimension()); - //std::fill( this->counter.begin() , this->counter.end() , 0 ); - } - Top_dimensional_cells_iterator operator++() - { - //first find first element of the counter that can be increased: - size_t dim = 0; - while ( ( dim != this->b.dimension() ) && ( this->counter[dim] == this->b.sizes[dim]-1 ) )++dim; - - if ( dim != this->b.dimension() ) - { - ++this->counter[dim]; - for ( size_t i = 0 ; i != dim ; ++i ) - { - this->counter[i] = 0; - } - } - else - { - ++this->counter[0]; - } - return *this; - } - Top_dimensional_cells_iterator operator++(int) - { - Top_dimensional_cells_iterator result = *this; - ++(*this); - return result; - } - Top_dimensional_cells_iterator operator =( const Top_dimensional_cells_iterator& rhs ) - { - this->counter = rhs.counter; - this->b = rhs.b; - return *this; - } - bool operator == ( const Top_dimensional_cells_iterator& rhs )const - { - if ( &this->b != &rhs.b )return false; - if ( this->counter.size() != rhs.counter.size() )return false; - for ( size_t i = 0 ; i != this->counter.size() ; ++i ) - { - if ( this->counter[i] != rhs.counter[i] )return false; - } - return true; - } - bool operator != ( const Top_dimensional_cells_iterator& rhs )const - { - return !(*this == rhs); - } - - //T& operator*() - //{ - // //given the counter, compute the index in the array and return this element. - // unsigned index = 0; - // for ( size_t i = 0 ; i != this->counter.size() ; ++i ) - // { - // index += (2*this->counter[i]+1)*this->b.multipliers[i]; - // } - // return this->b.data[index]; - //} - - /* - * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as an argument of the following functions: - * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell boundary and coboundary and dimension - * and in function get_cell_data to get a filtration of a cell. - */ - size_t operator*() - { - return this->compute_index_in_bitmap(); - } - - size_t compute_index_in_bitmap()const - { - size_t index = 0; - for ( size_t i = 0 ; i != this->counter.size() ; ++i ) - { - index += (2*this->counter[i]+1)*this->b.multipliers[i]; - } - return index; - } - - - void print_counter()const - { - for ( size_t i = 0 ; i != this->counter.size() ; ++i ) - { - cout << this->counter[i] << " "; - } - } - friend class Bitmap_cubical_complex_base; - protected: - std::vector< size_t > counter; - Bitmap_cubical_complex_base& b; - }; - - /** - * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell of the bitmap. - **/ - Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin() - { - Top_dimensional_cells_iterator a(*this); - return a; - } - - /** - * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell of the bitmap. - **/ - Top_dimensional_cells_iterator top_dimensional_cells_iterator_end() - { - Top_dimensional_cells_iterator a(*this); - for ( size_t i = 0 ; i != this->dimension() ; ++i ) - { - a.counter[i] = this->sizes[i]-1; - } - a.counter[0]++; - return a; - } - - /** - * Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range - **/ - class Top_dimensional_cells_range - { - public: - Top_dimensional_cells_range(Bitmap_cubical_complex_base* b):b(b){}; - Top_dimensional_cells_iterator begin() - { - return b->top_dimensional_cells_iterator_begin(); - } - Top_dimensional_cells_iterator end() - { - return b->top_dimensional_cells_iterator_end(); - } - private: - Bitmap_cubical_complex_base* b; - }; - - Top_dimensional_cells_range top_dimensional_cells_range() - { - return Top_dimensional_cells_range(this); - } - - -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// - - -inline size_t number_cells()const -{ - return this->total_number_of_cells; -} +class Bitmap_cubical_complex_base { + public: + typedef T filtration_type; + + /** + *Default constructor + **/ + Bitmap_cubical_complex_base() : + total_number_of_cells(0) { } + /** + * There are a few constructors of a Bitmap_cubical_complex_base class. + * First one, that takes vector, creates an empty bitmap of a dimension equal + * the number of elements in the + * input vector and size in the i-th dimension equal the number in the position i-of the input vector. + */ + Bitmap_cubical_complex_base(const std::vector& sizes); + /** + * The second constructor takes as a input a Perseus style file. For more details, + * please consult the documentations of + * Perseus software as well as examples attached to this + * implementation. + **/ + Bitmap_cubical_complex_base(const char* perseus_style_file); + /** + * The last constructor of a Bitmap_cubical_complex_base class accepts vector of dimensions (as the first one) + * together with vector of filtration values of top dimensional cells. + **/ + Bitmap_cubical_complex_base(const std::vector& dimensions, const std::vector& top_dimensional_cells); + + /** + * Destructor of the Bitmap_cubical_complex_base class. + **/ + virtual ~Bitmap_cubical_complex_base() { } + + /** + * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell + * and get_cell_data are the basic + * functions that compute boundary / coboundary / dimension and the filtration + * value form a position of a cell in the structure of a bitmap. The input parameter of all of those function is a + * non-negative integer, indicating a position of a cube in the data structure. + * In the case of functions that compute (co)boundary, the output is a vector if non-negative integers pointing to + * the positions of (co)boundary element of the input cell. + */ + virtual inline std::vector< size_t > get_boundary_of_a_cell(size_t cell)const; + /** + * The functions get_coboundary_of_a_cell, get_coboundary_of_a_cell, + * get_dimension_of_a_cell and get_cell_data are the basic + * functions that compute boundary / coboundary / dimension and the filtration + * value form a position of a cell in the structure of a bitmap. + * The input parameter of all of those function is a non-negative integer, + * indicating a position of a cube in the data structure. + * In the case of functions that compute (co)boundary, the output is a vector if + * non-negative integers pointing to the + * positions of (co)boundary element of the input cell. + **/ + virtual inline std::vector< size_t > get_coboundary_of_a_cell(size_t cell)const; + /** + * In the case of get_dimension_of_a_cell function, the output is a non-negative integer + * indicating the dimension of a cell. + **/ + inline unsigned get_dimension_of_a_cell(size_t cell)const; + /** + * In the case of get_cell_data, the output parameter is a reference to the value of a cube in a given position. + * This allows reading and changing the value of filtration. Note that if the value of a filtration is changed, the + * code do not check if we have a filtration or not. i.e. it do not check if the value of a filtration of a cell is + * not smaller than the value of a filtration of its boundary and not greater than the value of its coboundary. + **/ + inline T& get_cell_data(size_t cell); + + + /** + * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. + * Then, there are a few ways one can pick the filtration of lower dimensional + * cells. The most typical one is by so called lower star filtration. This function is always called by any + * constructor which takes the top dimensional cells. If you use such a constructor, + * then there is no need to call this function. Call it only if you are putting the filtration + * of the cells by your own (for instance by using Top_dimensional_cells_iterator). + **/ + void impose_lower_star_filtration(); // assume that top dimensional cells are already set. + + /** + * Returns dimension of a complex. + **/ + inline unsigned dimension()const { + return sizes.size(); + } + + /** + * Returns number of all cubes in the data structure. + **/ + inline unsigned size()const { + return this->data.size(); + } + + /** + * Writing to stream operator. By using it we get the values T of cells in order in which they are stored in the + * structure. This procedure is used for debugging purposes. + **/ + template + friend std::ostream& operator<<(std::ostream & os, const Bitmap_cubical_complex_base& b); + + /** + * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values + * equally distributed in the range of data. + * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute + * persistence gets worst. When dealing with this type of data, one may want to put different values on cells to + * some number of bins. The function put_data_to_bins( size_t number_of_bins ) is designed for that purpose. + * The parameter of the function is the number of bins (distinct values) we want to have in the cubical complex. + **/ + void put_data_to_bins(size_t number_of_bins); + + /** + * Function that put the input data to bins. By putting data to bins we mean rounding them to a sequence of values + * equally distributed in the range of data. + * Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute + * persistence gets worst. When dealing with this type of data, one may want to put different values on cells to + * some number of bins. The function put_data_to_bins( T diameter_of_bin ) is designed for that purpose. + * The parameter of it is the diameter of each bin. Note that the bottleneck distance between the persistence + * diagram of the cubical complex before and after using such a function will be bounded by the parameter + * diameter_of_bin. + **/ + void put_data_to_bins(T diameter_of_bin); + + /** + * Functions to find min and max values of filtration. + **/ + std::pair< T, T > min_max_filtration(); + + // ITERATORS + + /** + * Iterator through all cells in the complex (in order they appear in the structure -- i.e. + * in lexicographical order). + **/ + class All_cells_iterator : std::iterator< std::input_iterator_tag, T > { + public: + + All_cells_iterator() { + this->counter = 0; + } -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// -//****************************************************************************************************************// - -protected: - std::vector sizes; - std::vector multipliers; - std::vector data; - size_t total_number_of_cells; - void set_up_containers( const std::vector& sizes ) - { - unsigned multiplier = 1; - for ( size_t i = 0 ; i != sizes.size() ; ++i ) - { - this->sizes.push_back(sizes[i]); - this->multipliers.push_back(multiplier); - multiplier *= 2*sizes[i]+1; - } - this->data = std::vector(multiplier, std::numeric_limits::max()); - this->total_number_of_cells = multiplier; + All_cells_iterator operator++() { + //first find first element of the counter that can be increased: + ++this->counter; + return *this; } - size_t compute_position_in_bitmap( const std::vector< unsigned >& counter ) - { - size_t position = 0; - for ( size_t i = 0 ; i != this->multipliers.size() ; ++i ) - { - position += this->multipliers[i]*counter[i]; - } - return position; + All_cells_iterator operator++(int) { + All_cells_iterator result = *this; + ++(*this); + return result; + } + + All_cells_iterator operator=(const All_cells_iterator& rhs) { + this->counter = rhs.counter; + return *this; } - std::vector compute_counter_for_given_cell( size_t cell )const - { - std::vector counter; - counter.reserve( this->sizes.size() ); - for ( size_t dim = this->sizes.size() ; dim != 0 ; --dim ) - { - counter.push_back(cell/this->multipliers[dim-1]); - cell = cell%this->multipliers[dim-1]; + bool operator==(const All_cells_iterator& rhs)const { + if (this->counter != rhs.counter)return false; + return true; + } + + bool operator!=(const All_cells_iterator& rhs)const { + return !(*this == rhs); + } + + /* + * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as an argument of the following functions: + * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell boundary and coboundary and dimension + * and in function get_cell_data to get a filtration of a cell. + */ + size_t operator*() { + return this->counter; + } + friend class Bitmap_cubical_complex_base; + protected: + size_t counter; + }; + + /** + * Function returning a All_cells_iterator to the first cell of the bitmap. + **/ + All_cells_iterator all_cells_iterator_begin() { + All_cells_iterator a; + return a; + } + + /** + * Function returning a All_cells_iterator to the last cell of the bitmap. + **/ + All_cells_iterator all_cells_iterator_end() { + All_cells_iterator a; + a.counter = this->data.size(); + return a; + } + + /** + * All_cells_range class provides ranges for All_cells_iterator + **/ + class All_cells_range { + public: + + All_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }; + + All_cells_iterator begin() { + return b->all_cells_iterator_begin(); + } + + All_cells_iterator end() { + return b->all_cells_iterator_end(); + } + private: + Bitmap_cubical_complex_base* b; + }; + + All_cells_range all_cells_range() { + return All_cells_range(this); + } + + + /** + * Boundary_range class provides ranges for boundary iterators. + **/ + typedef typename std::vector< size_t >::const_iterator Boundary_iterator; + typedef typename std::vector< size_t > Boundary_range; + + /** + * boundary_simplex_range creates an object of a Boundary_simplex_range class + * that provides ranges for the Boundary_simplex_iterator. + **/ + Boundary_range boundary_range(size_t sh) { + return this->get_boundary_of_a_cell(sh); + } + + /** + * Coboundary_range class provides ranges for boundary iterators. + **/ + typedef typename std::vector< size_t >::const_iterator Coboundary_iterator; + typedef typename std::vector< size_t > Coboundary_range; + + /** + * boundary_simplex_range creates an object of a Boundary_simplex_range class + * that provides ranges for the Boundary_simplex_iterator. + **/ + Coboundary_range coboundary_range(size_t sh) { + return this->get_coboundary_of_a_cell(sh); + } + + /** + * Iterator through top dimensional cells of the complex. The cells appear in order they are stored + * in the structure (i.e. in lexicographical order) + **/ + class Top_dimensional_cells_iterator : std::iterator< std::input_iterator_tag, T > { + public: + + Top_dimensional_cells_iterator(Bitmap_cubical_complex_base& b) : b(b) { + this->counter = std::vector(b.dimension()); + //std::fill( this->counter.begin() , this->counter.end() , 0 ); + } + + Top_dimensional_cells_iterator operator++() { + //first find first element of the counter that can be increased: + size_t dim = 0; + while ((dim != this->b.dimension()) && (this->counter[dim] == this->b.sizes[dim] - 1))++dim; + + if (dim != this->b.dimension()) { + ++this->counter[dim]; + for (size_t i = 0; i != dim; ++i) { + this->counter[i] = 0; } - std::reverse( counter.begin() , counter.end() ); - return counter; - } - void read_perseus_style_file( const char* perseus_style_file ); - void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells); - Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ); - Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ); - Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells , std::vector directions ); + } else { + ++this->counter[0]; + } + return *this; + } + + Top_dimensional_cells_iterator operator++(int) { + Top_dimensional_cells_iterator result = *this; + ++(*this); + return result; + } + + Top_dimensional_cells_iterator operator=(const Top_dimensional_cells_iterator& rhs) { + this->counter = rhs.counter; + this->b = rhs.b; + return *this; + } + + bool operator==(const Top_dimensional_cells_iterator& rhs)const { + if (&this->b != &rhs.b)return false; + if (this->counter.size() != rhs.counter.size())return false; + for (size_t i = 0; i != this->counter.size(); ++i) { + if (this->counter[i] != rhs.counter[i])return false; + } + return true; + } + + bool operator!=(const Top_dimensional_cells_iterator& rhs)const { + return !(*this == rhs); + } + + /* + * The operator * returns position of a cube in the structure of cubical complex. This position can be then used as an argument of the following functions: + * get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell to get information about the cell boundary and coboundary and dimension + * and in function get_cell_data to get a filtration of a cell. + */ + size_t operator*() { + return this->compute_index_in_bitmap(); + } + + size_t compute_index_in_bitmap()const { + size_t index = 0; + for (size_t i = 0; i != this->counter.size(); ++i) { + index += (2 * this->counter[i] + 1) * this->b.multipliers[i]; + } + return index; + } + + void print_counter()const { + for (size_t i = 0; i != this->counter.size(); ++i) { + std::cout << this->counter[i] << " "; + } + } + friend class Bitmap_cubical_complex_base; + protected: + std::vector< size_t > counter; + Bitmap_cubical_complex_base& b; + }; + + /** + * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell of the bitmap. + **/ + Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin() { + Top_dimensional_cells_iterator a(*this); + return a; + } + + /** + * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell of the bitmap. + **/ + Top_dimensional_cells_iterator top_dimensional_cells_iterator_end() { + Top_dimensional_cells_iterator a(*this); + for (size_t i = 0; i != this->dimension(); ++i) { + a.counter[i] = this->sizes[i] - 1; + } + a.counter[0]++; + return a; + } + + /** + * Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range + **/ + class Top_dimensional_cells_range { + public: + + Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }; + + Top_dimensional_cells_iterator begin() { + return b->top_dimensional_cells_iterator_begin(); + } + + Top_dimensional_cells_iterator end() { + return b->top_dimensional_cells_iterator_end(); + } + private: + Bitmap_cubical_complex_base* b; + }; + + Top_dimensional_cells_range top_dimensional_cells_range() { + return Top_dimensional_cells_range(this); + } + + + //****************************************************************************************************************// + //****************************************************************************************************************// + //****************************************************************************************************************// + //****************************************************************************************************************// + + inline size_t number_cells()const { + return this->total_number_of_cells; + } + + //****************************************************************************************************************// + //****************************************************************************************************************// + //****************************************************************************************************************// + //****************************************************************************************************************// + + protected: + std::vector sizes; + std::vector multipliers; + std::vector data; + size_t total_number_of_cells; + + void set_up_containers(const std::vector& sizes) { + unsigned multiplier = 1; + for (size_t i = 0; i != sizes.size(); ++i) { + this->sizes.push_back(sizes[i]); + this->multipliers.push_back(multiplier); + multiplier *= 2 * sizes[i] + 1; + } + this->data = std::vector(multiplier, std::numeric_limits::max()); + this->total_number_of_cells = multiplier; + } + + size_t compute_position_in_bitmap(const std::vector< unsigned >& counter) { + size_t position = 0; + for (size_t i = 0; i != this->multipliers.size(); ++i) { + position += this->multipliers[i] * counter[i]; + } + return position; + } + + std::vector compute_counter_for_given_cell(size_t cell)const { + std::vector counter; + counter.reserve(this->sizes.size()); + for (size_t dim = this->sizes.size(); dim != 0; --dim) { + counter.push_back(cell / this->multipliers[dim - 1]); + cell = cell % this->multipliers[dim - 1]; + } + std::reverse(counter.begin(), counter.end()); + return counter; + } + void read_perseus_style_file(const char* perseus_style_file); + void setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions, const std::vector& top_dimensional_cells); + Bitmap_cubical_complex_base(const char* perseus_style_file, std::vector directions); + Bitmap_cubical_complex_base(const std::vector& sizes, std::vector directions); + Bitmap_cubical_complex_base(const std::vector& dimensions, const std::vector& top_dimensional_cells, std::vector directions); }; +template +void Bitmap_cubical_complex_base::put_data_to_bins(size_t number_of_bins) { + bool bdg = false; + + std::pair< T, T > min_max = this->min_max_filtration(); + T dx = (min_max.second - min_max.first) / (T) number_of_bins; + + //now put the data into the appropriate bins: + for (size_t i = 0; i != this->data.size(); ++i) { + if (bdg) { + std::cerr << "Before binning : " << this->data[i] << std::endl; + } + this->data[i] = min_max.first + dx * (this->data[i] - min_max.first) / number_of_bins; + if (bdg) { + std::cerr << "After binning : " << this->data[i] << std::endl; + getchar(); + } + } +} -template -void Bitmap_cubical_complex_base::put_data_to_bins( size_t number_of_bins ) -{ - bool bdg = false; - - std::pair< T ,T > min_max = this->min_max_filtration(); - T dx = (min_max.second-min_max.first)/(T)number_of_bins; - - //now put the data into the appropriate bins: - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} - this->data[i] = min_max.first + dx*(this->data[i]-min_max.first)/number_of_bins; - if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} - } -} - template -void Bitmap_cubical_complex_base::put_data_to_bins( T diameter_of_bin ) -{ - bool bdg = false; - std::pair< T ,T > min_max = this->min_max_filtration(); - - size_t number_of_bins = (min_max.second - min_max.first)/diameter_of_bin; - //now put the data into the appropriate bins: - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( bdg ){cerr << "Before binning : " << this->data[i] << endl;} - this->data[i] = min_max.first + diameter_of_bin*(this->data[i]-min_max.first)/number_of_bins; - if ( bdg ){cerr << "After binning : " << this->data[i] << endl;getchar();} - } -} - -template -std::pair< T ,T > Bitmap_cubical_complex_base::min_max_filtration() -{ - std::pair< T ,T > min_max( std::numeric_limits::max() , std::numeric_limits::min() ); - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - if ( this->data[i] < min_max.first )min_max.first = this->data[i]; - if ( this->data[i] > min_max.second )min_max.second = this->data[i]; - } - return min_max; -} +void Bitmap_cubical_complex_base::put_data_to_bins(T diameter_of_bin) { + bool bdg = false; + std::pair< T, T > min_max = this->min_max_filtration(); + + size_t number_of_bins = (min_max.second - min_max.first) / diameter_of_bin; + //now put the data into the appropriate bins: + for (size_t i = 0; i != this->data.size(); ++i) { + if (bdg) { + std::cerr << "Before binning : " << this->data[i] << std::endl; + } + this->data[i] = min_max.first + diameter_of_bin * (this->data[i] - min_max.first) / number_of_bins; + if (bdg) { + std::cerr << "After binning : " << this->data[i] << std::endl; + getchar(); + } + } +} +template +std::pair< T, T > Bitmap_cubical_complex_base::min_max_filtration() { + std::pair< T, T > min_max(std::numeric_limits::max(), std::numeric_limits::min()); + for (size_t i = 0; i != this->data.size(); ++i) { + if (this->data[i] < min_max.first)min_max.first = this->data[i]; + if (this->data[i] > min_max.second)min_max.second = this->data[i]; + } + return min_max; +} template -ostream& operator << ( ostream & out , const Bitmap_cubical_complex_base& b ) -{ - for ( typename Bitmap_cubical_complex_base::all_cells_const_iterator - it = b.all_cells_const_begin() ; it != b.all_cells_const_end() ; ++it ) - { - out << *it << " "; - } - return out; +ostream& operator<<(ostream & out, const Bitmap_cubical_complex_base& b) { + for (typename Bitmap_cubical_complex_base::all_cells_const_iterator + it = b.all_cells_const_begin(); it != b.all_cells_const_end(); ++it) { + out << *it << " "; + } + return out; } - template Bitmap_cubical_complex_base::Bitmap_cubical_complex_base -( const std::vector& sizes ) -{ - this->set_up_containers( sizes ); +(const std::vector& sizes) { + this->set_up_containers(sizes); } - -template -void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells) -{ - this->set_up_containers( sizes_in_following_directions ); - - size_t number_of_top_dimensional_elements = 1; - for ( size_t i = 0 ; i != sizes_in_following_directions.size() ; ++i ) - { - number_of_top_dimensional_elements *= sizes_in_following_directions[i]; - } - if ( number_of_top_dimensional_elements != top_dimensional_cells.size() ) - { - cerr << - "Error in constructor\ + +template +void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells_list(const std::vector& sizes_in_following_directions, const std::vector& top_dimensional_cells) { + this->set_up_containers(sizes_in_following_directions); + + size_t number_of_top_dimensional_elements = 1; + for (size_t i = 0; i != sizes_in_following_directions.size(); ++i) { + number_of_top_dimensional_elements *= sizes_in_following_directions[i]; + } + if (number_of_top_dimensional_elements != top_dimensional_cells.size()) { + std::cerr << + "Error in constructor\ Bitmap_cubical_complex_base\ ( std::vector sizes_in_following_directions , std::vector top_dimensional_cells ).\ Number of top dimensional elements that follow from sizes_in_following_directions vector is different\ - than the size of top_dimensional_cells vector." << endl; - throw("Error in constructor Bitmap_cubical_complex_base( std::vector sizes_in_following_directions,\ + than the size of top_dimensional_cells vector." << std::endl; + throw ("Error in constructor Bitmap_cubical_complex_base( std::vector sizes_in_following_directions,\ std::vector top_dimensional_cells )\ . Number of top dimensional elements that follow from sizes_in_following_directions vector is different than the\ size of top_dimensional_cells vector."); - } - - Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - size_t index = 0; - for ( it = this->top_dimensional_cells_iterator_begin() ; it != this->top_dimensional_cells_iterator_end() ; ++it ) - { - this->get_cell_data(*it) = top_dimensional_cells[index]; - ++index; - } - this->impose_lower_star_filtration(); -} + } + + Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + size_t index = 0; + for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) { + this->get_cell_data(*it) = top_dimensional_cells[index]; + ++index; + } + this->impose_lower_star_filtration(); +} template Bitmap_cubical_complex_base::Bitmap_cubical_complex_base -( const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells ) -{ - this->setup_bitmap_based_on_top_dimensional_cells_list( sizes_in_following_directions , top_dimensional_cells ); -} - -template -void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseus_style_file ) -{ - bool dbg = false; - ifstream inFiltration, inIds; - inFiltration.open( perseus_style_file ); - unsigned dimensionOfData; - inFiltration >> dimensionOfData; - - if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;getchar();} - - std::vector sizes; - sizes.reserve( dimensionOfData ); - for ( size_t i = 0 ; i != dimensionOfData ; ++i ) - { - unsigned size_in_this_dimension; - inFiltration >> size_in_this_dimension; - size_in_this_dimension = size_in_this_dimension; - sizes.push_back( size_in_this_dimension ); - if (dbg){cerr << "size_in_this_dimension : " << size_in_this_dimension << endl;} - } - this->set_up_containers( sizes ); - - Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - it = this->top_dimensional_cells_iterator_begin(); - - while ( !inFiltration.eof() ) - { - T filtrationLevel; - inFiltration >> filtrationLevel; - if ( dbg ) - { - cerr << "Cell of an index : " - << it.compute_index_in_bitmap() - << " and dimension: " - << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) - << " get the value : " << filtrationLevel << endl; - } - this->get_cell_data(*it) = filtrationLevel; - ++it; - } - inFiltration.close(); - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->read_perseus_style_file( perseus_style_file ); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const std::vector& sizes , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->set_up_containers( sizes ); -} - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const std::vector& dimensions , const std::vector& top_dimensional_cells , std::vector directions ) -{ - //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. - //It ignores the last parameter of the function. - this->setup_bitmap_based_on_top_dimensional_cells_list( dimensions , top_dimensional_cells ); +(const std::vector& sizes_in_following_directions, const std::vector& top_dimensional_cells) { + this->setup_bitmap_based_on_top_dimensional_cells_list(sizes_in_following_directions, top_dimensional_cells); } template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file ) -{ - this->read_perseus_style_file( perseus_style_file ); +void Bitmap_cubical_complex_base::read_perseus_style_file(const char* perseus_style_file) { + bool dbg = false; + std::ifstream inFiltration, inIds; + inFiltration.open(perseus_style_file); + unsigned dimensionOfData; + inFiltration >> dimensionOfData; + + if (dbg) { + std::cerr << "dimensionOfData : " << dimensionOfData << std::endl; + getchar(); + } + + std::vector sizes; + sizes.reserve(dimensionOfData); + for (size_t i = 0; i != dimensionOfData; ++i) { + unsigned size_in_this_dimension; + inFiltration >> size_in_this_dimension; + size_in_this_dimension = size_in_this_dimension; + sizes.push_back(size_in_this_dimension); + if (dbg) { + std::cerr << "size_in_this_dimension : " << size_in_this_dimension << std::endl; + } + } + this->set_up_containers(sizes); + + Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + it = this->top_dimensional_cells_iterator_begin(); + + while (!inFiltration.eof()) { + T filtrationLevel; + inFiltration >> filtrationLevel; + if (dbg) { + std::cerr << "Cell of an index : " + << it.compute_index_in_bitmap() + << " and dimension: " + << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) + << " get the value : " << filtrationLevel << std::endl; + } + this->get_cell_data(*it) = filtrationLevel; + ++it; + } + inFiltration.close(); + this->impose_lower_star_filtration(); } - template -std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( size_t cell )const -{ - std::vector< size_t > boundary_elements; - - //Speed traded of for memory. Check if it is better in practice. - boundary_elements.reserve( this->dimension()*2 ); - - size_t cell1 = cell; - for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) - { - unsigned position = cell1/this->multipliers[i-1]; - if ( position%2 == 1 ) - { - boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); - boundary_elements.push_back( cell + this->multipliers[ i-1 ] ); - } - cell1 = cell1%this->multipliers[i-1]; - } - return boundary_elements; -} - +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(const char* perseus_style_file, std::vector directions) { + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->read_perseus_style_file(perseus_style_file); +} - - - template -std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( size_t cell )const -{ - std::vector counter = this->compute_counter_for_given_cell( cell ); - std::vector< size_t > coboundary_elements; - size_t cell1 = cell; - for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) - { - unsigned position = cell1/this->multipliers[i-1]; - if ( position%2 == 0 ) - { - if ( (cell > this->multipliers[i-1]) && (counter[i-1] != 0) ) - { - coboundary_elements.push_back( cell - this->multipliers[i-1] ); - } - if ( - (cell + this->multipliers[i-1] < this->data.size()) && (counter[i-1] != 2*this->sizes[i-1]) ) - { - coboundary_elements.push_back( cell + this->multipliers[i-1] ); - } - } - cell1 = cell1%this->multipliers[i-1]; - } - return coboundary_elements; -} - - - - +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(const std::vector& sizes, std::vector directions) { + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->set_up_containers(sizes); +} +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(const std::vector& dimensions, const std::vector& top_dimensional_cells, std::vector directions) { + //this constructor is here just for compatibility with a class that creates cubical complexes with periodic bundary conditions. + //It ignores the last parameter of the function. + this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells); +} +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base(const char* perseus_style_file) { + this->read_perseus_style_file(perseus_style_file); +} +template +std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell(size_t cell)const { + std::vector< size_t > boundary_elements; + + //Speed traded of for memory. Check if it is better in practice. + boundary_elements.reserve(this->dimension()*2); + + size_t cell1 = cell; + for (size_t i = this->multipliers.size(); i != 0; --i) { + unsigned position = cell1 / this->multipliers[i - 1]; + if (position % 2 == 1) { + boundary_elements.push_back(cell - this->multipliers[ i - 1 ]); + boundary_elements.push_back(cell + this->multipliers[ i - 1 ]); + } + cell1 = cell1 % this->multipliers[i - 1]; + } + return boundary_elements; +} template -unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell( size_t cell )const -{ - bool dbg = false; - if (dbg)cerr << "\n\n\n Computing position o a cell of an index : " << cell << endl; - unsigned dimension = 0; - for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) - { - unsigned position = cell/this->multipliers[i-1]; - - if (dbg)cerr << "i-1 :" << i-1 << endl; - if (dbg)cerr << "cell : " << cell << endl; - if (dbg)cerr << "position : " << position << endl; - if (dbg)cerr << "multipliers["<multipliers[i-1] << endl; - if (dbg)getchar(); - - if ( position%2 == 1 ) - { - if (dbg)cerr << "Nonzero length in this direction \n"; - dimension++; - } - cell = cell%this->multipliers[i-1]; +std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell(size_t cell)const { + std::vector counter = this->compute_counter_for_given_cell(cell); + std::vector< size_t > coboundary_elements; + size_t cell1 = cell; + for (size_t i = this->multipliers.size(); i != 0; --i) { + unsigned position = cell1 / this->multipliers[i - 1]; + if (position % 2 == 0) { + if ((cell > this->multipliers[i - 1]) && (counter[i - 1] != 0)) { + coboundary_elements.push_back(cell - this->multipliers[i - 1]); + } + if ( + (cell + this->multipliers[i - 1] < this->data.size()) && (counter[i - 1] != 2 * this->sizes[i - 1])) { + coboundary_elements.push_back(cell + this->multipliers[i - 1]); + } } - return dimension; + cell1 = cell1 % this->multipliers[i - 1]; + } + return coboundary_elements; } template -inline T& Bitmap_cubical_complex_base::get_cell_data( size_t cell ) -{ - return this->data[cell]; +unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell(size_t cell)const { + bool dbg = false; + if (dbg) std::cerr << "\n\n\n Computing position o a cell of an index : " << cell << std::endl; + unsigned dimension = 0; + for (size_t i = this->multipliers.size(); i != 0; --i) { + unsigned position = cell / this->multipliers[i - 1]; + + if (dbg) { + std::cerr << "i-1 :" << i - 1 << std::endl; + std::cerr << "cell : " << cell << std::endl; + std::cerr << "position : " << position << std::endl; + std::cerr << "multipliers[" << i - 1 << "] = " << this->multipliers[i - 1] << std::endl; + getchar(); + } + + if (position % 2 == 1) { + if (dbg) std::cerr << "Nonzero length in this direction \n"; + dimension++; + } + cell = cell % this->multipliers[i - 1]; + } + return dimension; } +template +inline T& Bitmap_cubical_complex_base::get_cell_data(size_t cell) { + return this->data[cell]; +} template -void Bitmap_cubical_complex_base::impose_lower_star_filtration() -{ - bool dbg = false; - - //this vector will be used to check which elements have already been taken care of - //in imposing lower star filtration: - std::vector is_this_cell_considered( this->data.size() , false ); - - size_t size_to_reserve = 1; - for ( size_t i = 0 ; i != this->multipliers.size() ; ++i ) - { - size_to_reserve *= (size_t)((this->multipliers[i]-1)/2); - } - - std::vector indices_to_consider; - indices_to_consider.reserve( size_to_reserve ); - //we assume here that we already have a filtration on the top dimensional cells and - //we have to extend it to lower ones. - typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - for ( it = this->top_dimensional_cells_iterator_begin() ; it != this->top_dimensional_cells_iterator_end() ; ++it ) - { - indices_to_consider.push_back( it.compute_index_in_bitmap() ); - } - - while ( indices_to_consider.size() ) - { - if ( dbg ) - { - cerr << "indices_to_consider in this iteration \n"; - for ( size_t i = 0 ; i != indices_to_consider.size() ; ++i ) - { - cout << indices_to_consider[i] << " "; - } +void Bitmap_cubical_complex_base::impose_lower_star_filtration() { + bool dbg = false; + + //this vector will be used to check which elements have already been taken care of + //in imposing lower star filtration: + std::vector is_this_cell_considered(this->data.size(), false); + + size_t size_to_reserve = 1; + for (size_t i = 0; i != this->multipliers.size(); ++i) { + size_to_reserve *= (size_t) ((this->multipliers[i] - 1) / 2); + } + + std::vector indices_to_consider; + indices_to_consider.reserve(size_to_reserve); + //we assume here that we already have a filtration on the top dimensional cells and + //we have to extend it to lower ones. + typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); + for (it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) { + indices_to_consider.push_back(it.compute_index_in_bitmap()); + } + + while (indices_to_consider.size()) { + if (dbg) { + std::cerr << "indices_to_consider in this iteration \n"; + for (size_t i = 0; i != indices_to_consider.size(); ++i) { + std::cout << indices_to_consider[i] << " "; + } + getchar(); + } + std::vector new_indices_to_consider; + for (size_t i = 0; i != indices_to_consider.size(); ++i) { + std::vector bd = this->get_boundary_of_a_cell(indices_to_consider[i]); + for (size_t boundaryIt = 0; boundaryIt != bd.size(); ++boundaryIt) { + if (dbg) { + std::cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ] << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ] << std::endl; + getchar(); + + } + if (this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ]) { + this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; + if (dbg) { + std::cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " << this->data[ indices_to_consider[i] ] << std::endl; getchar(); + } } - std::vector new_indices_to_consider; - for ( size_t i = 0 ; i != indices_to_consider.size() ; ++i ) - { - std::vector bd = this->get_boundary_of_a_cell( indices_to_consider[i] ); - for ( size_t boundaryIt = 0 ; boundaryIt != bd.size() ; ++boundaryIt ) - { - if ( dbg ) - { - cerr << "filtration of a cell : " << bd[boundaryIt] << " is : " << this->data[ bd[boundaryIt] ] << " while of a cell: " << indices_to_consider[i] << " is: " << this->data[ indices_to_consider[i] ] << endl; - getchar(); - - } - if ( this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ] ) - { - this->data[ bd[boundaryIt] ] = this->data[ indices_to_consider[i] ]; - if ( dbg ) - { - cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " << this->data[ indices_to_consider[i] ] << endl; - getchar(); - } - } - if ( is_this_cell_considered[ bd[boundaryIt] ] == false ) - { - new_indices_to_consider.push_back( bd[boundaryIt] ); - is_this_cell_considered[ bd[boundaryIt] ] = true; - } - } + if (is_this_cell_considered[ bd[boundaryIt] ] == false) { + new_indices_to_consider.push_back(bd[boundaryIt]); + is_this_cell_considered[ bd[boundaryIt] ] = true; } - indices_to_consider.swap(new_indices_to_consider); + } } + indices_to_consider.swap(new_indices_to_consider); + } } - template -bool compareFirstElementsOfTuples( const std::pair< std::pair< T , size_t > , char >& first , - const std::pair< std::pair< T , size_t > , char >& second ) -{ - if ( first.first.first < second.first.first ) - { - return true; - } - else - { - if ( first.first.first > second.first.first ) - { - return false; - } - //in this case first.first.first == second.first.first, so we need to compare dimensions - return first.second < second.second; +bool compareFirstElementsOfTuples(const std::pair< std::pair< T, size_t >, char >& first, + const std::pair< std::pair< T, size_t >, char >& second) { + if (first.first.first < second.first.first) { + return true; + } else { + if (first.first.first > second.first.first) { + return false; } + //in this case first.first.first == second.first.first, so we need to compare dimensions + return first.second < second.second; + } } +} // namespace Cubical_complex +} // namespace Gudhi - -} - -} +#endif // BITMAP_CUBICAL_COMPLEX_BASE_H_ diff --git a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h index 956e74a7..2c0d77fe 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h @@ -18,348 +18,289 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ - -#pragma once -#include -#include "Bitmap_cubical_complex_base.h" - -using namespace std; - -namespace Gudhi -{ - -namespace Cubical_complex -{ - -//in this class, we are storing all the elements which are in normal bitmap (i.e. the bitmap without the periodic boundary conditions). But, we set up the iterators and the procedures -//to compute boundary and coboundary in the way that it is all right. We assume here that all the cells that are on the left / bottom and so on remains, while all the cells on the -//right / top are not in the Bitmap_cubical_complex_periodic_boundary_conditions_base - - + */ + +#ifndef BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_ +#define BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_ + +#include + +#include +#include // for numeric_limits<> +#include + +namespace Gudhi { + +namespace Cubical_complex { + +// in this class, we are storing all the elements which are in normal bitmap (i.e. the bitmap without the periodic +// boundary conditions). But, we set up the iterators and the procedures to compute boundary and coboundary in the way +// that it is all right. We assume here that all the cells that are on the left / bottom and so on remains, while all +// the cells on the right / top are not in the Bitmap_cubical_complex_periodic_boundary_conditions_base + /** - *@class Bitmap_cubical_complex_periodic_boundary_conditions_base - *@brief Cubical complex with periodic boundary conditions represented as a bitmap. - *@ingroup cubical_complex - */ + * @class Bitmap_cubical_complex_periodic_boundary_conditions_base + * @brief Cubical complex with periodic boundary conditions represented as a bitmap. + * @ingroup cubical_complex + */ /** -* This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the functions are identical to the functions from Bitmap_cubical_complex_base. +* This is a class implementing a bitmap data structure with periodic boundary conditions. Most of the functions are identical to the functions from Bitmap_cubical_complex_base. * The ones that needed to be updated are the constructors and get_boundary_of_a_cell and get_coboundary_of_a_cell. -*/ -template -class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base -{ -public: - //constructors that take an extra parameter: - /** - * Default constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class. - */ - Bitmap_cubical_complex_periodic_boundary_conditions_base(){}; - - /** - * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of booleans. If at i-th position of this vector there is true value, that means that periodic boundary conditions are to be imposed in this direction. In case of false, the periodic boundary conditions will not be imposed in the direction i. - */ - Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& sizes , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ); - /** - * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the name of Perseus style file as an input. Please consult the documentation about the specification of the file. - */ - Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseusStyleFile ); - /** - * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of top dimensional cells (ordered lexicographically) and (3) vector of booleans. If at i-th position of this vector there is true value, that means that periodic boundary conditions are to be imposed in this direction. In case of false, the periodic boundary conditions will not be imposed in the direction i. - */ - Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& dimensions , const std::vector& topDimensionalCells , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ); - - /** - * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class. - **/ - virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base(){} - - //overwritten methods co compute boundary and coboundary - /** - * A version of a function that return boundary of a given cell for an object of Bitmap_cubical_complex_periodic_boundary_conditions_base class. - */ - virtual std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; - /** - * A version of a function that return coboundary of a given cell for an object of Bitmap_cubical_complex_periodic_boundary_conditions_base class. - */ - virtual std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; -protected: - std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed; - void set_up_containers( const std::vector& sizes ) - { - - unsigned multiplier = 1; - for ( size_t i = 0 ; i != sizes.size() ; ++i ) - { - this->sizes.push_back(sizes[i]); - this->multipliers.push_back(multiplier); - - if ( directions_in_which_periodic_b_cond_are_to_be_imposed[i] ) - { - multiplier *= 2*sizes[i]; - } - else - { - multiplier *= 2*sizes[i]+1; - } - } - //std::reverse( this->sizes.begin() , this->sizes.end() ); - this->data = std::vector(multiplier,std::numeric_limits::max()); - this->total_number_of_cells = multiplier; - } - Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& sizes ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& dimensions , const std::vector& topDimensionalCells ); - void construct_complex_based_on_top_dimensional_cells( const std::vector& dimensions , const std::vector& topDimensionalCells , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ); -}; - -template -void Bitmap_cubical_complex_periodic_boundary_conditions_base::construct_complex_based_on_top_dimensional_cells( const std::vector& dimensions , const std::vector& topDimensionalCells , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ) -{ - this->directions_in_which_periodic_b_cond_are_to_be_imposed = directions_in_which_periodic_b_cond_are_to_be_imposed; - this->set_up_containers( dimensions ); - - size_t i = 0; - for ( typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it = this->top_dimensional_cells_iterator_begin() ; it != this->top_dimensional_cells_iterator_end() ; ++it ) - { - this->get_cell_data(*it) = topDimensionalCells[i]; - ++i; - } - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& sizes , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ) -{ - this->directions_in_which_periodic_b_cond_are_to_be_imposed(directions_in_which_periodic_b_cond_are_to_be_imposed); - this->set_up_containers( sizes ); -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseus_style_file ) -{ - - //for Perseus style files: - bool dbg = false; - ifstream inFiltration; - inFiltration.open( perseus_style_file ); - unsigned dimensionOfData; - inFiltration >> dimensionOfData; - - this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector( dimensionOfData , false ); - - std::vector sizes; - sizes.reserve( dimensionOfData ); - for ( size_t i = 0 ; i != dimensionOfData ; ++i ) - { - int size_in_this_dimension; - inFiltration >> size_in_this_dimension; - if ( size_in_this_dimension < 0 ) - { - this->directions_in_which_periodic_b_cond_are_to_be_imposed[i] = true; - } - sizes.push_back( abs(size_in_this_dimension) ); - } - this->set_up_containers( sizes ); - - typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it(*this); - it = this->top_dimensional_cells_iterator_begin(); - - while ( !inFiltration.eof() ) - { - double filtrationLevel; - inFiltration >> filtrationLevel; - if ( inFiltration.eof() )break; - - if ( dbg ) - { - cerr << "Cell of an index : " - << it.compute_index_in_bitmap() - << " and dimension: " - << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) - << " get the value : " << filtrationLevel << endl; - } - this->get_cell_data(*it) = filtrationLevel; - ++it; - } - inFiltration.close(); - this->impose_lower_star_filtration(); - -/* - char* filename = (char*)perseus_style_file; - //char* filename = "combustionWithPeriodicBoundaryConditions/v0/tV0_000000.float"; - ifstream file( filename , ios::binary | ios::ate ); - unsigned realSizeOfFile = file.tellg(); - file.close(); - realSizeOfFile = realSizeOfFile/sizeof(T); - - unsigned w, h, d; - - w = h = d = ceil(pow( realSizeOfFile , (double)(1/(double)3) )); - - T* slice = new T[w*h*d]; - if (slice == NULL) - { - cerr << "Allocation error, cannot allocate " << w*h*d*sizeof(T) << " bytes to store the data from the file. The program will now terminate \n"; - exit(EXIT_FAILURE); - } - - FILE* fp; - if ((fp=fopen( filename, "rb" )) == NULL ) - { - cerr << "Cannot open the file: " << filename << ". The program will now terminate \n"; - exit(1); - } - - clock_t read_begin = clock(); - fread( slice,4,w*h*d,fp ); - fclose(fp); - cerr << "Time of reading the file : " << double(clock() - read_begin) / CLOCKS_PER_SEC << endl; - - - clock_t begin_creation_bitap = clock(); - std::vector data(slice,slice+w*h*d); - delete[] slice; - std::vector< unsigned > sizes; - sizes.push_back(w); - sizes.push_back(w); - sizes.push_back(w); - - this->directions_in_which_periodic_b_cond_are_to_be_imposed.push_back( true ); - this->directions_in_which_periodic_b_cond_are_to_be_imposed.push_back( true ); - this->directions_in_which_periodic_b_cond_are_to_be_imposed.push_back( true ); - this->set_up_containers( sizes ); - - size_t i = 0; - for ( typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it = this->top_dimensional_cells_iterator_begin() ; it != this->top_dimensional_cells_iterator_end() ; ++it ) - { - *it = data[i]; - ++i; - } - this->impose_lower_star_filtration(); - cerr << "Time of creation of a bitmap : " << double(clock() - begin_creation_bitap ) / CLOCKS_PER_SEC << endl; - */ -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& sizes ) -{ - this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector( sizes.size() , false ); - this->set_up_containers( sizes ); -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& dimensions , const std::vector& topDimensionalCells ) -{ - std::vector directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector( dimensions.size() , false ); - this->construct_complex_based_on_top_dimensional_cells( dimensions , topDimensionalCells , directions_in_which_periodic_b_cond_are_to_be_imposed ); -} - - - - - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( const std::vector& dimensions , const std::vector& topDimensionalCells , const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed ) -{ - this->construct_complex_based_on_top_dimensional_cells( dimensions , topDimensionalCells , directions_in_which_periodic_b_cond_are_to_be_imposed ); -} - -//***********************Methods************************// - -template -std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base::get_boundary_of_a_cell( size_t cell )const -{ - bool dbg = false; - if ( dbg ){cerr << "Computations of boundary of a cell : " << cell << endl;} - - std::vector< size_t > boundary_elements; - size_t cell1 = cell; - for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) - { - unsigned position = cell1/this->multipliers[i-1]; - //this cell have a nonzero length in this direction, therefore we can compute its boundary in this direction. - - if ( position%2 == 1 ) - { - //if there are no periodic boundary conditions in this direction, we do not have to do anything. - if ( !directions_in_which_periodic_b_cond_are_to_be_imposed[i-1] ) - { - //cerr << "A\n"; - boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); - boundary_elements.push_back( cell + this->multipliers[ i-1 ] ); - if (dbg){cerr << cell - this->multipliers[ i-1 ] << " " << cell + this->multipliers[ i-1 ] << " ";} - } - else - { - //in this direction we have to do boundary conditions. Therefore, we need to check if we are not at the end. - if ( position != 2*this->sizes[ i-1 ]-1 ) - { - //cerr << "B\n"; - boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); - boundary_elements.push_back( cell + this->multipliers[ i-1 ] ); - if (dbg){cerr << cell - this->multipliers[ i-1 ] << " " << cell + this->multipliers[ i-1 ] << " ";} - } - else - { - //cerr << "C\n"; - boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); - boundary_elements.push_back( cell - (2*this->sizes[ i-1 ]-1)*this->multipliers[ i-1 ] ); - if (dbg){cerr << cell - this->multipliers[ i-1 ] << " " << cell - (2*this->sizes[ i-1 ]-1)*this->multipliers[ i-1 ] << " ";} - } - } - } - cell1 = cell1%this->multipliers[i-1]; - } - return boundary_elements; -} - -template -std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base::get_coboundary_of_a_cell( size_t cell )const -{ - std::vector counter = this->compute_counter_for_given_cell( cell ); - std::vector< size_t > coboundary_elements; - size_t cell1 = cell; - for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) - { - unsigned position = cell1/this->multipliers[i-1]; - //if the cell has zero length in this direction, then it will have cbd in this direction. - if ( position%2 == 0 ) - { - if ( !this->directions_in_which_periodic_b_cond_are_to_be_imposed[i-1] ) - { - //no periodic boundary conditions in this direction - if ( (counter[i-1] != 0) && (cell > this->multipliers[i-1]) ) - { - coboundary_elements.push_back( cell - this->multipliers[i-1] ); - } - if ( (counter[i-1] != 2*this->sizes[i-1]) && (cell + this->multipliers[i-1] < this->data.size()) ) - { - coboundary_elements.push_back( cell + this->multipliers[i-1] ); - } - } - else - { - //we want to have periodic boundary conditions in this direction - if ( counter[i-1] != 0 ) - { - coboundary_elements.push_back( cell - this->multipliers[i-1] ); - coboundary_elements.push_back( cell + this->multipliers[i-1] ); - } - else - { - //in this case counter[i-1] == 0. - coboundary_elements.push_back( cell + this->multipliers[i-1] ); - coboundary_elements.push_back( cell + (2*this->sizes[ i-1 ]-1)*this->multipliers[i-1] ); - } - } - } - - cell1 = cell1%this->multipliers[i-1]; - } - return coboundary_elements; -} - - - -}//Cubical_complex -}//namespace Gudhi +*/ +template +class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base { + public: + // constructors that take an extra parameter: + + /** + * Default constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class. + */ + Bitmap_cubical_complex_periodic_boundary_conditions_base() { } + /** + * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following + * parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of booleans. If + * at i-th position of this vector there is true value, that means that periodic boundary conditions are to be + * imposed in this direction. In case of false, the periodic boundary conditions will not be imposed in the direction + * i. + */ + Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& sizes, + const std::vector& directions_in_which_periodic_b_cond_are_to_be_imposed); + /** + * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the name of Perseus + * style file as an input. Please consult the documentation about the specification of the file. + */ + Bitmap_cubical_complex_periodic_boundary_conditions_base(const char* perseusStyleFile); + /** + * A constructor of Bitmap_cubical_complex_periodic_boundary_conditions_base class that takes the following + * parameters: (1) vector with numbers of top dimensional cells in all dimensions and (2) vector of top dimensional + * cells (ordered lexicographically) and (3) vector of booleans. If at i-th position of this vector there is true + * value, that means that periodic boundary conditions are to be imposed in this direction. In case of false, the + * periodic boundary conditions will not be imposed in the direction i. + */ + Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& dimensions, + const std::vector& topDimensionalCells, + const std::vector< bool >& directions_in_which_periodic_b_cond_are_to_be_imposed); + + /** + * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class. + **/ + virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base(){} + + // overwritten methods co compute boundary and coboundary + /** + * A version of a function that return boundary of a given cell for an object of Bitmap_cubical_complex_periodic_boundary_conditions_base class. + */ + virtual std::vector< size_t > get_boundary_of_a_cell(size_t cell)const; + + /** + * A version of a function that return coboundary of a given cell for an object of Bitmap_cubical_complex_periodic_boundary_conditions_base class. + */ + virtual std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; + + protected: + std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed; + + void set_up_containers(const std::vector& sizes) { + unsigned multiplier = 1; + for (size_t i = 0; i != sizes.size(); ++i) { + this->sizes.push_back(sizes[i]); + this->multipliers.push_back(multiplier); + + if (directions_in_which_periodic_b_cond_are_to_be_imposed[i]) { + multiplier *= 2 * sizes[i]; + } else { + multiplier *= 2 * sizes[i] + 1; + } + } + // std::reverse( this->sizes.begin() , this->sizes.end() ); + this->data = std::vector(multiplier, std::numeric_limits::max()); + this->total_number_of_cells = multiplier; + } + Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& sizes); + Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& dimensions, + const std::vector& topDimensionalCells); + void construct_complex_based_on_top_dimensional_cells(const std::vector& dimensions, + const std::vector& topDimensionalCells, + const std::vector& directions_in_which_periodic_b_cond_are_to_be_imposed); +}; + +template +void Bitmap_cubical_complex_periodic_boundary_conditions_base::construct_complex_based_on_top_dimensional_cells(const std::vector& dimensions, + const std::vector& topDimensionalCells, + const std::vector& directions_in_which_periodic_b_cond_are_to_be_imposed) { + this->directions_in_which_periodic_b_cond_are_to_be_imposed = directions_in_which_periodic_b_cond_are_to_be_imposed; + this->set_up_containers(dimensions); + + size_t i = 0; + for (typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) { + this->get_cell_data(*it) = topDimensionalCells[i]; + ++i; + } + this->impose_lower_star_filtration(); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& sizes, + const std::vector& directions_in_which_periodic_b_cond_are_to_be_imposed) { + this->directions_in_which_periodic_b_cond_are_to_be_imposed(directions_in_which_periodic_b_cond_are_to_be_imposed); + this->set_up_containers(sizes); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base(const char* perseus_style_file) { + // for Perseus style files: + bool dbg = false; + + std::ifstream inFiltration; + inFiltration.open(perseus_style_file); + unsigned dimensionOfData; + inFiltration >> dimensionOfData; + + this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector(dimensionOfData, false); + + std::vector sizes; + sizes.reserve(dimensionOfData); + for (size_t i = 0; i != dimensionOfData; ++i) { + int size_in_this_dimension; + inFiltration >> size_in_this_dimension; + if (size_in_this_dimension < 0) { + this->directions_in_which_periodic_b_cond_are_to_be_imposed[i] = true; + } + sizes.push_back(abs(size_in_this_dimension)); + } + this->set_up_containers(sizes); + + typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it(*this); + it = this->top_dimensional_cells_iterator_begin(); + + while (!inFiltration.eof()) { + double filtrationLevel; + inFiltration >> filtrationLevel; + if (inFiltration.eof())break; + + if (dbg) { + std::cerr << "Cell of an index : " + << it.compute_index_in_bitmap() + << " and dimension: " + << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) + << " get the value : " << filtrationLevel << std::endl; + } + this->get_cell_data(*it) = filtrationLevel; + ++it; + } + inFiltration.close(); + this->impose_lower_star_filtration(); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& sizes) { + this->directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector(sizes.size(), false); + this->set_up_containers(sizes); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& dimensions, + const std::vector& topDimensionalCells) { + std::vector directions_in_which_periodic_b_cond_are_to_be_imposed = std::vector(dimensions.size(), false); + this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells, + directions_in_which_periodic_b_cond_are_to_be_imposed); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base:: +Bitmap_cubical_complex_periodic_boundary_conditions_base(const std::vector& dimensions, + const std::vector& topDimensionalCells, + const std::vector& directions_in_which_periodic_b_cond_are_to_be_imposed) { + this->construct_complex_based_on_top_dimensional_cells(dimensions, topDimensionalCells, + directions_in_which_periodic_b_cond_are_to_be_imposed); +} + +// ***********************Methods************************ // + +template +std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base::get_boundary_of_a_cell(size_t cell) const { + bool dbg = false; + if (dbg) { + std::cerr << "Computations of boundary of a cell : " << cell << std::endl; + } + + std::vector< size_t > boundary_elements; + size_t cell1 = cell; + for (size_t i = this->multipliers.size(); i != 0; --i) { + unsigned position = cell1 / this->multipliers[i - 1]; + // this cell have a nonzero length in this direction, therefore we can compute its boundary in this direction. + + if (position % 2 == 1) { + // if there are no periodic boundary conditions in this direction, we do not have to do anything. + if (!directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) { + // std::cerr << "A\n"; + boundary_elements.push_back(cell - this->multipliers[ i - 1 ]); + boundary_elements.push_back(cell + this->multipliers[ i - 1 ]); + if (dbg) { + std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " "; + } + } else { + // in this direction we have to do boundary conditions. Therefore, we need to check if we are not at the end. + if (position != 2 * this->sizes[ i - 1 ] - 1) { + // std::cerr << "B\n"; + boundary_elements.push_back(cell - this->multipliers[ i - 1 ]); + boundary_elements.push_back(cell + this->multipliers[ i - 1 ]); + if (dbg) { + std::cerr << cell - this->multipliers[ i - 1 ] << " " << cell + this->multipliers[ i - 1 ] << " "; + } + } else { + // std::cerr << "C\n"; + boundary_elements.push_back(cell - this->multipliers[ i - 1 ]); + boundary_elements.push_back(cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ]); + if (dbg) { + std::cerr << cell - this->multipliers[ i - 1 ] << " " << + cell - (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[ i - 1 ] << " "; + } + } + } + } + cell1 = cell1 % this->multipliers[i - 1]; + } + return boundary_elements; +} + +template +std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base::get_coboundary_of_a_cell(size_t cell) const { + std::vector counter = this->compute_counter_for_given_cell(cell); + std::vector< size_t > coboundary_elements; + size_t cell1 = cell; + for (size_t i = this->multipliers.size(); i != 0; --i) { + unsigned position = cell1 / this->multipliers[i - 1]; + // if the cell has zero length in this direction, then it will have cbd in this direction. + if (position % 2 == 0) { + if (!this->directions_in_which_periodic_b_cond_are_to_be_imposed[i - 1]) { + // no periodic boundary conditions in this direction + if ((counter[i - 1] != 0) && (cell > this->multipliers[i - 1])) { + coboundary_elements.push_back(cell - this->multipliers[i - 1]); + } + if ((counter[i - 1] != 2 * this->sizes[i - 1]) && (cell + this->multipliers[i - 1] < this->data.size())) { + coboundary_elements.push_back(cell + this->multipliers[i - 1]); + } + } else { + // we want to have periodic boundary conditions in this direction + if (counter[i - 1] != 0) { + coboundary_elements.push_back(cell - this->multipliers[i - 1]); + coboundary_elements.push_back(cell + this->multipliers[i - 1]); + } else { + // in this case counter[i-1] == 0. + coboundary_elements.push_back(cell + this->multipliers[i - 1]); + coboundary_elements.push_back(cell + (2 * this->sizes[ i - 1 ] - 1) * this->multipliers[i - 1]); + } + } + } + + cell1 = cell1 % this->multipliers[i - 1]; + } + return coboundary_elements; +} + +} // namespace Cubical_complex + +} // namespace Gudhi + +#endif // BITMAP_CUBICAL_COMPLEX_PERIODIC_BOUNDARY_CONDITIONS_BASE_H_ diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index 35c54ade..a9162cee 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -1,105 +1,79 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Pawel Dlotko + * + * Copyright (C) 2015 INRIA Saclay (France) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "cubical_complex" +#include + #include #include #include -#include // standard stuff #include #include +#include -#define BOOST_TEST_DYN_LINK -#define BOOST_TEST_MODULE "cubical_complex" -#include +typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_base Bitmap_cubical_complex_base; +typedef Gudhi::Cubical_complex::Bitmap_cubical_complex Bitmap_cubical_complex; -using namespace std; -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; -using namespace Gudhi::persistent_cohomology; +typedef Gudhi::Cubical_complex::Bitmap_cubical_complex_periodic_boundary_conditions_base +Bitmap_cubical_complex_periodic_boundary_conditions_base; +typedef Gudhi::Cubical_complex::Bitmap_cubical_complex +Bitmap_cubical_complex_periodic_boundary_conditions; +BOOST_AUTO_TEST_CASE(check_dimension) { + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + std::vector dimensions({3, 3}); -BOOST_AUTO_TEST_CASE(check_dimension) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); BOOST_CHECK(increasing.dimension() == 2); } BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { - std::vector< double > expectedFiltrationValues1; - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(100); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - expectedFiltrationValues1.push_back(0); - - std::vector< double > expectedFiltrationValues2; - expectedFiltrationValues2.push_back(1); - expectedFiltrationValues2.push_back(2); - expectedFiltrationValues2.push_back(3); - expectedFiltrationValues2.push_back(4); - expectedFiltrationValues2.push_back(5); - expectedFiltrationValues2.push_back(6); - expectedFiltrationValues2.push_back(7); - expectedFiltrationValues2.push_back(8); - expectedFiltrationValues2.push_back(9); - - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector< double > oneDimensionalCycle; - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(100); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - oneDimensionalCycle.push_back(0); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - Bitmap_cubical_complex< Bitmap_cubical_complex_base > hole(dimensions, oneDimensionalCycle); + std::vector< double > expectedFiltrationValues1({0, 0, 0, 0, 100, 0, 0, 0, 0}); + + std::vector< double > expectedFiltrationValues2({1, 2, 3, 4, 5, 6, 7, 8, 9}); + + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + + std::vector< double > oneDimensionalCycle({0, 0, 0, 0, 100, 0, 0, 0, 0}); + + std::vector dimensions({3, 3}); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle); int i = 0; - for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = increasing.top_dimensional_cells_iterator_begin(); it != increasing.top_dimensional_cells_iterator_end(); ++it) { BOOST_CHECK(increasing.get_cell_data(*it) == expectedFiltrationValues2[i]); ++i; } i = 0; - for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator + for (Bitmap_cubical_complex::Top_dimensional_cells_iterator it = hole.top_dimensional_cells_iterator_begin(); it != hole.top_dimensional_cells_iterator_end(); ++it) { BOOST_CHECK(hole.get_cell_data(*it) == expectedFiltrationValues1[i]); ++i; @@ -107,7 +81,6 @@ BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { } BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { - std::vector boundary0; std::vector boundary1; boundary1.push_back(0); @@ -294,22 +267,11 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); + std::vector dimensions({3, 3}); - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); for (size_t i = 0; i != increasing.size(); ++i) { std::vector< size_t > bd = increasing.get_boundary_of_a_cell(i); for (size_t j = 0; j != bd.size(); ++j) { @@ -319,22 +281,11 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { } BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); + std::vector dimensions({3, 3}); - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector coboundaryElements; @@ -429,27 +380,15 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { BOOST_CHECK(coboundaryElements[number] == bd[j]); ++number; } - } } BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + + std::vector dimensions({3, 3}); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector dim; dim.push_back(0); @@ -508,22 +447,11 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { } BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { - std::vector< double > increasingFiltrationOfTopDimensionalCells; - increasingFiltrationOfTopDimensionalCells.push_back(1); - increasingFiltrationOfTopDimensionalCells.push_back(2); - increasingFiltrationOfTopDimensionalCells.push_back(3); - increasingFiltrationOfTopDimensionalCells.push_back(4); - increasingFiltrationOfTopDimensionalCells.push_back(5); - increasingFiltrationOfTopDimensionalCells.push_back(6); - increasingFiltrationOfTopDimensionalCells.push_back(7); - increasingFiltrationOfTopDimensionalCells.push_back(8); - increasingFiltrationOfTopDimensionalCells.push_back(9); - - std::vector dimensions; - dimensions.push_back(3); - dimensions.push_back(3); - - Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + std::vector< double > increasingFiltrationOfTopDimensionalCells({1, 2, 3, 4, 5, 6, 7, 8, 9}); + + std::vector dimensions({3, 3}); + + Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector< unsigned > dim; dim.push_back(0); @@ -628,104 +556,93 @@ BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { fil.push_back(9); - Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Filtration_simplex_range range = increasing.filtration_simplex_range(); + Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range(); size_t position = 0; - for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) { + for (Bitmap_cubical_complex::Filtration_simplex_iterator it = range.begin(); it != range.end(); ++it) { BOOST_CHECK(increasing.dimension(*it) == dim[position]); BOOST_CHECK(increasing.filtration(*it) == fil[position]); ++position; } } - - - + BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { - std::vector< double > filtration; - filtration.push_back(0); - filtration.push_back(0); - filtration.push_back(0); - filtration.push_back(0); - - - std::vector dimensions; - dimensions.push_back(2); - dimensions.push_back(2); - - std::vector periodic_directions; - periodic_directions.push_back(true); - periodic_directions.push_back(true); - - Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > cmplx(dimensions, filtration,periodic_directions); - BOOST_CHECK(cmplx.dimension() == 2); - - + std::vector< double > filtration({0, 0, 0, 0}); + + std::vector dimensions({2, 2}); + + std::vector periodic_directions({true, true}); + + Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions); + BOOST_CHECK(cmplx.dimension() == 2); + + std::vector boundary0; - std::vector boundary1; - boundary1.push_back(0); - boundary1.push_back(2); - std::vector boundary2; - std::vector boundary3; - boundary3.push_back(2); - boundary3.push_back(0); - std::vector boundary4; - boundary4.push_back(0); - boundary4.push_back(8); - std::vector boundary5; - boundary5.push_back(1); - boundary5.push_back(9); - boundary5.push_back(4); - boundary5.push_back(6); - std::vector boundary6; - boundary6.push_back(2); - boundary6.push_back(10); - std::vector boundary7; - boundary7.push_back(3); - boundary7.push_back(11); - boundary7.push_back(6); - boundary7.push_back(4); - std::vector boundary8; - std::vector boundary9; - boundary9.push_back(8); - boundary9.push_back(10); - std::vector boundary10; - std::vector boundary11; - boundary11.push_back(10); - boundary11.push_back(8); - std::vector boundary12; - boundary12.push_back(8); - boundary12.push_back(0); - std::vector boundary13; - boundary13.push_back(9); - boundary13.push_back(1); - boundary13.push_back(12); - boundary13.push_back(14); - std::vector boundary14; - boundary14.push_back(10); - boundary14.push_back(2); - std::vector boundary15; - boundary15.push_back(11); - boundary15.push_back(3); - boundary15.push_back(14); - boundary15.push_back(12); - - std::vector< std::vector > boundaries; - boundaries.push_back( boundary0 ); - boundaries.push_back( boundary1 ); - boundaries.push_back( boundary2 ); - boundaries.push_back( boundary3 ); - boundaries.push_back( boundary4 ); - boundaries.push_back( boundary5 ); - boundaries.push_back( boundary6 ); - boundaries.push_back( boundary7 ); - boundaries.push_back( boundary8 ); - boundaries.push_back( boundary9 ); - boundaries.push_back( boundary10 ); - boundaries.push_back( boundary11 ); - boundaries.push_back( boundary12 ); - boundaries.push_back( boundary13 ); - boundaries.push_back( boundary14 ); - boundaries.push_back( boundary15 ); - + std::vector boundary1; + boundary1.push_back(0); + boundary1.push_back(2); + std::vector boundary2; + std::vector boundary3; + boundary3.push_back(2); + boundary3.push_back(0); + std::vector boundary4; + boundary4.push_back(0); + boundary4.push_back(8); + std::vector boundary5; + boundary5.push_back(1); + boundary5.push_back(9); + boundary5.push_back(4); + boundary5.push_back(6); + std::vector boundary6; + boundary6.push_back(2); + boundary6.push_back(10); + std::vector boundary7; + boundary7.push_back(3); + boundary7.push_back(11); + boundary7.push_back(6); + boundary7.push_back(4); + std::vector boundary8; + std::vector boundary9; + boundary9.push_back(8); + boundary9.push_back(10); + std::vector boundary10; + std::vector boundary11; + boundary11.push_back(10); + boundary11.push_back(8); + std::vector boundary12; + boundary12.push_back(8); + boundary12.push_back(0); + std::vector boundary13; + boundary13.push_back(9); + boundary13.push_back(1); + boundary13.push_back(12); + boundary13.push_back(14); + std::vector boundary14; + boundary14.push_back(10); + boundary14.push_back(2); + std::vector boundary15; + boundary15.push_back(11); + boundary15.push_back(3); + boundary15.push_back(14); + boundary15.push_back(12); + + std::vector< std::vector > boundaries; + boundaries.push_back(boundary0); + boundaries.push_back(boundary1); + boundaries.push_back(boundary2); + boundaries.push_back(boundary3); + boundaries.push_back(boundary4); + boundaries.push_back(boundary5); + boundaries.push_back(boundary6); + boundaries.push_back(boundary7); + boundaries.push_back(boundary8); + boundaries.push_back(boundary9); + boundaries.push_back(boundary10); + boundaries.push_back(boundary11); + boundaries.push_back(boundary12); + boundaries.push_back(boundary13); + boundaries.push_back(boundary14); + boundaries.push_back(boundary15); + for (size_t i = 0; i != cmplx.size(); ++i) { std::vector< size_t > bd = cmplx.get_boundary_of_a_cell(i); for (size_t j = 0; j != bd.size(); ++j) { @@ -733,759 +650,729 @@ BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { } } } - - - - - - + BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { - std::vector< double > filtration; - filtration.push_back(0); - filtration.push_back(0); - filtration.push_back(0); - filtration.push_back(0); - - - std::vector dimensions; - dimensions.push_back(2); - dimensions.push_back(2); - - std::vector periodic_directions; - periodic_directions.push_back(true); - periodic_directions.push_back(true); - - Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > cmplx(dimensions, filtration,periodic_directions); - BOOST_CHECK(cmplx.dimension() == 2); - - - std::vector coboundary0; - coboundary0.push_back(4); - coboundary0.push_back(12); - coboundary0.push_back(1); - coboundary0.push_back(3); - std::vector coboundary1; - coboundary1.push_back(5); - coboundary1.push_back(13); - std::vector coboundary2; - coboundary2.push_back(6); - coboundary2.push_back(14); - coboundary2.push_back(1); - coboundary2.push_back(3); - std::vector coboundary3; - coboundary3.push_back(7); - coboundary3.push_back(15); - std::vector coboundary4; - coboundary4.push_back(5); - coboundary4.push_back(7); - std::vector coboundary5; - std::vector coboundary6; - coboundary6.push_back(5); - coboundary6.push_back(7); - std::vector coboundary7; - std::vector coboundary8; - coboundary8.push_back(4); - coboundary8.push_back(12); - coboundary8.push_back(9); - coboundary8.push_back(11); - std::vector coboundary9; - coboundary9.push_back(5); - coboundary9.push_back(13); - std::vector coboundary10; - coboundary10.push_back(6); - coboundary10.push_back(14); - coboundary10.push_back(9); - coboundary10.push_back(11); - std::vector coboundary11; - coboundary11.push_back(7); - coboundary11.push_back(15); - std::vector coboundary12; - coboundary12.push_back(13); - coboundary12.push_back(15); - std::vector coboundary13; - std::vector coboundary14; - coboundary14.push_back(13); - coboundary14.push_back(15); + std::vector< double > filtration({0, 0, 0, 0}); + + std::vector dimensions({2, 2}); + + std::vector periodic_directions({true, true}); + + Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtration, periodic_directions); + BOOST_CHECK(cmplx.dimension() == 2); + + + std::vector coboundary0; + coboundary0.push_back(4); + coboundary0.push_back(12); + coboundary0.push_back(1); + coboundary0.push_back(3); + std::vector coboundary1; + coboundary1.push_back(5); + coboundary1.push_back(13); + std::vector coboundary2; + coboundary2.push_back(6); + coboundary2.push_back(14); + coboundary2.push_back(1); + coboundary2.push_back(3); + std::vector coboundary3; + coboundary3.push_back(7); + coboundary3.push_back(15); + std::vector coboundary4; + coboundary4.push_back(5); + coboundary4.push_back(7); + std::vector coboundary5; + std::vector coboundary6; + coboundary6.push_back(5); + coboundary6.push_back(7); + std::vector coboundary7; + std::vector coboundary8; + coboundary8.push_back(4); + coboundary8.push_back(12); + coboundary8.push_back(9); + coboundary8.push_back(11); + std::vector coboundary9; + coboundary9.push_back(5); + coboundary9.push_back(13); + std::vector coboundary10; + coboundary10.push_back(6); + coboundary10.push_back(14); + coboundary10.push_back(9); + coboundary10.push_back(11); + std::vector coboundary11; + coboundary11.push_back(7); + coboundary11.push_back(15); + std::vector coboundary12; + coboundary12.push_back(13); + coboundary12.push_back(15); + std::vector coboundary13; + std::vector coboundary14; + coboundary14.push_back(13); + coboundary14.push_back(15); std::vector coboundary15; - - std::vector< std::vector > coboundaries; - coboundaries.push_back( coboundary0 ); - coboundaries.push_back( coboundary1 ); - coboundaries.push_back( coboundary2 ); - coboundaries.push_back( coboundary3 ); - coboundaries.push_back( coboundary4 ); - coboundaries.push_back( coboundary5 ); - coboundaries.push_back( coboundary6 ); - coboundaries.push_back( coboundary7 ); - coboundaries.push_back( coboundary8 ); - coboundaries.push_back( coboundary9 ); - coboundaries.push_back( coboundary10 ); - coboundaries.push_back( coboundary11 ); - coboundaries.push_back( coboundary12 ); - coboundaries.push_back( coboundary13 ); - coboundaries.push_back( coboundary14 ); - coboundaries.push_back( coboundary15 ); - + + std::vector< std::vector > coboundaries; + coboundaries.push_back(coboundary0); + coboundaries.push_back(coboundary1); + coboundaries.push_back(coboundary2); + coboundaries.push_back(coboundary3); + coboundaries.push_back(coboundary4); + coboundaries.push_back(coboundary5); + coboundaries.push_back(coboundary6); + coboundaries.push_back(coboundary7); + coboundaries.push_back(coboundary8); + coboundaries.push_back(coboundary9); + coboundaries.push_back(coboundary10); + coboundaries.push_back(coboundary11); + coboundaries.push_back(coboundary12); + coboundaries.push_back(coboundary13); + coboundaries.push_back(coboundary14); + coboundaries.push_back(coboundary15); + for (size_t i = 0; i != cmplx.size(); ++i) { std::vector< size_t > cbd = cmplx.get_coboundary_of_a_cell(i); for (size_t j = 0; j != cbd.size(); ++j) { BOOST_CHECK(coboundaries[i][j] == cbd[j]); } } -} - - - - - - - +} + BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { - std::vector< double > filtrationOrg; - filtrationOrg.push_back(0); - filtrationOrg.push_back(1); - filtrationOrg.push_back(2); - filtrationOrg.push_back(3); - - - std::vector dimensions; - dimensions.push_back(2); - dimensions.push_back(2); - - std::vector periodic_directions; - periodic_directions.push_back(true); - periodic_directions.push_back(true); - - Bitmap_cubical_complex< Bitmap_cubical_complex_periodic_boundary_conditions_base > cmplx(dimensions, filtrationOrg,periodic_directions); - BOOST_CHECK(cmplx.dimension() == 2); - - - std::vector filtration; - filtration.push_back(0);//0 - filtration.push_back(0);//1 - filtration.push_back(0);//2 - filtration.push_back(1);//3 - filtration.push_back(0);//4 - filtration.push_back(0);//5 - filtration.push_back(0);//6 - filtration.push_back(1);//7 - filtration.push_back(0);//8 - filtration.push_back(0);//9 - filtration.push_back(0);//10 - filtration.push_back(1);//11 - filtration.push_back(2);//12 - filtration.push_back(2);//13 - filtration.push_back(2);//14 - filtration.push_back(3);//15 - - - for (size_t i = 0; i != cmplx.size(); ++i) - { - BOOST_CHECK( filtration[i] == cmplx.get_cell_data(i) ); + std::vector< double > filtrationOrg({0, 1, 2, 3}); + + std::vector dimensions({2, 2}); + + std::vector periodic_directions({true, true}); + + Bitmap_cubical_complex_periodic_boundary_conditions cmplx(dimensions, filtrationOrg, periodic_directions); + BOOST_CHECK(cmplx.dimension() == 2); + + + std::vector filtration; + filtration.push_back(0); // 0 + filtration.push_back(0); // 1 + filtration.push_back(0); // 2 + filtration.push_back(1); // 3 + filtration.push_back(0); // 4 + filtration.push_back(0); // 5 + filtration.push_back(0); // 6 + filtration.push_back(1); // 7 + filtration.push_back(0); // 8 + filtration.push_back(0); // 9 + filtration.push_back(0); // 10 + filtration.push_back(1); // 11 + filtration.push_back(2); // 12 + filtration.push_back(2); // 13 + filtration.push_back(2); // 14 + filtration.push_back(3); // 15 + + + for (size_t i = 0; i != cmplx.size(); ++i) { + BOOST_CHECK(filtration[i] == cmplx.get_cell_data(i)); } -} - -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - for ( Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin() ; it != ba.all_cells_iterator_end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; - } -} - - - - - - - - -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check_2) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - - Bitmap_cubical_complex_base::All_cells_range range(&ba); - for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; - } -} - - - - - - -BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - std::vector expected_dimension; - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(2); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - expected_dimension.push_back(1); - expected_dimension.push_back(0); - - std::vector expected_boundary; - expected_boundary.push_back(0); - expected_boundary.push_back(2); - expected_boundary.push_back(2); - expected_boundary.push_back(4); - expected_boundary.push_back(0); - expected_boundary.push_back(10); - expected_boundary.push_back(1); - expected_boundary.push_back(11); - expected_boundary.push_back(5); - expected_boundary.push_back(7); - expected_boundary.push_back(2); - expected_boundary.push_back(12); - expected_boundary.push_back(3); - expected_boundary.push_back(13); - expected_boundary.push_back(7); - expected_boundary.push_back(9); - expected_boundary.push_back(4); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(12); - expected_boundary.push_back(12); - expected_boundary.push_back(14); - expected_boundary.push_back(10); - expected_boundary.push_back(20); - expected_boundary.push_back(11); - expected_boundary.push_back(21); - expected_boundary.push_back(15); - expected_boundary.push_back(17); - expected_boundary.push_back(12); - expected_boundary.push_back(22); - expected_boundary.push_back(13); - expected_boundary.push_back(23); - expected_boundary.push_back(17); - expected_boundary.push_back(19); - expected_boundary.push_back(14); - expected_boundary.push_back(24); - expected_boundary.push_back(20); - expected_boundary.push_back(22); - expected_boundary.push_back(22); - expected_boundary.push_back(24); - - - std::vector expected_coboundary; - expected_coboundary.push_back(5); - expected_coboundary.push_back(1); - expected_coboundary.push_back(6); - expected_coboundary.push_back(7); - expected_coboundary.push_back(1); - expected_coboundary.push_back(3); - expected_coboundary.push_back(8); - expected_coboundary.push_back(9); - expected_coboundary.push_back(3); - expected_coboundary.push_back(6); - expected_coboundary.push_back(6); - expected_coboundary.push_back(8); - expected_coboundary.push_back(8); - expected_coboundary.push_back(5); - expected_coboundary.push_back(15); - expected_coboundary.push_back(11); - expected_coboundary.push_back(6); - expected_coboundary.push_back(16); - expected_coboundary.push_back(7); - expected_coboundary.push_back(17); - expected_coboundary.push_back(11); - expected_coboundary.push_back(13); - expected_coboundary.push_back(8); - expected_coboundary.push_back(18); - expected_coboundary.push_back(9); - expected_coboundary.push_back(19); - expected_coboundary.push_back(13); - expected_coboundary.push_back(16); - expected_coboundary.push_back(16); - expected_coboundary.push_back(18); - expected_coboundary.push_back(18); - expected_coboundary.push_back(15); - expected_coboundary.push_back(21); - expected_coboundary.push_back(16); - expected_coboundary.push_back(17); - expected_coboundary.push_back(21); - expected_coboundary.push_back(23); - expected_coboundary.push_back(18); - expected_coboundary.push_back(19); - expected_coboundary.push_back(23); - - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - int bd_it = 0; - int cbd_it = 0; - - Bitmap_cubical_complex_base::All_cells_range range = ba.all_cells_range(); - for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); - - Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); - for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) - { - BOOST_CHECK( expected_boundary[bd_it] == *bd ); - ++bd_it; - } - - Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); - for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) - { - BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); - ++cbd_it; - } - ++i; - } -} - -BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check) -{ - std::vector< double > expected_filtration; - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(0); - expected_filtration.push_back(1); - expected_filtration.push_back(1); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(2); - expected_filtration.push_back(3); - expected_filtration.push_back(3); - - - std::vector< unsigned > sizes(2); - sizes[0] = 2; - sizes[1] = 2; - - std::vector< double > data(4); - data[0] = 0; - data[1] = 1; - data[2] = 2; - data[3] = 3; - - Bitmap_cubical_complex_base ba( sizes , data ); - int i = 0; - - Bitmap_cubical_complex_base::Top_dimensional_cells_range range = ba.top_dimensional_cells_range(); - for ( Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it = range.begin() ; it != range.end() ; ++it ) - { - BOOST_CHECK( data[i] == ba.get_cell_data( *it ) ); - BOOST_CHECK( ba.get_dimension_of_a_cell( *it ) == 2 ); - ++i; - } -} +} +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check) +{ + std::vector< double > expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(5); + expected_boundary.push_back(7); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(7); + expected_boundary.push_back(9); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(15); + expected_boundary.push_back(17); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(17); + expected_boundary.push_back(19); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + + std::vector expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + + + std::vector< unsigned > sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector< double > data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba( sizes , data ); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + for ( Bitmap_cubical_complex_base::All_cells_iterator it = ba.all_cells_iterator_begin() ; it != ba.all_cells_iterator_end() ; ++it ) + { + BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); + BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) + { + BOOST_CHECK( expected_boundary[bd_it] == *bd ); + ++bd_it; + } + + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) + { + BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); + ++cbd_it; + } + ++i; + } +} + + + + + + + + +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check_2) +{ + std::vector< double > expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(5); + expected_boundary.push_back(7); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(7); + expected_boundary.push_back(9); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(15); + expected_boundary.push_back(17); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(17); + expected_boundary.push_back(19); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + + std::vector expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + + + std::vector< unsigned > sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector< double > data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba( sizes , data ); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + + Bitmap_cubical_complex_base::All_cells_range range(&ba); + for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) + { + BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); + BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) + { + BOOST_CHECK( expected_boundary[bd_it] == *bd ); + ++bd_it; + } + + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) + { + BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); + ++cbd_it; + } + ++i; + } +} + + + + + + +BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical_complex_base_check_range_check) +{ + std::vector< double > expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + std::vector expected_dimension; + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(2); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + expected_dimension.push_back(1); + expected_dimension.push_back(0); + + std::vector expected_boundary; + expected_boundary.push_back(0); + expected_boundary.push_back(2); + expected_boundary.push_back(2); + expected_boundary.push_back(4); + expected_boundary.push_back(0); + expected_boundary.push_back(10); + expected_boundary.push_back(1); + expected_boundary.push_back(11); + expected_boundary.push_back(5); + expected_boundary.push_back(7); + expected_boundary.push_back(2); + expected_boundary.push_back(12); + expected_boundary.push_back(3); + expected_boundary.push_back(13); + expected_boundary.push_back(7); + expected_boundary.push_back(9); + expected_boundary.push_back(4); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(12); + expected_boundary.push_back(12); + expected_boundary.push_back(14); + expected_boundary.push_back(10); + expected_boundary.push_back(20); + expected_boundary.push_back(11); + expected_boundary.push_back(21); + expected_boundary.push_back(15); + expected_boundary.push_back(17); + expected_boundary.push_back(12); + expected_boundary.push_back(22); + expected_boundary.push_back(13); + expected_boundary.push_back(23); + expected_boundary.push_back(17); + expected_boundary.push_back(19); + expected_boundary.push_back(14); + expected_boundary.push_back(24); + expected_boundary.push_back(20); + expected_boundary.push_back(22); + expected_boundary.push_back(22); + expected_boundary.push_back(24); + + + std::vector expected_coboundary; + expected_coboundary.push_back(5); + expected_coboundary.push_back(1); + expected_coboundary.push_back(6); + expected_coboundary.push_back(7); + expected_coboundary.push_back(1); + expected_coboundary.push_back(3); + expected_coboundary.push_back(8); + expected_coboundary.push_back(9); + expected_coboundary.push_back(3); + expected_coboundary.push_back(6); + expected_coboundary.push_back(6); + expected_coboundary.push_back(8); + expected_coboundary.push_back(8); + expected_coboundary.push_back(5); + expected_coboundary.push_back(15); + expected_coboundary.push_back(11); + expected_coboundary.push_back(6); + expected_coboundary.push_back(16); + expected_coboundary.push_back(7); + expected_coboundary.push_back(17); + expected_coboundary.push_back(11); + expected_coboundary.push_back(13); + expected_coboundary.push_back(8); + expected_coboundary.push_back(18); + expected_coboundary.push_back(9); + expected_coboundary.push_back(19); + expected_coboundary.push_back(13); + expected_coboundary.push_back(16); + expected_coboundary.push_back(16); + expected_coboundary.push_back(18); + expected_coboundary.push_back(18); + expected_coboundary.push_back(15); + expected_coboundary.push_back(21); + expected_coboundary.push_back(16); + expected_coboundary.push_back(17); + expected_coboundary.push_back(21); + expected_coboundary.push_back(23); + expected_coboundary.push_back(18); + expected_coboundary.push_back(19); + expected_coboundary.push_back(23); + + + + std::vector< unsigned > sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector< double > data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba( sizes , data ); + int i = 0; + int bd_it = 0; + int cbd_it = 0; + + Bitmap_cubical_complex_base::All_cells_range range = ba.all_cells_range(); + for ( Bitmap_cubical_complex_base::All_cells_iterator it = range.begin() ; it != range.end() ; ++it ) + { + BOOST_CHECK( expected_filtration[i] == ba.get_cell_data( *it ) ); + BOOST_CHECK( expected_dimension[i] == ba.get_dimension_of_a_cell( *it ) ); + + Bitmap_cubical_complex_base::Boundary_range bdrange = ba.boundary_range(*it); + for ( Bitmap_cubical_complex_base::Boundary_iterator bd = bdrange.begin() ; bd != bdrange.end() ; ++bd ) + { + BOOST_CHECK( expected_boundary[bd_it] == *bd ); + ++bd_it; + } + + Bitmap_cubical_complex_base::Coboundary_range cbdrange = ba.coboundary_range(*it); + for ( Bitmap_cubical_complex_base::Coboundary_iterator cbd = cbdrange.begin() ; cbd != cbdrange.end() ; ++cbd ) + { + BOOST_CHECK( expected_coboundary[cbd_it] == *cbd ); + ++cbd_it; + } + ++i; + } +} + +BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check) +{ + std::vector< double > expected_filtration; + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(0); + expected_filtration.push_back(1); + expected_filtration.push_back(1); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(2); + expected_filtration.push_back(3); + expected_filtration.push_back(3); + + + std::vector< unsigned > sizes(2); + sizes[0] = 2; + sizes[1] = 2; + + std::vector< double > data(4); + data[0] = 0; + data[1] = 1; + data[2] = 2; + data[3] = 3; + + Bitmap_cubical_complex_base ba( sizes , data ); + int i = 0; + + Bitmap_cubical_complex_base::Top_dimensional_cells_range range = ba.top_dimensional_cells_range(); + for ( Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it = range.begin() ; it != range.end() ; ++it ) + { + BOOST_CHECK( data[i] == ba.get_cell_data( *it ) ); + BOOST_CHECK( ba.get_dimension_of_a_cell( *it ) == 2 ); + ++i; + } +} + -- cgit v1.2.3