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 ++ src/Bitmap_cubical_complex/example/CMakeLists.txt | 12 + .../example/Random_bitmap_cubical_complex.cpp | 85 +++ .../include/gudhi/Bitmap_cubical_complex.h | 706 +++++++++++++++++++++ .../include/gudhi/Bitmap_cubical_complex_base.h | 577 +++++++++++++++++ src/Bitmap_cubical_complex/include/gudhi/counter.h | 136 ++++ src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 623 ++++++++++++++++++ src/Bitmap_cubical_complex/test/CMakeLists.txt | 25 + 8 files changed, 2233 insertions(+) create mode 100644 src/Bitmap_cubical_complex/example/Bitmap_cubical_complex.cpp create mode 100644 src/Bitmap_cubical_complex/example/CMakeLists.txt create mode 100644 src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp create mode 100644 src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/counter.h create mode 100644 src/Bitmap_cubical_complex/test/Bitmap_test.cpp create mode 100644 src/Bitmap_cubical_complex/test/CMakeLists.txt (limited to 'src/Bitmap_cubical_complex') 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; +} diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt new file mode 100644 index 00000000..05ef1319 --- /dev/null +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.6) +project(GUDHISimplexTreeFromFile) + +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_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) + diff --git a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp new file mode 100644 index 00000000..de9d96e0 --- /dev/null +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -0,0 +1,85 @@ +/* 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 "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 +#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 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); //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 new file mode 100644 index 00000000..61ae8105 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -0,0 +1,706 @@ +/* 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 + +//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) { + 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 -- 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 + + /** + * 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::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) { + 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) { + 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) { + 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->keyAssociatedToSimplex[ 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->simplexAssociatedToKey[ 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->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) { + 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) { + 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->boundaryElements.clear(); + this->boundaryElementsinsert(this->boundaryElements.end(), rhs.boundaryElements.begin(), rhs.boundaryElements.end()); + } + + bool operator==(const Boundary_simplex_iterator& rhs) { + if (globalDbg) { + 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) { + cerr << "bool operator != \n"; + } + return !(*this == rhs); + } + + Simplex_handle operator*() { + if (globalDbg) { + 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) { + 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.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) { + 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->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) { + 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->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) { + 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 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) { + 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; + 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) { + 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; + int dimension; + }; + + /** + * Function needed for compatibility with Gudhi. Not useful for other purposes. + **/ + Skeleton_simplex_range skeleton_simplex_range(int dimension) { + if (globalDbg) { + 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) { + cerr << i << " -> " << this->simplexAssociatedToKey[i] << 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; + std::vector< size_t > elementsOrderedAccordingToFiltration; //needed by Filtration_simplex_iterator. If this iterator is not used, this field is not initialized. +}; //Bitmap_cubical_complex + +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) { + 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) { + 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 -- 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::vector< size_t > elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap(this->data.size()); + for (size_t i = 0; i != dataOfElementsFromBitmap.size(); ++i) { + elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap[i] = dataOfElementsFromBitmap[i].first; + } + this->elementsOrderedAccordingToFiltration = elementsOfBitmapOrderedAccordingToFiltrationThenAccordingToDimensionThenAccordingToPositionInBitmap; +} + + +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// +//****************************************************************************************************************// + +#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 new file mode 100644 index 00000000..26c97872 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h @@ -0,0 +1,577 @@ +/* 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 + +#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 + * 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 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_) { + 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) { + 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 +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) { + 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()) { + 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." << 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; + ifstream inFiltration, inIds; + inFiltration.open(perseusStyleFile_); + unsigned dimensionOfData; + inFiltration >> dimensionOfData; + + if (dbg) { + cerr << "dimensionOfData : " << dimensionOfData << 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) { + cerr << "sizeInThisDimension : " << sizeInThisDimension << 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.computeIndexInBitmap() << " and dimension: " << this->get_dimension_of_a_cell(it.computeIndexInBitmap()) << " 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_) { + 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) { + cerr << "dimensionsInWhichCellHasNonzeroLength : \n"; + for (size_t i = 0; i != dimensionsInWhichCellHasNonzeroLength.size(); ++i) { + cerr << dimensionsInWhichCellHasNonzeroLength[i] << 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) 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; + } + 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) { + cerr << "dimensionsInWhichCellHasZeroLength : \n"; + for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { + cerr << dimensionsInWhichCellHasZeroLength[i] << endl; + } + cerr << "\n counter : " << endl; + for (size_t i = 0; i != counter.size(); ++i) { + cerr << counter[i] << endl; + } + getchar(); + } + + std::vector< size_t > coboundaryElements; + if (dimensionsInWhichCellHasZeroLength.size() == 0)return coboundaryElements; + for (size_t i = 0; i != dimensionsInWhichCellHasZeroLength.size(); ++i) { + if (bdg) { + cerr << "Dimension : " << i << 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"; + } + 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"; + } + } + + + if ((cell_ > multipliers[dimensionsInWhichCellHasZeroLength[i]]) && (counter[dimensionsInWhichCellHasZeroLength[i]] != 0)) + //if ( counter[dimensionsInWhichCellHasZeroLength[i]] != 0 ) + { + if (bdg)cerr << "Subtracting : " << cell_ - multipliers[dimensionsInWhichCellHasZeroLength[i]] << 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)cerr << "Adding : " << cell_ + multipliers[dimensionsInWhichCellHasZeroLength[i]] << endl; + } + } + return coboundaryElements; +} + +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; + 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)getchar(); + + if (position % 2 == 1) { + if (dbg)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) { + cerr << "indicesToConsider in this iteration \n"; + for (size_t i = 0; i != indicesToConsider.size(); ++i) { + 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) { + cerr << " position : " << position << endl; + cerr << c << endl; + getchar(); + } + + c.increment(); + } + + return result; +} + +#endif // BITMAP_CUBICAL_COMPLEX_BASE_H_ diff --git a/src/Bitmap_cubical_complex/include/gudhi/counter.h b/src/Bitmap_cubical_complex/include/gudhi/counter.h new file mode 100644 index 00000000..9df819b2 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/counter.h @@ -0,0 +1,136 @@ +/* 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 + +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. + **/ + 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< 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) { + //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< int > begin; + std::vector< int > end; + std::vector< int > current; +}; + +#endif // COUNTER_H_ diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp new file mode 100644 index 00000000..1c204bae --- /dev/null +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -0,0 +1,623 @@ +#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; + } +} diff --git a/src/Bitmap_cubical_complex/test/CMakeLists.txt b/src/Bitmap_cubical_complex/test/CMakeLists.txt new file mode 100644 index 00000000..97c374e6 --- /dev/null +++ b/src/Bitmap_cubical_complex/test/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 2.6) +project(GUDHIBitmapCCUT) + +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pg") +endif() + +add_executable ( BitmapCCUT Bitmap_test.cpp ) +target_link_libraries(BitmapCCUT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) + +# Unitary tests +add_test(NAME BitmapCCUT + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/BitmapCCUT + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/BitmapCCUT.xml --log_level=test_suite --report_level=no) + -- 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') 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') 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') 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 f0ca2ba2080c8f2b01a7cd459560980dfcb964f8 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 11 Dec 2015 12:44:20 +0000 Subject: Pictures in png format git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@943 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 470f82a103e17ffbda2b784fa829e5b0b11458e6 --- .../doc/Gudhi_Cubical_Complex_doc.h | 1 + src/Bitmap_cubical_complex/doc/bitmapAllCubes.png | Bin 0 -> 38944 bytes src/Bitmap_cubical_complex/doc/exampleBitmap.png | Bin 0 -> 9594 bytes 3 files changed, 1 insertion(+) create mode 100644 src/Bitmap_cubical_complex/doc/bitmapAllCubes.png create mode 100644 src/Bitmap_cubical_complex/doc/exampleBitmap.png (limited to 'src/Bitmap_cubical_complex') 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 4acf2b3a..6e821ce4 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -102,5 +102,6 @@ namespace Cubical_complex *\end{verbatim} * * +*@}//end of the group } } diff --git a/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png new file mode 100644 index 00000000..77167b13 Binary files /dev/null and b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.png differ diff --git a/src/Bitmap_cubical_complex/doc/exampleBitmap.png b/src/Bitmap_cubical_complex/doc/exampleBitmap.png new file mode 100644 index 00000000..f8207473 Binary files /dev/null and b/src/Bitmap_cubical_complex/doc/exampleBitmap.png differ -- cgit v1.2.3 From fd41fbbb321b36c143129b5a311e015bf7c44a6f Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 11 Dec 2015 13:04:06 +0000 Subject: Removed pdf to use png Biblio issue git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@944 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 68e93aa53ebadcde4b44eec881b72080e6ceaa70 --- biblio/bibliography.bib | 27 +++++++ .../doc/Gudhi_Cubical_Complex_doc.h | 89 ++++++++++----------- src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf | Bin 13940 -> 0 bytes src/Bitmap_cubical_complex/doc/exampleBitmap.pdf | Bin 11122 -> 0 bytes src/Doxyfile | 3 +- 5 files changed, 71 insertions(+), 48 deletions(-) delete mode 100644 src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf delete mode 100644 src/Bitmap_cubical_complex/doc/exampleBitmap.pdf (limited to 'src/Bitmap_cubical_complex') diff --git a/biblio/bibliography.bib b/biblio/bibliography.bib index 3fd1c10a..9fc01a5d 100644 --- a/biblio/bibliography.bib +++ b/biblio/bibliography.bib @@ -927,3 +927,30 @@ misc{jplex_cite, year = "2009", note = "http://comptop.stanford.edu/programs/jplex/" } + +@book{kaczynski2004computational, + title={Computational Homology}, + author={Kaczynski, T. and Mischaikow, K. and Mrozek, M.}, + isbn={9780387408538}, + lccn={03061109}, + series={Applied Mathematical Sciences}, + url={https://books.google.fr/books?id=AShKtpi3GecC}, + year={2004}, + publisher={Springer New York} +} + +@ARTICLE{peikert2012topological, +year={2012}, +isbn={978-3-642-23174-2}, +booktitle={Topological Methods in Data Analysis and Visualization II}, +series={Mathematics and Visualization}, +editor={Peikert, Ronald and Hauser, Helwig and Carr, Hamish and Fuchs, Raphael}, +doi={10.1007/978-3-642-23175-9_7}, +title={Efficient Computation of Persistent Homology for Cubical Data}, +url={http://dx.doi.org/10.1007/978-3-642-23175-9_7}, +publisher={Springer Berlin Heidelberg}, +author={Wagner, Hubert and Chen, Chao and Vucini, Erald}, +pages={91-106}, +language={English} +} + 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 6e821ce4..1a6310fb 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -38,70 +38,65 @@ namespace Cubical_complex *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$). +* 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-degenerated, while the second one is \a degenerated 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 degenerated 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 (degenerated or not) in the product. A dimension of a cube \f$C=I_1 \times ... \times I_n\f$ is the +*number of non degenerated 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 a book:\\ -*Computational homology, by Tomasz Kaczynski, Konstantin Mischaikow, and Marion Mrozek, Appl. Math. Sci., vol. 157, Springer-Verlag, New York, 2004 +*For further details and theory of cubical complexes, please consult \cite kaczynski2004computational . * -*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) +*as well as the following paper \cite peikert2012topological . * -*\section{Data structure.} +*\section datastructure 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}$. +*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.pdf" "Cubical complex in $\mathbb{R}^2". +*\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 $\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 +*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{Input Format.} +*\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 \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. +*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. * -*\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." +*\image html "exampleBitmap.png" "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} -* -* +*\verbatim +2 +3 +3 +1 +2 +3 +8 +20 +4 +7 +6 +5 +\endverbatim + +*/ +/** @} */ // end defgroup cubical_complex + *@}//end of the group } } diff --git a/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf b/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf deleted file mode 100644 index 694105e4..00000000 Binary files a/src/Bitmap_cubical_complex/doc/bitmapAllCubes.pdf and /dev/null differ diff --git a/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf b/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf deleted file mode 100644 index ef930c0c..00000000 Binary files a/src/Bitmap_cubical_complex/doc/exampleBitmap.pdf and /dev/null differ diff --git a/src/Doxyfile b/src/Doxyfile index faa0d3fe..7a21c254 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -834,7 +834,8 @@ EXAMPLE_RECURSIVE = NO IMAGE_PATH = doc/Skeleton_blocker/ \ doc/common/ \ - doc/Contraction/ + doc/Contraction/ \ + doc/Bitmap_cubical_complex # The INPUT_FILTER tag can be used to specify a program that doxygen should -- cgit v1.2.3 From 5eae3bbe5c06a3b601b885ea9f2561743f4aeb1a Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 22 Dec 2015 07:57:35 +0000 Subject: Changes according to Marc's comments from 18 December. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@947 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3afdd0423f3b36d8103360ef11fbb5f1c9a348a5 --- .../example/Random_bitmap_cubical_complex.cpp | 2 +- .../include/gudhi/Bitmap_cubical_complex.h | 90 +++--------- .../include/gudhi/Bitmap_cubical_complex/counter.h | 6 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 163 ++++++++------------- 4 files changed, 93 insertions(+), 168 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 60cfc113..36c22344 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -85,7 +85,7 @@ The program will create random cubical complex of that sizes and compute persist stringstream ss; ss << "randomComplex_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 b8887e71..c082caba 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -45,7 +45,6 @@ public: //*********************************************// //Typedefs and typenames //*********************************************// - friend class Simplex_handle; typedef size_t Simplex_key; typedef T Filtration_value; typedef Simplex_key Simplex_handle; @@ -83,7 +82,7 @@ public: * 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( const std::vector& dimensions , const std::vector& top_dimensional_cells ): Bitmap_cubical_complex_base(dimensions,top_dimensional_cells), key_associated_to_simplex(this->total_number_of_cells+1) { @@ -114,7 +113,7 @@ public: static Simplex_handle null_simplex() { if ( globalDbg ){cerr << "Simplex_handle null_simplex()\n";} - return std::numeric_limits::max(); + return std::numeric_limits::max(); } @@ -129,22 +128,22 @@ public: /** * Return dimension of a cell pointed by the Simplex_handle. **/ - inline unsigned dimension(const Simplex_handle& sh)const + 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 ); + 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. **/ - T filtration(const Simplex_handle& sh) + T filtration(Simplex_handle sh) { if ( globalDbg ){cerr << "T 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(); + if ( sh != std::numeric_limits::max() ) return this->data[sh]; + return std::numeric_limits::max(); } /** @@ -153,16 +152,16 @@ public: static Simplex_key null_key() { if ( globalDbg ){cerr << "Simplex_key null_key()\n";} - return std::numeric_limits::max(); + return std::numeric_limits::max(); } /** * Return the key of a cube pointed by the Simplex_handle. **/ - Simplex_key key(const Simplex_handle& sh)const + Simplex_key key(Simplex_handle sh)const { if ( globalDbg ){cerr << "Simplex_key key(const Simplex_handle& sh)\n";} - if ( sh != std::numeric_limits::max() ) + if ( sh != std::numeric_limits::max() ) { return this->key_associated_to_simplex[sh]; } @@ -175,7 +174,7 @@ public: Simplex_handle simplex(Simplex_key key) { if ( globalDbg ){cerr << "Simplex_handle simplex(Simplex_key key)\n";} - if ( key != std::numeric_limits::max() ) + if ( key != std::numeric_limits::max() ) { return this->simplex_associated_to_key[ key ]; } @@ -185,23 +184,10 @@ public: /** * Assign key to a cube pointed by the Simplex_handle **/ - void assign_key(Simplex_handle& sh, Simplex_key key) + 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;//TODO FAKE!!! CHEATING!!! - - - - - + if ( key == std::numeric_limits::max() ) return; this->key_associated_to_simplex[sh] = key; this->simplex_associated_to_key[key] = sh; } @@ -222,33 +208,9 @@ if ( key == std::numeric_limits::max() ) return;//TODO FAKE!!! CHEATING!!! /** * 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: - 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(); + typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; + typedef typename std::vector< Simplex_handle > Boundary_simplex_range; - } - 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; - }; /** @@ -341,13 +303,10 @@ if ( key == std::numeric_limits::max() ) return;//TODO FAKE!!! CHEATING!!! /** * 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,this); + **/ + Boundary_simplex_range boundary_simplex_range(Simplex_handle sh) + { + return this->get_boundary_of_a_cell(sh); } /** @@ -513,13 +472,12 @@ void Bitmap_cubical_complex::initialize_simplex_associated_to_key() if ( globalDbg ) { 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() , + } + 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) ); - this->simplex_associated_to_key = data_of_elements_from_bitmap; } 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 index 3a17b4a0..c13d96e1 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h @@ -51,7 +51,7 @@ 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(const std::vector& 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 ) @@ -67,7 +67,7 @@ public: * 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) + counter(const std::vector< unsigned >& beginn , const 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"; @@ -112,7 +112,7 @@ public: * 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 > find_opposite( const std::vector< bool >& directionsForPeriodicBCond ) { std::vector< unsigned > result; for ( size_t i = 0 ; i != this->current.size() ; ++i ) 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 4e63b9c3..fdc8511c 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 @@ -44,19 +44,19 @@ namespace Cubical_complex /** - * This is a class implementing a basic bitmap data structure to store cubical complexes. + * 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 + * 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). + * 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). + * 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 + * 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. */ @@ -65,49 +65,49 @@ 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 + * 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 ); + 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 + * 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) + * 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 ); + Bitmap_cubical_complex_base( const 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 + * 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 + * 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 + * 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 + * 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, + * 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 + * 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 + * 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; @@ -118,11 +118,11 @@ public: /** - * Typical input used to construct a baseBitmap class is a filtration given at the top dimensional cells. + * 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 + * 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 + * 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. @@ -149,7 +149,7 @@ public: //ITERATORS /** - * Iterator through all cells in the complex (in order they appear in the structure -- i.e. + * 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; @@ -174,7 +174,7 @@ public: } /** - * Iterator through top dimensional cells of the complex. The cells appear in order they are stored + * 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 > @@ -184,7 +184,7 @@ public: { 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: @@ -298,7 +298,7 @@ protected: std::vector multipliers; std::vector data; size_t total_number_of_cells; - void set_up_containers( std::vector& sizes ) + void set_up_containers( const std::vector& sizes ) { unsigned multiplier = 1; for ( size_t i = 0 ; i != sizes.size() ; ++i ) @@ -315,7 +315,7 @@ protected: this->data = data; } - size_t compute_position_in_bitmap( std::vector< unsigned >& counter ) + 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 ) @@ -337,9 +337,9 @@ protected: return counter; } - std::vector< size_t > + std::vector< size_t > generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions - ( std::vector< bool >& directions_for_periodic_b_cond ); + ( const std::vector< bool >& directions_for_periodic_b_cond ); }; @@ -348,7 +348,7 @@ protected: template ostream& operator << ( ostream & out , const Bitmap_cubical_complex_base& b ) { - for ( typename Bitmap_cubical_complex_base::all_cells_const_iterator + 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 << " "; @@ -359,14 +359,14 @@ ostream& operator << ( ostream & out , const Bitmap_cubical_complex_base& b ) template Bitmap_cubical_complex_base::Bitmap_cubical_complex_base -( std::vector& sizes ) +( const 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 ) +( const std::vector& sizes_in_following_directions , const std::vector& top_dimensional_cells ) { this->set_up_containers( sizes_in_following_directions ); @@ -377,7 +377,7 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base } if ( number_of_top_dimensional_elements != top_dimensional_cells.size() ) { - cerr << + cerr << "Error in constructor\ Bitmap_cubical_complex_base\ ( std::vector sizes_in_following_directions , std::vector top_dimensional_cells ).\ @@ -432,10 +432,10 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus 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()) + 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; @@ -449,51 +449,18 @@ 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 { - 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; + std::vector< size_t > boundary_elements; 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++; + { + boundary_elements.push_back( cell - multipliers[ i-1 ] ); + boundary_elements.push_back( cell + multipliers[ i-1 ] ); } 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( 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[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; - 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; } @@ -504,7 +471,7 @@ 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. + //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; @@ -547,20 +514,20 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( cerr << "Dimension : " << i << endl; if (counter[dimensions_in_which_cell_has_zero_length[i]] == 0) { - cerr << "In dimension : " << i + 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]] - == + 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 + 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]]) + 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 ) { @@ -570,13 +537,13 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( } 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 ( + (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]] != + //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]] ); @@ -629,12 +596,12 @@ 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 + //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 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 ) @@ -699,7 +666,7 @@ bool compareFirstElementsOfTuples( const std::pair< std::pair< T , size_t > , ch 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 ) +( const std::vector< bool >& directions_for_periodic_b_cond ) { bool dbg = false; if ( this->sizes.size() != directions_for_periodic_b_cond.size() ) @@ -758,4 +725,4 @@ generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions } -} \ No newline at end of file +} -- cgit v1.2.3 From 1884df27964e344ac0004964c633ba01d4a6ae29 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Sun, 27 Dec 2015 09:25:07 +0000 Subject: COrrestions suggested by Marc just before Chrismas. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@948 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b5391c6584d8042646fea5ca17e250fcfc3dd85f --- .../include/gudhi/Bitmap_cubical_complex.h | 6 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 121 +++++++++------------ 2 files changed, 55 insertions(+), 72 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 c082caba..b324d272 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -278,7 +278,8 @@ public: //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 const_iterator; + typedef Filtration_simplex_iterator iterator; Filtration_simplex_range(Bitmap_cubical_complex* b):b(b){}; Filtration_simplex_iterator begin() { @@ -430,7 +431,8 @@ public: //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 const_iterator; + typedef Skeleton_simplex_iterator iterator; Skeleton_simplex_range(Bitmap_cubical_complex* b , unsigned dimension):b(b),dimension(dimension){}; Skeleton_simplex_iterator begin() { 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 fdc8511c..54d60325 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 @@ -183,7 +183,7 @@ 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 ); + //std::fill( this->counter.begin() , this->counter.end() , 0 ); } Top_dimensional_cells_iterator operator++() { @@ -327,7 +327,8 @@ 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 ) { counter.push_back(cell/this->multipliers[dim-1]); @@ -380,11 +381,11 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base cerr << "Error in constructor\ Bitmap_cubical_complex_base\ - ( std::vector sizes_in_following_directions , std::vector top_dimensional_cells ).\ + ( 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 )\ + 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."); } @@ -411,7 +412,8 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;} - std::vector sizes; + std::vector sizes; + sizes.reserve( dimensionOfData ); for ( size_t i = 0 ; i != dimensionOfData ; ++i ) { unsigned size_in_this_dimension; @@ -449,17 +451,21 @@ 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; + 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/multipliers[i-1]; + unsigned position = cell1/this->multipliers[i-1]; if ( position%2 == 1 ) { - boundary_elements.push_back( cell - multipliers[ i-1 ] ); - boundary_elements.push_back( cell + multipliers[ i-1 ] ); + boundary_elements.push_back( cell - this->multipliers[ i-1 ] ); + boundary_elements.push_back( cell + this->multipliers[ i-1 ] ); } - cell1 = cell1%multipliers[i-1]; + cell1 = cell1%this->multipliers[i-1]; } return boundary_elements; } @@ -470,84 +476,48 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( si 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; + std::vector< unsigned > dimensions_in_which_cell_has_zero_length; + + //Speed traded of for memory. Check if it is better in practice. + dimensions_in_which_cell_has_zero_length.reserve( this->dimension()*2 ); + unsigned dimension = 0; size_t cell1 = cell; for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) { - unsigned position = cell1/multipliers[i-1]; + unsigned position = cell1/this->multipliers[i-1]; if ( position%2 == 0 ) { dimensions_in_which_cell_has_zero_length.push_back(i-1); dimension++; } - cell1 = cell1%multipliers[i-1]; + cell1 = cell1%this->multipliers[i-1]; } std::vector counter = this->compute_counter_for_given_cell( cell ); - //reverse(counter.begin() , counter.end()); + std::vector< size_t > coboundary_elements; + + //Speed traded of for memory. Check if it is better in practice. + coboundary_elements.reserve ( dimensions_in_which_cell_has_zero_length.size()*2 ); - 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]]) + if ( (cell > this->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]] ); + coboundary_elements.push_back( cell - this->multipliers[dimensions_in_which_cell_has_zero_length[i]] ); } if ( - (cell + multipliers[dimensions_in_which_cell_has_zero_length[i]] < this->data.size()) && + (cell + this->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; + coboundary_elements.push_back( cell + this->multipliers[dimensions_in_which_cell_has_zero_length[i]] ); } } return coboundary_elements; @@ -566,12 +536,12 @@ unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell( size_t cell )c unsigned dimension = 0; for ( size_t i = this->multipliers.size() ; i != 0 ; --i ) { - unsigned position = cell/multipliers[i-1]; + 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]; } return dimension; } @@ -599,8 +569,15 @@ 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 ); - - 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. typename Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); @@ -672,12 +649,17 @@ generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions 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]; + std::vector sizes; + sizes.reserve( this->sizes.size() ); + for ( size_t i = 0 ; i != this->sizes.size() ; ++i ) + { + sizes.push_back(2*this->sizes[i]); + } counter c( sizes ); - std::vector< size_t > result; + std::vector< size_t > result; + result.reserve( this->data.size() ); for ( size_t i = 0 ; i != this->data.size() ; ++i ) { @@ -685,7 +667,6 @@ generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions if ( !c.isFinal() ) { position = i; - //result.push_back( i ); } else { -- 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') 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') 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 12226486b5bf3f1d867f46aed5dc6d2c9727a03c Mon Sep 17 00:00:00 2001 From: pdlotko Date: Wed, 13 Jan 2016 08:41:26 +0000 Subject: Added tests for periodic boubnadry oconditions bitmap. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@962 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 49f059cdf9e0c8e20ff727564da13be14ebc2c04 --- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 270 +++++++++++++++++++++++- 1 file changed, 259 insertions(+), 11 deletions(-) (limited to 'src/Bitmap_cubical_complex') diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index 183b856a..4235761f 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(check_dimension) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); BOOST_CHECK(increasing.dimension() == 2); } @@ -88,18 +88,18 @@ BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - Bitmap_cubical_complex hole(dimensions, oneDimensionalCycle); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > hole(dimensions, oneDimensionalCycle); int i = 0; - for (Bitmap_cubical_complex::Top_dimensional_cells_iterator + for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::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 + for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator it = hole.top_dimensional_cells_begin(); it != hole.top_dimensional_cells_end(); ++it) { BOOST_CHECK(*it == expectedFiltrationValues1[i]); ++i; @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > 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) { @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector coboundaryElements; @@ -449,7 +449,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector dim; dim.push_back(0); @@ -523,7 +523,7 @@ BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { dimensions.push_back(3); dimensions.push_back(3); - Bitmap_cubical_complex increasing(dimensions, increasingFiltrationOfTopDimensionalCells); + Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); std::vector< unsigned > dim; dim.push_back(0); @@ -628,11 +628,259 @@ BOOST_AUTO_TEST_CASE(Filtration_simplex_iterator_test) { fil.push_back(9); - Bitmap_cubical_complex::Filtration_simplex_range range = increasing.filtration_simplex_range(); + Bitmap_cubical_complex< Bitmap_cubical_complex_base >::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) { + for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::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 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 ); + + for (size_t i = 0; i != cmplx.size_of_bitmap(); ++i) { + std::vector< size_t > bd = cmplx.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(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 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_of_bitmap(); ++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_of_bitmap(); ++i) + { + BOOST_CHECK( filtration[i] == cmplx.get_cell_data(i) ); + } +} -- cgit v1.2.3 From 35143d2a24e7a601a4629a7cfe43ea6b8ea35f1a Mon Sep 17 00:00:00 2001 From: pdlotko Date: Wed, 13 Jan 2016 10:14:41 +0000 Subject: Adding documentation of the class. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@963 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6eec3b7216880475ed667660275c2314bf0feb0c --- .../include/gudhi/Bitmap_cubical_complex.h | 43 ++- .../include/gudhi/Bitmap_cubical_complex_base.h | 226 +++++++--------- ...cal_complex_periodic_boundary_conditions_base.h | 298 +++++++++++++++++++++ 3 files changed, 427 insertions(+), 140 deletions(-) create mode 100644 src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h (limited to 'src/Bitmap_cubical_complex') 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 b324d272..63edcadd 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -23,7 +23,8 @@ #pragma once #include -#include "Bitmap_cubical_complex_base.h" +#include "Bitmap_cubical_complex_base.h" +#include "Bitmap_cubical_complex_periodic_boundary_conditions_base.h" @@ -38,15 +39,15 @@ const bool globalDbg = false; template class is_before_in_filtration; -template -class Bitmap_cubical_complex : public Bitmap_cubical_complex_base +template +class Bitmap_cubical_complex : public T { public: //*********************************************// //Typedefs and typenames //*********************************************// typedef size_t Simplex_key; - typedef T Filtration_value; + typedef typename T::filtration_type Filtration_value; typedef Simplex_key Simplex_handle; @@ -63,7 +64,7 @@ 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) + T(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 ) @@ -82,8 +83,28 @@ public: * 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 ): - Bitmap_cubical_complex_base(dimensions,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 ) @@ -138,9 +159,9 @@ public: /** * Return the filtration of a cell pointed by the Simplex_handle. **/ - T filtration(Simplex_handle sh) + typename T::filtration_type filtration(Simplex_handle sh) { - if ( globalDbg ){cerr << "T filtration(const Simplex_handle& sh)\n";} + 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(); @@ -493,8 +514,8 @@ public: 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. - T fil1 = CC_->data[sh1]; - T fil2 = CC_->data[sh2]; + typename T::filtration_type fil1 = CC_->data[sh1]; + typename T::filtration_type fil2 = CC_->data[sh2]; if ( fil1 != fil2 ) { return fil1 < fil2; 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 54d60325..600f250d 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 @@ -63,7 +63,12 @@ namespace Cubical_complex template class Bitmap_cubical_complex_base { -public: +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 @@ -93,7 +98,7 @@ public: * 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; + 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 @@ -286,7 +291,12 @@ public: //****************************************************************************************************************// //****************************************************************************************************************// //****************************************************************************************************************// - + + +inline size_t number_cells()const +{ + return this->total_number_of_cells; +} //****************************************************************************************************************// //****************************************************************************************************************// @@ -305,14 +315,10 @@ protected: { 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->data = std::vector(multiplier, std::numeric_limits::max()); this->total_number_of_cells = multiplier; - this->data = data; } size_t compute_position_in_bitmap( const std::vector< unsigned >& counter ) @@ -336,11 +342,12 @@ protected: } std::reverse( counter.begin() , counter.end() ); return counter; - } - - std::vector< size_t > - generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions - ( const std::vector< bool >& directions_for_periodic_b_cond ); + } + 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 ); }; @@ -364,11 +371,10 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base { this->set_up_containers( sizes ); } - -template -Bitmap_cubical_complex_base::Bitmap_cubical_complex_base -( 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; @@ -397,13 +403,19 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base (*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 char* perseus_style_file ) +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 ); @@ -418,7 +430,7 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus { unsigned size_in_this_dimension; inFiltration >> size_in_this_dimension; - size_in_this_dimension = abs(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;} } @@ -427,7 +439,6 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus 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; @@ -444,7 +455,37 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus ++it; } inFiltration.close(); - this->impose_lower_star_filtration(); + 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 ); +} + +template +Bitmap_cubical_complex_base::Bitmap_cubical_complex_base( const char* perseus_style_file ) +{ + this->read_perseus_style_file( perseus_style_file ); } @@ -468,60 +509,39 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_boundary_of_a_cell( si 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 { - //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; - - //Speed traded of for memory. Check if it is better in practice. - dimensions_in_which_cell_has_zero_length.reserve( this->dimension()*2 ); - - unsigned dimension = 0; + 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 ) { - dimensions_in_which_cell_has_zero_length.push_back(i-1); - dimension++; + 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]; } - - std::vector counter = this->compute_counter_for_given_cell( cell ); - std::vector< size_t > coboundary_elements; + return coboundary_elements; +} - //Speed traded of for memory. Check if it is better in practice. - coboundary_elements.reserve ( dimensions_in_which_cell_has_zero_length.size()*2 ); - 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 ( (cell > this->multipliers[dimensions_in_which_cell_has_zero_length[i]]) - && (counter[dimensions_in_which_cell_has_zero_length[i]] != 0) ) - { - coboundary_elements.push_back( cell - this->multipliers[dimensions_in_which_cell_has_zero_length[i]] ); - } - if ( - (cell + this->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]]) - ) - { - coboundary_elements.push_back( cell + this->multipliers[dimensions_in_which_cell_has_zero_length[i]] ); - } - } - return coboundary_elements; -} @@ -555,7 +575,7 @@ unsigned Bitmap_cubical_complex_base::get_dimension_of_a_cell( size_t cell )c } template -T& Bitmap_cubical_complex_base::get_cell_data( size_t cell ) +inline T& Bitmap_cubical_complex_base::get_cell_data( size_t cell ) { return this->data[cell]; } @@ -602,10 +622,21 @@ 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 ( this->data[ bd[boundaryIt] ] > this->data[ indices_to_consider[i] ] ) { - 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 ) { @@ -640,69 +671,6 @@ bool compareFirstElementsOfTuples( const std::pair< std::pair< T , size_t > , ch -template -std::vector< size_t > Bitmap_cubical_complex_base:: -generate_vector_of_shifts_for_bitmaps_with_periodic_boundary_conditions -( const 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; - sizes.reserve( this->sizes.size() ); - for ( size_t i = 0 ; i != this->sizes.size() ; ++i ) - { - sizes.push_back(2*this->sizes[i]); - } - - counter c( sizes ); - - std::vector< size_t > result; - result.reserve( this->data.size() ); - - for ( size_t i = 0 ; i != this->data.size() ; ++i ) - { - size_t position; - if ( !c.isFinal() ) - { - position = 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; -} } 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 new file mode 100644 index 00000000..28911ea8 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h @@ -0,0 +1,298 @@ +#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 + +template +class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base +{ +public: + //constructors that take an extra parameter: + Bitmap_cubical_complex_periodic_boundary_conditions_base(){}; + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseusStyleFile ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); + + //overwritten methods co compute boundary and coboundary + virtual std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; + std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; + //inline unsigned get_dimension_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( std::vector sizes ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells ); + void construct_complex_based_on_top_dimensional_cells( std::vector dimensions , std::vector topDimensionalCells , 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( std::vector dimensions , std::vector topDimensionalCells , 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + { + *it = topDimensionalCells[i]; + ++i; + } + this->impose_lower_star_filtration(); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , 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_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; + } + *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); + } + fread( slice,4,w*h*d,fp ); + fclose(fp); + 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); + + std::vector< bool > directions; + directions.push_back( true ); + directions.push_back( true ); + directions.push_back( true ); + Bitmap_cubical_complex_periodic_boundary_conditions_base b( sizes, data, directions ); + *this = b; + */ +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( 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( std::vector dimensions , 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( std::vector dimensions , std::vector topDimensionalCells , 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 -- cgit v1.2.3 From 7fe2c44c56e4fbd176131f31bc4338932f7a9d32 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 5 Feb 2016 12:24:49 +0000 Subject: Over here I have linkd phat with Gudhi. So far it is done only for cubical complexes, but since I am ONLY using Filtration_simplex_iterator, there should be no problem to have it run with any other class we have. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1004 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ddb3e2c5fa0c2a816e7435c57d32c0644f8163d2 --- ...ubical_complex_periodic_boundary_conditions.cpp | 159 +++++++++++---------- src/Bitmap_cubical_complex/example/CMakeLists.txt | 2 + .../example/Compute_persistence_with_phat.cpp | 60 ++++++++ 3 files changed, 146 insertions(+), 75 deletions(-) create mode 100644 src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp (limited to 'src/Bitmap_cubical_complex') 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 3d80c96d..df01240b 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,75 +1,84 @@ - /* 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_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] ); - - - // 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(); - - 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 ) +{ + 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; +} diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index 26796e9d..fbd1b28b 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -13,3 +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 diff --git a/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp b/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp new file mode 100644 index 00000000..fe9be33e --- /dev/null +++ b/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp @@ -0,0 +1,60 @@ + + /* 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 +#include + +using namespace Gudhi; +using namespace Gudhi::Cubical_complex; + +//standard stuff +#include +#include +#include + +using namespace std; + + +int main( int argc , char** argv ) +{ + 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] ); + cerr << "Cubical complex created \n"; + + + Compute_persistence_with_phat< Bitmap_cubical_complex< Bitmap_cubical_complex_base > , double > phat(&b); + phat::persistence_pairs pairs = phat.compute_persistence_pairs_dualized_chunk_reduction(); + std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > persistence = phat.get_the_intervals( pairs ); + writeBettiNumbersAndPersistenceIntervalsToFile( "phat_persistence" , persistence ); + + return 0; +} -- cgit v1.2.3 From 3be6acc35255b52a60a254fa101aec5b11173b6d Mon Sep 17 00:00:00 2001 From: pdlotko Date: Mon, 8 Feb 2016 15:10:49 +0000 Subject: Adding changes suggested by Marc. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1007 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2462c084e3269a3d44813619f44852d3c8d6e163 --- src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Bitmap_cubical_complex') diff --git a/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp b/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp index fe9be33e..f552a094 100644 --- a/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp +++ b/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp @@ -52,7 +52,7 @@ int main( int argc , char** argv ) Compute_persistence_with_phat< Bitmap_cubical_complex< Bitmap_cubical_complex_base > , double > phat(&b); - phat::persistence_pairs pairs = phat.compute_persistence_pairs_dualized_chunk_reduction(); + phat::persistence_pairs pairs = phat.compute_persistence_pairs_standard_reduction(); std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > persistence = phat.get_the_intervals( pairs ); writeBettiNumbersAndPersistenceIntervalsToFile( "phat_persistence" , persistence ); -- cgit v1.2.3 From 84399987baac2817e58bf9f5e18ded6aa6893b0f Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 9 Feb 2016 13:26:47 +0000 Subject: adding missing partsy git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1008 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: f6de1ee4317763b50233f9a7212bdbf6587ee686 --- .../doc/Gudhi_Cubical_Complex_doc.h | 41 +- src/Bitmap_cubical_complex/doc/exampleBitmap.png | Bin 9594 -> 2549 bytes .../include/gudhi/Bitmap_cubical_complex.h | 28 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 114 +++++- ...cal_complex_periodic_boundary_conditions_base.h | 451 +++++++++++---------- .../include/gudhi/Compute_persistence_with_phat.h | 242 +++++++++++ .../gudhi/phat/algorithms/chunk_reduction.h | 240 +++++++++++ .../include/gudhi/phat/algorithms/row_reduction.h | 55 +++ .../gudhi/phat/algorithms/standard_reduction.h | 45 ++ .../gudhi/phat/algorithms/twist_reduction.h | 50 +++ .../include/gudhi/phat/boundary_matrix.h | 336 +++++++++++++++ .../include/gudhi/phat/compute_persistence_pairs.h | 69 ++++ .../include/gudhi/phat/helpers/dualize.h | 63 +++ .../include/gudhi/phat/helpers/misc.h | 74 ++++ .../gudhi/phat/helpers/thread_local_storage.h | 52 +++ .../include/gudhi/phat/persistence_pairs.h | 151 +++++++ .../phat/representations/abstract_pivot_column.h | 158 ++++++++ .../phat/representations/bit_tree_pivot_column.h | 169 ++++++++ .../gudhi/phat/representations/full_pivot_column.h | 81 ++++ .../phat/representations/sparse_pivot_column.h | 62 +++ .../gudhi/phat/representations/vector_list.h | 98 +++++ .../gudhi/phat/representations/vector_set.h | 100 +++++ .../gudhi/phat/representations/vector_vector.h | 93 +++++ src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 12 +- 24 files changed, 2532 insertions(+), 252 deletions(-) create mode 100644 src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h create mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h (limited to 'src/Bitmap_cubical_complex') 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 1a6310fb..c06678a1 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -38,20 +38,18 @@ namespace Cubical_complex *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-degenerated, while the second one is \a degenerated 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 degenerated elementary interval. An elementary cube \f$ C \f$ is a +* 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 -*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 (degenerated or not) in the product. A dimension of a cube \f$C=I_1 \times ... \times I_n\f$ is the -*number of non degenerated 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: +*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 . +*For further details and theory of cubical complexes, please consult \cite kaczynski2004computational as well as the following paper \cite peikert2012topological . * *\section datastructure Data structure. * @@ -73,7 +71,8 @@ namespace Cubical_complex *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. +*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." @@ -84,6 +83,29 @@ namespace Cubical_complex 3 3 1 +4 +6 +8 +20 +4 +7 +6 +5 +\endverbatim + +\section 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 +2 +-3 +3 +1 2 3 8 @@ -94,6 +116,9 @@ namespace Cubical_complex 5 \endverbatim +Indicate that we have imposed periodic boundary conditions in the direction x, but not in the direction y. + + */ /** @} */ // end defgroup cubical_complex diff --git a/src/Bitmap_cubical_complex/doc/exampleBitmap.png b/src/Bitmap_cubical_complex/doc/exampleBitmap.png index f8207473..069c6eb2 100644 Binary files a/src/Bitmap_cubical_complex/doc/exampleBitmap.png and b/src/Bitmap_cubical_complex/doc/exampleBitmap.png differ 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 63edcadd..82ea8672 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -1,4 +1,4 @@ - /* This file is part of the Gudhi Library. The Gudhi library +/* This file is part of the Gudhi Library. The Gudhi library * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * @@ -65,7 +65,8 @@ public: **/ 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 ) { @@ -74,7 +75,8 @@ public: //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(); + 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; } @@ -115,7 +117,8 @@ 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(); - } + } + //*********************************************// //Other 'easy' functions @@ -328,6 +331,15 @@ public: **/ 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); } @@ -500,7 +512,13 @@ void Bitmap_cubical_complex::initialize_simplex_associated_to_key() 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) ); + 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; + } } 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 600f250d..22b703a9 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 @@ -29,7 +29,8 @@ #include #include #include -#include +#include +#include #include "Bitmap_cubical_complex/counter.h" @@ -68,7 +69,9 @@ public: /** *Default constructor **/ - Bitmap_cubical_complex_base(){} + 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 @@ -110,7 +113,7 @@ public: * 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; + 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. @@ -140,7 +143,7 @@ public: /** * Returns number of all cubes in the data structure. **/ - inline unsigned size_of_bitmap()const + inline unsigned size()const { return this->data.size(); } @@ -149,7 +152,19 @@ 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. + **/ + void put_data_toBins( size_t number_of_bins ); + 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 @@ -157,22 +172,41 @@ 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; - all_cells_iterator all_cells_begin()const + typedef typename std::vector< T >::iterator all_cells_iterator; + + /** + * Function returning an iterator to the first cell of the bitmap. + **/ + all_cells_iterator all_cells_begin() { return this->data.begin(); - } + } + + /** + * Function returning an iterator to the last cell of the bitmap. + **/ all_cells_iterator all_cells_end()const { return this->data.end(); } - - typedef typename std::vector< T >::const_iterator all_cells_const_iterator; + /** + * Constant iterator through all cells in the complex (in order they appear in the structure -- i.e. + * in lexicographical order). + **/ + 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 a constant iterator to the last cell of the bitmap. + **/ all_cells_const_iterator all_cells_const_end()const { return this->data.end(); @@ -269,12 +303,20 @@ 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. + **/ Top_dimensional_cells_iterator top_dimensional_cells_begin() { 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. + **/ Top_dimensional_cells_iterator top_dimensional_cells_end() { Top_dimensional_cells_iterator a(*this); @@ -351,6 +393,50 @@ protected: }; +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; +} template @@ -422,7 +508,7 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu unsigned dimensionOfData; inFiltration >> dimensionOfData; - if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;} + if (dbg){cerr << "dimensionOfData : " << dimensionOfData << endl;getchar();} std::vector sizes; sizes.reserve( dimensionOfData ); 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 28911ea8..38c218dc 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 @@ -1,120 +1,120 @@ -#pragma once -#include -#include "Bitmap_cubical_complex_base.h" - +#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 - -template -class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base -{ -public: - //constructors that take an extra parameter: - Bitmap_cubical_complex_periodic_boundary_conditions_base(){}; - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseusStyleFile ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); - - //overwritten methods co compute boundary and coboundary - virtual std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; - std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; - //inline unsigned get_dimension_of_a_cell( size_t cell )const; - -protected: - std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed; +{ + +//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 + +template +class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base +{ +public: + //constructors that take an extra parameter: + Bitmap_cubical_complex_periodic_boundary_conditions_base(){}; + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseusStyleFile ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); + + //overwritten methods co compute boundary and coboundary + virtual std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; + std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; + //inline unsigned get_dimension_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; + + 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( std::vector sizes ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells ); - void construct_complex_based_on_top_dimensional_cells( std::vector dimensions , std::vector topDimensionalCells , 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( std::vector dimensions , std::vector topDimensionalCells , 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) - { - *it = topDimensionalCells[i]; - ++i; - } - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , 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; - + } + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes ); + Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells ); + void construct_complex_based_on_top_dimensional_cells( std::vector dimensions , std::vector topDimensionalCells , 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( std::vector dimensions , std::vector topDimensionalCells , 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + { + *it = topDimensionalCells[i]; + ++i; + } + this->impose_lower_star_filtration(); +} + +template +Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , 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; + 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; + 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 ); - + this->set_up_containers( sizes ); + typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it(*this); it = this->top_dimensional_cells_begin(); while ( !inFiltration.eof() ) { double filtrationLevel; - inFiltration >> filtrationLevel; - if ( inFiltration.eof() )break; + inFiltration >> filtrationLevel; + if ( inFiltration.eof() )break; if ( dbg ) { @@ -128,124 +128,137 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_comp ++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); - } - fread( slice,4,w*h*d,fp ); - fclose(fp); - 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); - - std::vector< bool > directions; - directions.push_back( true ); - directions.push_back( true ); - directions.push_back( true ); - Bitmap_cubical_complex_periodic_boundary_conditions_base b( sizes, data, directions ); - *this = b; - */ -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( 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( std::vector dimensions , 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( std::vector dimensions , std::vector topDimensionalCells , 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;} - + 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_begin() ; it != this->top_dimensional_cells_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( 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( std::vector dimensions , 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( std::vector dimensions , std::vector topDimensionalCells , 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. + 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 ] << " ";} - } + { + //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; -} - + return boundary_elements; +} + template std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_base::get_coboundary_of_a_cell( size_t cell )const { @@ -254,12 +267,12 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_basemultipliers.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. + 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] ) - { + { + 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]) ) { @@ -268,31 +281,31 @@ std::vector< size_t > Bitmap_cubical_complex_periodic_boundary_conditions_basesizes[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] ); - } + } } - } + 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 +} + + + +}//Cubical_complex +}//namespace Gudhi diff --git a/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h b/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h new file mode 100644 index 00000000..9f4ada45 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h @@ -0,0 +1,242 @@ +/* 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 "phat/compute_persistence_pairs.h" +#include "phat/representations/vector_vector.h" +#include "phat/algorithms/standard_reduction.h" +#include "phat/algorithms/chunk_reduction.h" +#include "phat/algorithms/row_reduction.h" +#include "phat/algorithms/twist_reduction.h" + + +namespace Gudhi +{ + + +//the only aim of this class is to have a ability to compute persistence with phat. +template +void writeBettiNumbersAndPersistenceIntervalsToFile( char* prefix , std::pair< std::vector > , std::vector< std::vector< std::pair > > > resutsFromPhat ) +{ + std::ostringstream filenameStr; + filenameStr << prefix << "_bettiNumbers"; + std::string str = filenameStr.str(); + const char* filename = str.c_str(); + ofstream out; + out.open( filename ); + for ( size_t dim = 0 ; dim != resutsFromPhat.first.size() ; ++dim ) + { + out << "Dimension : " << dim << endl; + for ( size_t i = 0 ; i != resutsFromPhat.first[dim].size() ; ++i ) + { + out << resutsFromPhat.first[dim][i] << endl; + } + out << endl; + } + out.close(); + + + cerr << "Write persistence to file \n"; + for ( size_t dim = 0 ; dim != resutsFromPhat.second.size() ; ++dim ) + { + cerr << "resutsFromPhat.second[dim].size() : " << resutsFromPhat.second[dim].size() << endl; + if ( resutsFromPhat.second[dim].size() == 0 )continue; + std::ostringstream filenameStr; + filenameStr << prefix << "_persistence_" << dim; + std::string str = filenameStr.str(); + const char* filename = str.c_str(); + ofstream out1; + out1.open( filename ); + for ( size_t i = 0 ; i != resutsFromPhat.second[dim].size() ; ++i ) + { + out1 << resutsFromPhat.second[dim][i].first << " " << resutsFromPhat.second[dim][i].second << endl; + } + out1.close(); + } +}//writeBettiNumbersAndPersistenceIntervalsToFile + + +template +class Compute_persistence_with_phat +{ +public: + Compute_persistence_with_phat( T* data_structure_ ); + std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > get_the_intervals( phat::persistence_pairs pairs ); + + phat::persistence_pairs compute_persistence_pairs_dualized_chunk_reduction(); + phat::persistence_pairs compute_persistence_pairs_twist_reduction(); + phat::persistence_pairs compute_persistence_pairs_standard_reduction(); + //phat::persistence_pairs compute_persistence_pairs_spectral_sequence_reduction(); +private: + void print_bd_matrix(); + phat::boundary_matrix< phat::vector_vector > boundary_matrix; + T* data_structure; +}; + +template +void Compute_persistence_with_phat::print_bd_matrix() +{ + std::cout << "The boundary matrix has " << this->boundary_matrix.get_num_cols() << " columns: " << std::endl; + for( phat::index col_idx = 0; col_idx < this->boundary_matrix.get_num_cols(); col_idx++ ) { + std::cout << "Colum " << col_idx << " represents a cell of dimension " << (int)this->boundary_matrix.get_dim( col_idx ) << ". "; + if( !this->boundary_matrix.is_empty( col_idx ) ) { + std::vector< phat::index > temp_col; + this->boundary_matrix.get_col( col_idx, temp_col ); + std::cout << "Its boundary consists of the cells"; + for( phat::index idx = 0; idx < (phat::index)temp_col.size(); idx++ ) + std::cout << " " << temp_col[ idx ]; + } + std::cout << std::endl; + } +} + +template +phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_dualized_chunk_reduction() +{ + phat::persistence_pairs pairs; + phat::compute_persistence_pairs_dualized< phat::chunk_reduction >( pairs, this->boundary_matrix ); + return pairs; +} + +template +phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_twist_reduction() +{ + phat::persistence_pairs pairs; + phat::compute_persistence_pairs< phat::twist_reduction >( pairs, this->boundary_matrix ); + return pairs; +} + +template +phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_standard_reduction() +{ + phat::persistence_pairs pairs; + phat::compute_persistence_pairs< phat::standard_reduction >( pairs, this->boundary_matrix ); + return pairs; +} + +//template +//phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_spectral_sequence_reduction() +//{ +// phat::persistence_pairs pairs; +// phat::compute_persistence_pairs< phat::spectral_sequence_reduction >( pairs, this->boundary_matrix ); +// return pairs; +//} + +template +Compute_persistence_with_phat::Compute_persistence_with_phat( T* data_structure_ ):data_structure( data_structure_ ) +{ + bool dbg = false; + this->boundary_matrix.set_num_cols( this->data_structure->num_simplices() ); + + //setting up the dimensions of cells: + for ( size_t i = 0 ; i != this->data_structure->num_simplices() ; ++i ) + { + this->boundary_matrix.set_dim( i, this->data_structure->dimension( this->data_structure->simplex(i) ) ); + } + + + //now it is time to set up the boundary matrix: + typename T::Filtration_simplex_range range = this->data_structure->filtration_simplex_range(); + std::vector< phat::index > temp_col; + for ( typename T::Filtration_simplex_iterator it = range.begin() ; it != range.end() ; ++it ) + { + typename T::Boundary_simplex_range boundary_range = this->data_structure->boundary_simplex_range( *it ); + for ( typename T::Boundary_simplex_iterator bd = boundary_range.begin() ; bd != boundary_range.end() ; ++bd ) + { + temp_col.push_back( this->data_structure->key( *bd ) ); + } + //we do not know if the boundary elements are sorted according to filtration, that is why I am enforcing it here: + this->boundary_matrix.set_col( this->data_structure->key( *it ) , temp_col ); + temp_col.clear(); + } +} + +template +std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > Compute_persistence_with_phat::get_the_intervals( phat::persistence_pairs pairs ) +{ + bool dbg = false; + //in order to find the birth times of the infinite homology classes, we need to know which elements are not paired. To search for them, we will use this vector: + std::vector isTheElementPaired( this->data_structure->num_simplices() , false ); + + //now it is time to recover the finite persistence pairs and the Betti numbers: + std::vector< std::vector< std::pair > > finitePersistencePairs( this->data_structure->dimension() ); + for( phat::index idx = 0; idx < pairs.get_num_pairs(); idx++ ) + { + typename T::Simplex_key positionOfBeginOfInterval = pairs.get_pair( idx ).first; + typename T::Simplex_key positionOfEndOfInterval = pairs.get_pair( idx ).second; + + typename T::Simplex_handle first_simplex = this->data_structure->simplex(positionOfBeginOfInterval); + typename T::Simplex_handle second_simplex = this->data_structure->simplex(positionOfEndOfInterval); + + typename T::Filtration_value valueFirst = this->data_structure->filtration( first_simplex ); + typename T::Filtration_value valueSecond = this->data_structure->filtration( second_simplex ); + + if ( valueFirst > valueSecond ){std::swap( valueFirst , valueSecond );} + + unsigned dimFirst = this->data_structure->dimension(first_simplex); + unsigned dimSecond = this->data_structure->dimension(second_simplex); + unsigned dim = std::min( dimFirst , dimSecond ); + + + //we are ignoring trivial barcodes + if ( valueFirst != valueSecond ) + { + finitePersistencePairs[ dim ].push_back( std::make_pair(valueFirst , valueSecond) ); + if ( dbg ){cerr << "Adding barcode : " << valueFirst << "," << valueSecond << endl;} + } + + //isTheElementPaired[ positionOfBeginOfIntervalInBitmap ] = true; + //isTheElementPaired[ positionOfEndOfIntervalInBitmap ] = true; + isTheElementPaired[ pairs.get_pair( idx ).first ] = true; + isTheElementPaired[ pairs.get_pair( idx ).second ] = true; + } + + + std::vector< std::vector > birthTimesOfInfinitePersistnceClasses(this->data_structure->dimension()+1 ); + for ( size_t i = 0 ; i != this->data_structure->dimension()+1 ; ++i ) + { + std::vector v; + birthTimesOfInfinitePersistnceClasses[i] = v; + } + for ( size_t i = 0 ; i != isTheElementPaired.size() ; ++i ) + { + if ( isTheElementPaired[i] == false ) + { + //i-th element is not paired, therefore it gives an infinite class + typename T::Simplex_handle simplex = this->data_structure->simplex(i); + birthTimesOfInfinitePersistnceClasses[ this->data_structure->dimension( simplex ) ].push_back( this->data_structure->filtration(simplex) ); + } + } + + //sorting finite persistence pairs: + for ( size_t dim = 0 ; dim != finitePersistencePairs.size() ; ++dim ) + { + std::sort( finitePersistencePairs[dim].begin() , finitePersistencePairs[dim].end() ); + } + return std::make_pair( birthTimesOfInfinitePersistnceClasses , finitePersistencePairs ); +}//Compute_persistence_with_phat + + + +}//namespace Gudhi diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h new file mode 100644 index 00000000..352392a8 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h @@ -0,0 +1,240 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../boundary_matrix.h" + +namespace phat { + class chunk_reduction { + public: + enum column_type { GLOBAL + , LOCAL_POSITIVE + , LOCAL_NEGATIVE }; + + public: + template< typename Representation > + void operator() ( boundary_matrix< Representation >& boundary_matrix ) { + + const index nr_columns = boundary_matrix.get_num_cols(); + const dimension max_dim = boundary_matrix.get_max_dim(); + + std::vector< index > lowest_one_lookup( nr_columns, -1 ); + std::vector < column_type > column_type( nr_columns, GLOBAL ); + std::vector< char > is_active( nr_columns, false ); + + std::vector chunk_boundaries; + _get_chunks( boundary_matrix, chunk_boundaries ); + + // Phase 1: Reduce chunks locally -- 1st pass + #pragma omp parallel for schedule( guided, 1 ) + for( index chunk_id = 0; chunk_id < (index) chunk_boundaries.size() - 2; chunk_id += 2 ) + _local_chunk_reduction( boundary_matrix, lowest_one_lookup, column_type, max_dim, + chunk_boundaries[chunk_id], chunk_boundaries[chunk_id+2] - 1 ); + boundary_matrix.sync(); + + // Phase 1: Reduce chunks locally -- 2nd pass + #pragma omp parallel for schedule( guided, 1 ) + for( index chunk_id = 1; chunk_id < (index) chunk_boundaries.size() - 2; chunk_id += 2 ) + _local_chunk_reduction( boundary_matrix, lowest_one_lookup, column_type, max_dim, + chunk_boundaries[chunk_id], chunk_boundaries[chunk_id+2] - 1 ); + boundary_matrix.sync(); + + // get global columns + std::vector< index > global_columns; + for( index cur_col_idx = 0; cur_col_idx < nr_columns; cur_col_idx++ ) + if( column_type[ cur_col_idx ] == GLOBAL ) + global_columns.push_back( cur_col_idx ); + + // get active columns + #pragma omp parallel for + for( index idx = 0; idx < (index)global_columns.size(); idx++ ) + is_active[ global_columns[ idx ] ] = true; + _get_active_columns( boundary_matrix, lowest_one_lookup, column_type, global_columns, is_active ); + + // Phase 2+3: Simplify columns and reduce them + for( dimension cur_dim = max_dim; cur_dim >= 1; cur_dim-- ) { + // Phase 2: Simplify columns + std::vector< index > temp_col; + #pragma omp parallel for schedule( guided, 1 ), private( temp_col ) + for( index idx = 0; idx < (index)global_columns.size(); idx++ ) + if( boundary_matrix.get_dim( global_columns[ idx ] ) == cur_dim ) + _global_column_simplification( global_columns[ idx ], boundary_matrix, lowest_one_lookup, column_type, is_active, temp_col ); + boundary_matrix.sync(); + + // Phase 3: Reduce columns + for( index idx = 0; idx < (index)global_columns.size(); idx++ ) { + index cur_col = global_columns[ idx ]; + if( boundary_matrix.get_dim( cur_col ) == cur_dim && column_type[ cur_col ] == GLOBAL ) { + index lowest_one = boundary_matrix.get_max_index( cur_col ); + while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { + boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); + lowest_one = boundary_matrix.get_max_index( cur_col ); + } + if( lowest_one != -1 ) { + lowest_one_lookup[ lowest_one ] = cur_col; + boundary_matrix.clear( lowest_one ); + } + } + } + } + + boundary_matrix.sync(); + } + + protected: + template< typename Representation > + void _get_chunks( const boundary_matrix< Representation >& boundary_matrix + , std::vector< index >& chunk_boundaries) + { + chunk_boundaries.clear(); + std::vector temp_chunk_boundaries; + const index nr_columns = boundary_matrix.get_num_cols(); + + // size of chuks = sqrt(N) + const index chunk_size = (index) sqrt( (float)nr_columns ); + + // size of chunks = N / num_threads + //const index chunk_size = nr_columns / omp_get_max_threads(); + + for ( index cur_col = 0; cur_col < nr_columns; cur_col++ ) + if( cur_col % chunk_size == 0 ) + temp_chunk_boundaries.push_back( cur_col ); + temp_chunk_boundaries.push_back( nr_columns ); + + // subdivide chunks for interleaved 2 pass appraoch + for( index chunk_id = 0; chunk_id < (index) temp_chunk_boundaries.size(); chunk_id ++ ) { + chunk_boundaries.push_back( temp_chunk_boundaries[ chunk_id ] ); + if( chunk_id < (index) temp_chunk_boundaries.size() - 1 ) { + index midPoint = ( temp_chunk_boundaries[ chunk_id ] + temp_chunk_boundaries[ chunk_id + 1 ] ) / 2; + chunk_boundaries.push_back( midPoint ); + } + } + } + + template< typename Representation > + void _local_chunk_reduction( boundary_matrix< Representation >& boundary_matrix + , std::vector& lowest_one_lookup + , std::vector< column_type >& column_type + , const dimension max_dim + , const index chunk_begin + , const index chunk_end ) { + for( dimension cur_dim = max_dim; cur_dim >= 1; cur_dim-- ) { + for( index cur_col = chunk_begin; cur_col <= chunk_end; cur_col++ ) { + if( column_type[ cur_col ] == GLOBAL && boundary_matrix.get_dim( cur_col ) == cur_dim ) { + index lowest_one = boundary_matrix.get_max_index( cur_col ); + while( lowest_one != -1 && lowest_one >= chunk_begin && lowest_one_lookup[ lowest_one ] != -1 ) { + boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); + lowest_one = boundary_matrix.get_max_index( cur_col ); + } + if( lowest_one >= chunk_begin ) { + lowest_one_lookup[ lowest_one ] = cur_col; + column_type[ cur_col ] = LOCAL_NEGATIVE; + column_type[ lowest_one ] = LOCAL_POSITIVE; + boundary_matrix.clear( lowest_one ); + } + } + } + } + } + + template< typename Representation > + void _get_active_columns( const boundary_matrix< Representation >& boundary_matrix + , const std::vector< index >& lowest_one_lookup + , const std::vector< column_type >& column_type + , const std::vector< index >& global_columns + , std::vector< char >& is_active ) { + + const index nr_columns = boundary_matrix.get_num_cols(); + std::vector< char > finished( nr_columns, false ); + + std::vector< std::pair < index, index > > stack; + std::vector< index > cur_col_values; + #pragma omp parallel for schedule( guided, 1 ), private( stack, cur_col_values ) + for( index idx = 0; idx < (index)global_columns.size(); idx++ ) { + bool pop_next = false; + index start_col = global_columns[ idx ]; + stack.push_back( std::pair< index, index >( start_col, -1 ) ); + while( !stack.empty() ) { + index cur_col = stack.back().first; + index prev_col = stack.back().second; + if( pop_next ) { + stack.pop_back(); + pop_next = false; + if( prev_col != -1 ) { + if( is_active[ cur_col ] ) { + is_active[ prev_col ] = true; + } + if( prev_col == stack.back().first ) { + finished[ prev_col ] = true; + pop_next = true; + } + } + } else { + pop_next = true; + boundary_matrix.get_col( cur_col, cur_col_values ); + for( index idx = 0; idx < (index) cur_col_values.size(); idx++ ) { + index cur_row = cur_col_values[ idx ]; + if( ( column_type[ cur_row ] == GLOBAL ) ) { + is_active[ cur_col ] = true; + } else if( column_type[ cur_row ] == LOCAL_POSITIVE ) { + index next_col = lowest_one_lookup[ cur_row ]; + if( next_col != cur_col && !finished[ cur_col ] ) { + stack.push_back( std::make_pair( next_col, cur_col ) ); + pop_next = false; + } + } + } + } + } + } + } + + template< typename Representation > + void _global_column_simplification( const index col_idx + , boundary_matrix< Representation >& boundary_matrix + , const std::vector< index >& lowest_one_lookup + , const std::vector< column_type >& column_type + , const std::vector< char >& is_active + , std::vector< index >& temp_col ) + { + temp_col.clear(); + while( !boundary_matrix.is_empty( col_idx ) ) { + index cur_row = boundary_matrix.get_max_index( col_idx ); + switch( column_type[ cur_row ] ) { + case GLOBAL: + temp_col.push_back( cur_row ); + boundary_matrix.remove_max( col_idx ); + break; + case LOCAL_NEGATIVE: + boundary_matrix.remove_max( col_idx ); + break; + case LOCAL_POSITIVE: + if( is_active[ lowest_one_lookup[ cur_row ] ] ) + boundary_matrix.add_to( lowest_one_lookup[ cur_row ], col_idx ); + else + boundary_matrix.remove_max( col_idx ); + break; + } + } + std::reverse( temp_col.begin(), temp_col.end() ); + boundary_matrix.set_col( col_idx, temp_col ); + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h new file mode 100644 index 00000000..2047cafd --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h @@ -0,0 +1,55 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../boundary_matrix.h" + +namespace phat { + class row_reduction { + public: + template< typename Representation > + void operator() ( boundary_matrix< Representation >& boundary_matrix ) { + + const index nr_columns = boundary_matrix.get_num_cols(); + std::vector< std::vector< index > > lowest_one_lookup( nr_columns ); + + for( index cur_col = nr_columns - 1; cur_col >= 0; cur_col-- ) { + if( !boundary_matrix.is_empty( cur_col ) ) + lowest_one_lookup[ boundary_matrix.get_max_index( cur_col ) ].push_back( cur_col ); + + if( !lowest_one_lookup[ cur_col ].empty() ) { + boundary_matrix.clear( cur_col ); + std::vector< index >& cols_with_cur_lowest = lowest_one_lookup[ cur_col ]; + index source = *min_element( cols_with_cur_lowest.begin(), cols_with_cur_lowest.end() ); + for( index idx = 0; idx < (index)cols_with_cur_lowest.size(); idx++ ) { + index target = cols_with_cur_lowest[ idx ]; + if( target != source && !boundary_matrix.is_empty( target ) ) { + boundary_matrix.add_to( source, target ); + if( !boundary_matrix.is_empty( target ) ) { + index lowest_one_of_target = boundary_matrix.get_max_index( target ); + lowest_one_lookup[ lowest_one_of_target ].push_back( target ); + } + } + } + } + } + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h new file mode 100644 index 00000000..b2c91a85 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h @@ -0,0 +1,45 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../boundary_matrix.h" + +namespace phat { + class standard_reduction { + public: + template< typename Representation > + void operator() ( boundary_matrix< Representation >& boundary_matrix ) { + + const index nr_columns = boundary_matrix.get_num_cols(); + std::vector< index > lowest_one_lookup( nr_columns, -1 ); + + for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { + index lowest_one = boundary_matrix.get_max_index( cur_col ); + while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { + boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); + lowest_one = boundary_matrix.get_max_index( cur_col ); + } + if( lowest_one != -1 ) { + lowest_one_lookup[ lowest_one ] = cur_col; + } + } + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h new file mode 100644 index 00000000..1bdd8de2 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h @@ -0,0 +1,50 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../boundary_matrix.h" + +namespace phat { + class twist_reduction { + public: + template< typename Representation > + void operator () ( boundary_matrix< Representation >& boundary_matrix ) { + + const index nr_columns = boundary_matrix.get_num_cols(); + std::vector< index > lowest_one_lookup( nr_columns, -1 ); + + for( index cur_dim = boundary_matrix.get_max_dim(); cur_dim >= 1 ; cur_dim-- ) { + for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { + if( boundary_matrix.get_dim( cur_col ) == cur_dim ) { + index lowest_one = boundary_matrix.get_max_index( cur_col ); + while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { + boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); + lowest_one = boundary_matrix.get_max_index( cur_col ); + } + if( lowest_one != -1 ) { + lowest_one_lookup[ lowest_one ] = cur_col; + boundary_matrix.clear( lowest_one ); + } + } + } + } + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h b/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h new file mode 100644 index 00000000..941537da --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h @@ -0,0 +1,336 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "helpers/misc.h" +#include "representations/bit_tree_pivot_column.h" + +// interface class for the main data structure -- implementations of the interface can be found in ./representations +namespace phat { + template< class Representation = bit_tree_pivot_column > + class boundary_matrix + { + + protected: + Representation rep; + + // interface functions -- actual implementation and complexity depends on chosen @Representation template + public: + // get overall number of columns in boundary_matrix + index get_num_cols() const { return rep._get_num_cols(); } + + // set overall number of columns in boundary_matrix + void set_num_cols( index nr_of_columns ) { rep._set_num_cols( nr_of_columns ); } + + // get dimension of given index + dimension get_dim( index idx ) const { return rep._get_dim( idx ); } + + // set dimension of given index + void set_dim( index idx, dimension dim ) { rep._set_dim( idx, dim ); } + + // replaces content of @col with boundary of given index + void get_col( index idx, column& col ) const { rep._get_col( idx, col ); } + + // set column @idx to the values contained in @col + void set_col( index idx, const column& col ) { rep._set_col( idx, col ); } + + // true iff boundary of given column is empty + bool is_empty( index idx ) const { return rep._is_empty( idx ); } + + // largest index of given column (new name for lowestOne()) + index get_max_index( index idx ) const { return rep._get_max_index( idx ); } + + // removes maximal index from given column + void remove_max( index idx ) { rep._remove_max( idx ); } + + // adds column @source to column @target' + void add_to( index source, index target ) { rep._add_to( source, target ); } + + // clears given column + void clear( index idx ) { rep._clear( idx ); } + + // syncronizes all internal data structures -- has to be called before and after any multithreaded access! + void sync() { rep._sync(); } + + // info functions -- independent of chosen 'Representation' + public: + // maximal dimension + dimension get_max_dim() const { + dimension cur_max_dim = 0; + for( index idx = 0; idx < get_num_cols(); idx++ ) + cur_max_dim = get_dim( idx ) > cur_max_dim ? get_dim( idx ) : cur_max_dim; + return cur_max_dim; + } + + // number of nonzero rows for given column @idx + index get_num_rows( index idx ) const { + column cur_col; + get_col( idx, cur_col ); + return cur_col.size(); + } + + // maximal number of nonzero rows of all columns + index get_max_col_entries() const { + index max_col_entries = -1; + const index nr_of_columns = get_num_cols(); + for( index idx = 0; idx < nr_of_columns; idx++ ) + max_col_entries = get_num_rows( idx ) > max_col_entries ? get_num_rows( idx ) : max_col_entries; + return max_col_entries; + } + + // maximal number of nonzero cols of all rows + index get_max_row_entries() const { + size_t max_row_entries = 0; + const index nr_of_columns = get_num_cols(); + std::vector< std::vector< index > > transposed_matrix( nr_of_columns ); + column temp_col; + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + get_col( cur_col, temp_col ); + for( index idx = 0; idx < (index)temp_col.size(); idx++) + transposed_matrix[ temp_col[ idx ] ].push_back( cur_col ); + } + for( index idx = 0; idx < nr_of_columns; idx++ ) + max_row_entries = transposed_matrix[ idx ].size() > max_row_entries ? transposed_matrix[ idx ].size() : max_row_entries; + return max_row_entries; + } + + // overall number of entries in the matrix + index get_num_entries() const { + index number_of_nonzero_entries = 0; + const index nr_of_columns = get_num_cols(); + for( index idx = 0; idx < nr_of_columns; idx++ ) + number_of_nonzero_entries += get_num_rows( idx ); + return number_of_nonzero_entries; + } + + // operators / constructors + public: + boundary_matrix() {}; + + template< class OtherRepresentation > + boundary_matrix( const boundary_matrix< OtherRepresentation >& other ) { + *this = other; + } + + template< typename OtherRepresentation > + bool operator==( const boundary_matrix< OtherRepresentation >& other_boundary_matrix ) const { + const index number_of_columns = this->get_num_cols(); + + if( number_of_columns != other_boundary_matrix.get_num_cols() ) + return false; + + column temp_col; + column other_temp_col; + for( index idx = 0; idx < number_of_columns; idx++ ) { + this->get_col( idx, temp_col ); + other_boundary_matrix.get_col( idx, other_temp_col ); + if( temp_col != other_temp_col || this->get_dim( idx ) != other_boundary_matrix.get_dim( idx ) ) + return false; + } + return true; + } + + template< typename OtherRepresentation > + bool operator!=( const boundary_matrix< OtherRepresentation >& other_boundary_matrix ) const { + return !( *this == other_boundary_matrix ); + } + + template< typename OtherRepresentation > + boundary_matrix< Representation >& operator=( const boundary_matrix< OtherRepresentation >& other ) + { + const index nr_of_columns = other.get_num_cols(); + this->set_num_cols( nr_of_columns ); + column temp_col; + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + this->set_dim( cur_col, other.get_dim( cur_col ) ); + other.get_col( cur_col, temp_col ); + this->set_col( cur_col, temp_col ); + } + + // by convention, always return *this + return *this; + } + + // I/O -- independent of chosen 'Representation' + public: + + // initializes boundary_matrix from (vector, vector) pair -- untested + template< typename index_type, typename dimemsion_type > + void load_vector_vector( const std::vector< std::vector< index_type > >& input_matrix, const std::vector< dimemsion_type >& input_dims ) { + const index nr_of_columns = (index)input_matrix.size(); + this->set_num_cols( nr_of_columns ); + column temp_col; + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + this->set_dim( cur_col, (dimension)input_dims[ cur_col ] ); + + index num_rows = input_matrix[ cur_col ].size(); + temp_col.resize( num_rows ); + for( index cur_row = 0; cur_row < num_rows; cur_row++ ) + temp_col[ cur_row ] = (index)input_matrix[ cur_col ][ cur_row ]; + this->set_col( cur_col, temp_col ); + } + } + + template< typename index_type, typename dimemsion_type > + void save_vector_vector( std::vector< std::vector< index_type > >& output_matrix, std::vector< dimemsion_type >& output_dims ) { + const index nr_of_columns = get_num_cols(); + output_matrix.resize( nr_of_columns ); + output_dims.resize( nr_of_columns ); + column temp_col; + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + output_dims[ cur_col ] = (dimemsion_type)get_dim( cur_col ); + get_col( cur_col, temp_col ); + index num_rows = temp_col.size(); + output_matrix[ cur_col ].clear(); + output_matrix[ cur_col ].resize( num_rows ); + for( index cur_row = 0; cur_row < num_rows; cur_row++ ) + output_matrix[ cur_col ][ cur_row ] = (index_type)temp_col[ cur_row ]; + } + } + + // Loads the boundary_matrix from given file in ascii format + // Format: each line represents a column, first number is dimension, other numbers are the content of the column. + // Ignores empty lines and lines starting with a '#'. + bool load_ascii( std::string filename ) { + // first count number of columns: + std::string cur_line; + std::ifstream dummy( filename .c_str() ); + if( dummy.fail() ) + return false; + + index number_of_columns = 0; + while( getline( dummy, cur_line ) ) { + cur_line.erase(cur_line.find_last_not_of(" \t\n\r\f\v") + 1); + if( cur_line != "" && cur_line[ 0 ] != '#' ) + number_of_columns++; + + } + this->set_num_cols( number_of_columns ); + dummy.close(); + + std::ifstream input_stream( filename.c_str() ); + if( input_stream.fail() ) + return false; + + column temp_col; + index cur_col = -1; + while( getline( input_stream, cur_line ) ) { + cur_line.erase(cur_line.find_last_not_of(" \t\n\r\f\v") + 1); + if( cur_line != "" && cur_line[ 0 ] != '#' ) { + cur_col++; + std::stringstream ss( cur_line ); + + int64_t temp_dim; + ss >> temp_dim; + this->set_dim( cur_col, (dimension) temp_dim ); + + int64_t temp_index; + temp_col.clear(); + while( ss.good() ) { + ss >> temp_index; + temp_col.push_back( (index)temp_index ); + } + std::sort( temp_col.begin(), temp_col.end() ); + this->set_col( cur_col, temp_col ); + } + } + + input_stream.close(); + return true; + } + + // Saves the boundary_matrix to given file in ascii format + // Format: each line represents a column, first number is dimension, other numbers are the content of the column + bool save_ascii( std::string filename ) { + std::ofstream output_stream( filename.c_str() ); + if( output_stream.fail() ) + return false; + + const index nr_columns = this->get_num_cols(); + column tempCol; + for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { + output_stream << (int64_t)this->get_dim( cur_col ); + this->get_col( cur_col, tempCol ); + for( index cur_row_idx = 0; cur_row_idx < (index)tempCol.size(); cur_row_idx++ ) + output_stream << " " << tempCol[ cur_row_idx ]; + output_stream << std::endl; + } + + output_stream.close(); + return true; + } + + // Loads boundary_matrix from given file + // Format: nr_columns % dim1 % N1 % row1 row2 % ...% rowN1 % dim2 % N2 % ... + bool load_binary( std::string filename ) { + std::ifstream input_stream( filename.c_str(), std::ios_base::binary | std::ios_base::in ); + if( input_stream.fail() ) + return false; + + int64_t nr_columns; + input_stream.read( (char*)&nr_columns, sizeof( int64_t ) ); + this->set_num_cols( (index)nr_columns ); + + column temp_col; + for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { + int64_t cur_dim; + input_stream.read( (char*)&cur_dim, sizeof( int64_t ) ); + this->set_dim( cur_col, (dimension) cur_dim ); + int64_t nr_rows; + input_stream.read( (char*)&nr_rows, sizeof( int64_t ) ); + temp_col.resize( (std::size_t)nr_rows ); + for( index idx = 0; idx < nr_rows; idx++ ) { + int64_t cur_row; + input_stream.read( (char*)&cur_row, sizeof( int64_t ) ); + temp_col[ idx ] = (index)cur_row; + } + this->set_col( cur_col, temp_col ); + } + + input_stream.close(); + return true; + } + + // Saves the boundary_matrix to given file in binary format + // Format: nr_columns % dim1 % N1 % row1 row2 % ...% rowN1 % dim2 % N2 % ... + bool save_binary( std::string filename ) { + std::ofstream output_stream( filename.c_str(), std::ios_base::binary | std::ios_base::out ); + if( output_stream.fail() ) + return false; + + const int64_t nr_columns = this->get_num_cols(); + output_stream.write( (char*)&nr_columns, sizeof( int64_t ) ); + column tempCol; + for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { + int64_t cur_dim = this->get_dim( cur_col ); + output_stream.write( (char*)&cur_dim, sizeof( int64_t ) ); + this->get_col( cur_col, tempCol ); + int64_t cur_nr_rows = tempCol.size(); + output_stream.write( (char*)&cur_nr_rows, sizeof( int64_t ) ); + for( index cur_row_idx = 0; cur_row_idx < (index)tempCol.size(); cur_row_idx++ ) { + int64_t cur_row = tempCol[ cur_row_idx ]; + output_stream.write( (char*)&cur_row, sizeof( int64_t ) ); + } + } + + output_stream.close(); + return true; + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h b/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h new file mode 100644 index 00000000..f5b04d5a --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h @@ -0,0 +1,69 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "persistence_pairs.h" +#include "boundary_matrix.h" +#include "helpers/dualize.h" +#include "algorithms/twist_reduction.h" + +namespace phat { + + template< typename ReductionAlgorithm, typename Representation > + void compute_persistence_pairs( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { + ReductionAlgorithm reduce; + reduce( boundary_matrix ); + pairs.clear(); + for( index idx = 0; idx < boundary_matrix.get_num_cols(); idx++ ) { + if( !boundary_matrix.is_empty( idx ) ) { + index birth = boundary_matrix.get_max_index( idx ); + index death = idx; + pairs.append_pair( birth, death ); + } + } + } + + template< typename ReductionAlgorithm, typename Representation > + void compute_persistence_pairs_dualized( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { + ReductionAlgorithm reduce; + const index nr_columns = boundary_matrix.get_num_cols(); + dualize( boundary_matrix ); + reduce( boundary_matrix ); + pairs.clear(); + for( index idx = 0; idx < nr_columns; idx++ ) { + if( !boundary_matrix.is_empty( idx ) ) { + index death = nr_columns - 1 - boundary_matrix.get_max_index( idx ); + index birth = nr_columns - 1 - idx; + pairs.append_pair( birth, death ); + } + } + } + + template< typename Representation > + void compute_persistence_pairs( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { + phat::compute_persistence_pairs< twist_reduction >( pairs, boundary_matrix ); + } + + + template< typename Representation > + void compute_persistence_pairs_dualized( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { + compute_persistence_pairs_dualized< twist_reduction >( pairs, boundary_matrix ); + } + +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h new file mode 100644 index 00000000..60caa05c --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h @@ -0,0 +1,63 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "misc.h" +#include "../boundary_matrix.h" + +namespace phat { + template< typename Representation > + void dualize( boundary_matrix< Representation >& boundary_matrix ) { + + std::vector< dimension > dual_dims; + std::vector< std::vector< index > > dual_matrix; + + index nr_of_columns = boundary_matrix.get_num_cols(); + dual_matrix.resize( nr_of_columns ); + dual_dims.resize( nr_of_columns ); + + std::vector< index > dual_sizes( nr_of_columns, 0 ); + + column temp_col; + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + boundary_matrix.get_col( cur_col, temp_col ); + for( index idx = 0; idx < (index)temp_col.size(); idx++) + dual_sizes[ nr_of_columns - 1 - temp_col[ idx ] ]++; + } + + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + dual_matrix[cur_col].reserve(dual_sizes[cur_col]); + } + + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { + boundary_matrix.get_col( cur_col, temp_col ); + for( index idx = 0; idx < (index)temp_col.size(); idx++) + dual_matrix[ nr_of_columns - 1 - temp_col[ idx ] ].push_back( nr_of_columns - 1 - cur_col ); + } + + const dimension max_dim = boundary_matrix.get_max_dim(); + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) + dual_dims[ nr_of_columns - 1 - cur_col ] = max_dim - boundary_matrix.get_dim( cur_col ); + + for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) + std::reverse( dual_matrix[ cur_col ].begin(), dual_matrix[ cur_col ].end() ); + + boundary_matrix.load_vector_vector( dual_matrix, dual_dims ); + } +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h new file mode 100644 index 00000000..abbf8d53 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h @@ -0,0 +1,74 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +// STL includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// VS2008 and below unfortunately do not support stdint.h +#if defined(_MSC_VER)&& _MSC_VER < 1600 + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +#else + #include +#endif + +// basic types. index can be changed to int32_t to save memory on small instances +namespace phat { + typedef int64_t index; + typedef int8_t dimension; + typedef std::vector< index > column; +} + +// OpenMP (proxy) functions +#if defined _OPENMP + #include +#else + #define omp_get_thread_num() 0 + #define omp_get_max_threads() 1 + #define omp_get_num_threads() 1 + void omp_set_num_threads( int ) {}; + #include + #define omp_get_wtime() (float)clock() / (float)CLOCKS_PER_SEC +#endif + +#include "thread_local_storage.h" + + + diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h new file mode 100644 index 00000000..06e95c20 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h @@ -0,0 +1,52 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "misc.h" + +// should ideally be equal to the cache line size of the CPU +#define PHAT_TLS_SPACING_FACTOR 64 + +// ThreadLocalStorage with some spacing to avoid "false sharing" (see wikipedia) +template< typename T > +class thread_local_storage +{ +public: + + thread_local_storage() : per_thread_storage( omp_get_max_threads() * PHAT_TLS_SPACING_FACTOR ) {}; + + T& operator()() { + return per_thread_storage[ omp_get_thread_num() * PHAT_TLS_SPACING_FACTOR ]; + } + + const T& operator()() const { + return per_thread_storage[ omp_get_thread_num() * PHAT_TLS_SPACING_FACTOR ]; + } + + T& operator[]( int tid ) { + return per_thread_storage[ tid * PHAT_TLS_SPACING_FACTOR ]; + } + + const T& operator[]( int tid ) const { + return per_thread_storage[ tid * PHAT_TLS_SPACING_FACTOR ]; + } + +protected: + std::vector< T > per_thread_storage; +}; diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h b/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h new file mode 100644 index 00000000..f8006353 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h @@ -0,0 +1,151 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "helpers/misc.h" + +namespace phat { + class persistence_pairs { + + protected: + std::vector< std::pair< index, index > > pairs; + + public: + index get_num_pairs() const { + return (index)pairs.size(); + } + + void append_pair( index birth, index death ) { + pairs.push_back( std::make_pair( birth, death ) ); + } + + std::pair< index, index > get_pair( index idx ) const { + return pairs[ idx ]; + } + + void clear() { + pairs.clear(); + } + + void sort() { + std::sort( pairs.begin(), pairs.end() ); + } + + // Loads the persistence pairs from given file in asci format + // Format: nr_pairs % newline % birth1 % death1 % newline % birth2 % death2 % newline ... + bool load_ascii( std::string filename ) { + std::ifstream input_stream( filename.c_str() ); + if( input_stream.fail() ) + return false; + + int64_t nr_pairs; + input_stream >> nr_pairs; + pairs.clear(); + for( index idx = 0; idx < nr_pairs; idx++ ) { + int64_t birth; + input_stream >> birth; + int64_t death; + input_stream >> death; + append_pair( (index)birth, (index)death ); + } + + input_stream.close(); + return true; + } + + // Saves the persistence pairs to given file in binary format + // Format: nr_pairs % newline % birth1 % death1 % newline % birth2 % death2 % newline ... + bool save_ascii( std::string filename ) { + std::ofstream output_stream( filename.c_str() ); + if( output_stream.fail() ) + return false; + + this->sort(); + output_stream << get_num_pairs() << std::endl; + for( std::size_t idx = 0; idx < pairs.size(); idx++ ) { + output_stream << pairs[idx].first << " " << pairs[idx].second << std::endl; + } + + output_stream.close(); + return true; + } + + // Loads the persistence pairs from given file in binary format + // Format: nr_pairs % birth1 % death1 % birth2 % death2 ... + bool load_binary( std::string filename ) { + std::ifstream input_stream( filename.c_str(), std::ios_base::binary | std::ios_base::in ); + if( input_stream.fail() ) + return false; + + int64_t nr_pairs; + input_stream.read( (char*)&nr_pairs, sizeof( int64_t ) ); + for( index idx = 0; idx < nr_pairs; idx++ ) { + int64_t birth; + input_stream.read( (char*)&birth, sizeof( int64_t ) ); + int64_t death; + input_stream.read( (char*)&death, sizeof( int64_t ) ); + append_pair( (index)birth, (index)death ); + } + + input_stream.close(); + return true; + } + + // Saves the persistence pairs to given file in binary format + // Format: nr_pairs % birth1 % death1 % birth2 % death2 ... + bool save_binary( std::string filename ) { + std::ofstream output_stream( filename.c_str(), std::ios_base::binary | std::ios_base::out ); + if( output_stream.fail() ) + return false; + + this->sort(); + int64_t nr_pairs = get_num_pairs(); + output_stream.write( (char*)&nr_pairs, sizeof( int64_t ) ); + for( std::size_t idx = 0; idx < pairs.size(); idx++ ) { + int64_t birth = pairs[ idx ].first; + output_stream.write( (char*)&birth, sizeof( int64_t ) ); + int64_t death = pairs[ idx ].second; + output_stream.write( (char*)&death, sizeof( int64_t ) ); + } + + output_stream.close(); + return true; + } + + bool operator==( persistence_pairs& other_pairs ) { + this->sort(); + other_pairs.sort(); + if( pairs.size() != (std::size_t)other_pairs.get_num_pairs() ) + return false; + + for( index idx = 0; idx < (index)pairs.size(); idx++ ) + if( get_pair( idx ) != other_pairs.get_pair( idx ) ) + return false; + + return true; + } + + bool operator!=( persistence_pairs& other_pairs ) { + return !( *this == other_pairs ); + } + }; + + + +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h new file mode 100644 index 00000000..41104108 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h @@ -0,0 +1,158 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../representations/vector_vector.h" + +namespace phat { + + // Note: We could even make the rep generic in the underlying Const representation + // But I cannot imagine that anything else than vector> would + // make sense + template< typename PivotColumn > + class abstract_pivot_column : public vector_vector { + public: + + protected: + typedef vector_vector Base; + typedef PivotColumn pivot_column; + + // For parallization purposes, it could be more than one full column + mutable thread_local_storage< pivot_column > _pivot_columns; + mutable thread_local_storage< index > pos_of_pivot_columns; + + pivot_column& get_pivot_column() const { + return _pivot_columns(); + } + + bool is_represented_by_pivot_column( index idx ) const { + return pos_of_pivot_columns() == idx; + } + + void unset_pos_of_pivot_column() { + index idx = pos_of_pivot_columns(); + if( idx != -1 ) { + _pivot_columns().get_column_and_clear( this->matrix[ idx ] ); + } + pos_of_pivot_columns() = -1; + } + + void represent_by_pivot_column( index idx ) { + pos_of_pivot_columns() = idx; + get_pivot_column().add_column( matrix[ idx ] ); + } + + public: + + void _set_num_cols( index nr_of_columns ) { + #pragma omp parallel for + for( int tid = 0; tid < omp_get_num_threads(); tid++ ) { + _pivot_columns[ tid ].init( nr_of_columns ); + pos_of_pivot_columns[ tid ] = -1; + } + Base::_set_num_cols( nr_of_columns ); + } + // replaces(!) content of 'col' with boundary of given index + void _get_col( index idx, column& col ) const { + col.clear(); + if( is_represented_by_pivot_column( idx ) ) { + pivot_column& pivot_column = get_pivot_column(); + pivot_column.get_column_and_clear( col ); + pivot_column.add_column( col ); + } else { + Base::_get_col( idx, col ); + } + } + + // true iff boundary of given idx is empty + bool _is_empty( index idx ) const { + return is_represented_by_pivot_column( idx ) ? get_pivot_column().empty() : Base::_is_empty( idx ); + } + + // largest row index of given column idx (new name for lowestOne()) + index _get_max_index( index idx ) const { + if( is_represented_by_pivot_column( idx ) ) { + pivot_column& pivot_column = get_pivot_column(); + if( pivot_column.empty() ) { + return -1; + } else { + return pivot_column.max_index(); + } + } else { + return Base::_get_max_index( idx ); + } + } + + // adds column 'source' to column 'target' + void _add_to( index source, index target ) { + if( !is_represented_by_pivot_column( target ) ) { + unset_pos_of_pivot_column(); + represent_by_pivot_column( target ); + } + get_pivot_column().add_column( matrix[source] ); + } + + // clears given column + void _clear( index idx ) { + if( is_represented_by_pivot_column( idx ) ) { + column dummy; + get_pivot_column().get_column_and_clear(dummy); + } else { + Base::_clear( idx ); + } + } + + void _set_col( index idx, const column& col ) { + if( is_represented_by_pivot_column( idx ) ) { + column dummy; + pivot_column& pivot_column = get_pivot_column(); + pivot_column.get_column_and_clear( dummy ); + pivot_column.add_column( col ); + } else { + Base::_set_col( idx, col ); + } + } + + // removes the maximal index of a column + void _remove_max( index idx ) { + _toggle( idx, _get_max_index( idx ) ); + } + + //// toggles given index pair + void _toggle( index col_idx, index row_idx ) { + if( !is_represented_by_pivot_column( col_idx ) ) { + unset_pos_of_pivot_column(); + represent_by_pivot_column( col_idx ); + } + get_pivot_column().add_index( row_idx ); + } + + // syncronizes all data structures (essential for openmp stuff) + // has to be called before and after any multithreaded access! + void _sync() { + #pragma omp parallel for + for( int tid = 0; tid < omp_get_num_threads(); tid++ ) + unset_pos_of_pivot_column(); + } + + }; +} + + diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h new file mode 100644 index 00000000..34366d6a --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h @@ -0,0 +1,169 @@ +/* Copyright 2013 IST Austria + Contributed by: Hubert Wagner + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" +#include "../representations/abstract_pivot_column.h" + +namespace phat { + + // This is a bitset indexed with a 64-ary tree. Each node in the index + // has 64 bits; i-th bit says that the i-th subtree is non-empty. + // Supports practically O(1), inplace, zero-allocation: insert, remove, max_element + // and clear in O(number of ones in the bitset). + // 'add_index' is still the real bottleneck in practice. + class bit_tree_column + { + size_t offset; // data[i + offset] = ith block of the data-bitset + typedef uint64_t block_type; + std::vector< block_type > data; + + // this static is not a problem with OMP, it's initialized just after program starts + static const size_t debrujin_magic_table[64]; + + enum { block_size_in_bits = 64 }; + enum { block_shift = 6 }; + + // Some magic: http://graphics.stanford.edu/~seander/bithacks.html + // Gets the position of the rightmost bit of 'x'. 0 means the most significant bit. + // (-x)&x isolates the rightmost bit. + // The whole method is much faster than calling log2i, and very comparable to using ScanBitForward/Reverse intrinsic, + // which should be one CPU instruction, but is not portable. + size_t rightmost_pos(const block_type value) const + { + return 64 - 1 - debrujin_magic_table[((value & (-(int64_t)value))*0x07EDD5E59A4E28C2) >> 58]; + } + + public: + + void init(index num_cols) + { + int64_t n = 1; // in case of overflow + int64_t bottom_blocks_needed = (num_cols+block_size_in_bits-1)/block_size_in_bits; + int64_t upper_blocks = 1; + + // How many blocks/nodes of index needed to index the whole bitset? + while(n * block_size_in_bits < bottom_blocks_needed) + { + n *= block_size_in_bits; + upper_blocks += n; + } + + offset = upper_blocks; + data.resize(upper_blocks + bottom_blocks_needed, 0); + } + + index max_index() const + { + if (!data[0]) + return -1; + + const size_t size = data.size(); + size_t n = 0; + + while(true) + { + const block_type val = data[n]; + const size_t index = rightmost_pos(val); + const size_t newn = (n << block_shift) + index + 1; + + if (newn >= size) + { + const size_t bottom_index = n - offset; + return (bottom_index << block_shift) + index; + } + + n = newn; + } + + return -1; + } + + bool empty() const + { + return data[0] == 0; + } + + void add_index(const size_t entry) + { + const block_type ONE = 1; + const block_type block_modulo_mask = ((ONE << block_shift) - 1); + size_t index_in_level = entry >> block_shift; + size_t address = index_in_level + offset; + size_t index_in_block = entry & block_modulo_mask; + + block_type mask = (ONE << (block_size_in_bits - index_in_block - 1)); + + while(true) + { + data[address]^=mask; + + // First we check if we reached the root. + // Also, if anyone else was in this block, we don't need to update the path up. + if (!address || (data[address] & ~mask)) + return; + + index_in_block = index_in_level & block_modulo_mask; + index_in_level >>= block_shift; + --address; + address >>= block_shift; + mask = (ONE << (block_size_in_bits - index_in_block - 1)); + } + } + + void get_column_and_clear(column &out) + { + out.clear(); + while(true) + { + index mx = this->max_index(); + if (mx == -1) + break; + out.push_back(mx); + add_index(mx); + } + + std::reverse(out.begin(), out.end()); + } + + void add_column(const column &col) + { + for (size_t i = 0; i < col.size(); ++i) + { + add_index(col[i]); + } + } + + bool empty() { + return !data[0]; + } + }; + + const size_t bit_tree_column::debrujin_magic_table[64] = { + 63, 0, 58, 1, 59, 47, 53, 2, + 60, 39, 48, 27, 54, 33, 42, 3, + 61, 51, 37, 40, 49, 18, 28, 20, + 55, 30, 34, 11, 43, 14, 22, 4, + 62, 57, 46, 52, 38, 26, 32, 41, + 50, 36, 17, 19, 29, 10, 13, 21, + 56, 45, 25, 31, 35, 16, 9, 12, + 44, 24, 15, 8, 23, 7, 6, 5}; + + typedef abstract_pivot_column bit_tree_pivot_column; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h new file mode 100644 index 00000000..9e0c348d --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h @@ -0,0 +1,81 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include +#include + +namespace phat { + class full_column { + + protected: + std::priority_queue< index > m_history; + std::vector< char > m_isInHistory; + std::vector< char > m_data; + + public: + void init( const index total_size ) { + m_data.resize( total_size, false ); + m_isInHistory.resize( total_size, false ); + } + + void add_column( const column& col ) { + for( index idx = 0; idx < (index) col.size(); idx++ ) { + add_index( col[ idx ] ); + } + } + void add_index( const index idx ) { + if( !m_isInHistory[ idx ] ) { + m_history.push( idx ); + m_isInHistory[ idx ] = true; + } + + m_data[ idx ] = !m_data[ idx ]; + } + + index max_index() { + while( m_history.size() > 0 ) { + index topIndex = m_history.top(); + if( m_data[ topIndex ] ) { + return topIndex; + } else { + m_history.pop(); + m_isInHistory[ topIndex ] = false; + } + } + + return -1; + } + + void get_column_and_clear( column& col ) { + col.clear(); + while( !empty() ) { + col.push_back( max_index() ); + add_index( max_index() ); + } + std::reverse( col.begin(), col.end() ); + } + + bool empty() { + return (max_index() == -1); + } + }; + + typedef abstract_pivot_column< full_column > full_pivot_column; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h new file mode 100644 index 00000000..c851a2b5 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h @@ -0,0 +1,62 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include +#include + +namespace phat { + class sparse_column { + + protected: + std::set< index > m_data; + + public: + void init( const index total_size ) { + m_data.clear(); + } + + void add_column( const column& col ) { + for( index idx = 0; idx < (index) col.size(); idx++ ) + add_index( col[ idx ] ); + } + + void add_index( const index idx ) { + std::pair< std::set< index >::iterator, bool > result = m_data.insert( idx ); + if( result.second == false ) + m_data.erase( result.first ); + } + + index max_index() { + return m_data.empty() ? -1 : *m_data.rbegin(); + } + + void get_column_and_clear( column& col ) { + col.clear(); + col.assign( m_data.begin(), m_data.end() ); + m_data.clear(); + } + + bool empty() { + return m_data.empty(); + } + }; + + typedef abstract_pivot_column< sparse_column > sparse_pivot_column; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h new file mode 100644 index 00000000..38e3090c --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h @@ -0,0 +1,98 @@ +/* Copyright 2013 IST Austria + Contributed by: Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include + +namespace phat { + class vector_list { + + protected: + typedef std::list< index > internal_column; + std::vector< dimension > dims; + std::vector< internal_column > matrix; + + public: + // overall number of cells in boundary_matrix + index _get_num_cols() const { + return (index)matrix.size(); + } + void _set_num_cols( index nr_of_columns ) { + dims.resize( nr_of_columns ); + matrix.resize( nr_of_columns ); + } + + // dimension of given index + dimension _get_dim( index idx ) const { + return dims[ idx ]; + } + void _set_dim( index idx, dimension dim ) { + dims[ idx ] = dim; + } + + // replaces(!) content of 'col' with boundary of given index + void _get_col( index idx, column& col ) const { + col.clear(); + col.reserve( matrix[idx].size() ); + std::copy (matrix[idx].begin(), matrix[idx].end(), std::back_inserter(col) ); + } + + void _set_col( index idx, const column& col ) { + matrix[ idx ].clear(); + matrix[ idx ].resize( col.size() ); + std::copy (col.begin(), col.end(), matrix[ idx ].begin() ); + } + + // true iff boundary of given idx is empty + bool _is_empty( index idx ) const { + return matrix[ idx ].empty(); + } + + // largest row index of given column idx (new name for lowestOne()) + index _get_max_index( index idx ) const { + return matrix[ idx ].empty() ? -1 : *matrix[ idx ].rbegin(); + } + + // removes the maximal index of a column + void _remove_max( index idx ) { + internal_column::iterator it = matrix[ idx ].end(); + it--; + matrix[ idx ].erase( it ); + } + + // clears given column + void _clear( index idx ) { + matrix[ idx ].clear(); + } + + // syncronizes all data structures (essential for openmp stuff) + void _sync() {} + + // adds column 'source' to column 'target' + void _add_to( index source, index target ) { + internal_column& source_col = matrix[ source ]; + internal_column& target_col = matrix[ target ]; + internal_column temp_col; + target_col.swap( temp_col ); + std::set_symmetric_difference( temp_col.begin(), temp_col.end(), + source_col.begin(), source_col.end(), + std::back_inserter( target_col ) ); + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h new file mode 100644 index 00000000..dadf1b34 --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h @@ -0,0 +1,100 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include + +namespace phat { + class vector_set { + + protected: + typedef std::set< index > internal_column; + std::vector< dimension > dims; + std::vector< internal_column > matrix; + + public: + // overall number of cells in boundary_matrix + index _get_num_cols() const { + return (index)matrix.size(); + } + void _set_num_cols( index nr_of_columns ) { + dims.resize( nr_of_columns ); + matrix.resize( nr_of_columns ); + } + + // dimension of given index + dimension _get_dim( index idx ) const { + return dims[ idx ]; + } + void _set_dim( index idx, dimension dim ) { + dims[ idx ] = dim; + } + + // replaces(!) content of 'col' with boundary of given index + void _get_col( index idx, column& col ) const { + col.clear(); + col.reserve( matrix[idx].size() ); + std::copy (matrix[idx].begin(), matrix[idx].end(), std::back_inserter(col) ); + } + void _set_col( index idx, const column& col ) { + matrix[ idx ].clear(); + matrix[ idx ].insert( col.begin(), col.end() ); + } + + // true iff boundary of given idx is empty + bool _is_empty( index idx ) const { + return matrix[ idx ].empty(); + } + + // largest row index of given column idx (new name for lowestOne()) + index _get_max_index( index idx ) const { + return matrix[ idx ].empty() ? -1 : *matrix[ idx ].rbegin(); + } + + // removes the maximal index of a column + void _remove_max( index idx ) { + internal_column::iterator it = matrix[ idx ].end(); + it--; + matrix[ idx ].erase( it ); + } + + // clears given column + void _clear( index idx ) { + matrix[ idx ].clear(); + } + + // syncronizes all data structures (essential for openmp stuff) + void _sync() {} + + // adds column 'source' to column 'target' + void _add_to( index source, index target ) { + for( internal_column::iterator it = matrix[ source ].begin(); it != matrix[ source ].end(); it++ ) + _toggle( target, *it ); + } + + //// toggles given index pair + void _toggle( index col_idx, index row_idx ) { + internal_column& col = matrix[ col_idx ]; + std::pair< internal_column::iterator, bool > result = col.insert( row_idx ); + if( !result.second ) { + col.erase( result.first ); + } + } + }; +} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h new file mode 100644 index 00000000..efe8de4d --- /dev/null +++ b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h @@ -0,0 +1,93 @@ +/* Copyright 2013 IST Austria + Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus + + This file is part of PHAT. + + PHAT is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + PHAT 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PHAT. If not, see . */ + +#pragma once + +#include "../helpers/misc.h" + +namespace phat { + class vector_vector { + + protected: + std::vector< dimension > dims; + std::vector< column > matrix; + + thread_local_storage< column > temp_column_buffer; + + public: + // overall number of cells in boundary_matrix + index _get_num_cols() const { + return (index)matrix.size(); + } + void _set_num_cols( index nr_of_columns ) { + dims.resize( nr_of_columns ); + matrix.resize( nr_of_columns ); + } + + // dimension of given index + dimension _get_dim( index idx ) const { + return dims[ idx ]; + } + void _set_dim( index idx, dimension dim ) { + dims[ idx ] = dim; + } + + // replaces(!) content of 'col' with boundary of given index + void _get_col( index idx, column& col ) const { + col = matrix[ idx ]; + } + void _set_col( index idx, const column& col ) { + matrix[ idx ] = col; + } + + // true iff boundary of given idx is empty + bool _is_empty( index idx ) const { + return matrix[ idx ].empty(); + } + + // largest row index of given column idx (new name for lowestOne()) + index _get_max_index( index idx ) const { + return matrix[ idx ].empty() ? -1 : matrix[ idx ].back(); + } + + // removes the maximal index of a column + void _remove_max( index idx ) { + matrix[ idx ].pop_back(); + } + + // clears given column + void _clear( index idx ) { + matrix[ idx ].clear(); + } + + // syncronizes all data structures (essential for openmp stuff) + void _sync() {} + + // adds column 'source' to column 'target' + void _add_to( index source, index target ) { + column& source_col = matrix[ source ]; + column& target_col = matrix[ target ]; + column& temp_col = temp_column_buffer(); + temp_col.clear(); + std::set_symmetric_difference( target_col.begin(), target_col.end(), + source_col.begin(), source_col.end(), + std::back_inserter( temp_col ) ); + target_col.swap( temp_col ); + } + }; +} diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index 4235761f..968483a3 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -310,7 +310,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_1) { dimensions.push_back(3); Bitmap_cubical_complex< Bitmap_cubical_complex_base > increasing(dimensions, increasingFiltrationOfTopDimensionalCells); - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + 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) { BOOST_CHECK(boundaries[i][j] == bd[j]); @@ -423,7 +423,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_2) { coboundaryElements.push_back(41); coboundaryElements.push_back(47); size_t number = 0; - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + for (size_t i = 0; i != increasing.size(); ++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]); @@ -502,7 +502,7 @@ BOOST_AUTO_TEST_CASE(compute_boundary_test_3) { dim.push_back(1); dim.push_back(0); - for (size_t i = 0; i != increasing.size_of_bitmap(); ++i) { + for (size_t i = 0; i != increasing.size(); ++i) { BOOST_CHECK(increasing.get_dimension_of_a_cell(i) == dim[i]); } } @@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(boudary_operator_2d_bitmap_with_periodic_bcond) { boundaries.push_back( boundary14 ); boundaries.push_back( boundary15 ); - for (size_t i = 0; i != cmplx.size_of_bitmap(); ++i) { + 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) { BOOST_CHECK(boundaries[i][j] == bd[j]); @@ -826,7 +826,7 @@ BOOST_AUTO_TEST_CASE(coboudary_operator_2d_bitmap_with_periodic_bcond) { coboundaries.push_back( coboundary14 ); coboundaries.push_back( coboundary15 ); - for (size_t i = 0; i != cmplx.size_of_bitmap(); ++i) { + 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]); @@ -879,7 +879,7 @@ BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { filtration.push_back(3);//15 - for (size_t i = 0; i != cmplx.size_of_bitmap(); ++i) + for (size_t i = 0; i != cmplx.size(); ++i) { BOOST_CHECK( filtration[i] == cmplx.get_cell_data(i) ); } -- cgit v1.2.3 From 904e931e2938ed3a5b526711b073c957b938ae63 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 9 Feb 2016 14:04:23 +0000 Subject: Doxygen fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1009 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 490dcfd0ca24df97b9bf7735fa167ef844d49b71 --- .../doc/Gudhi_Cubical_Complex_doc.h | 11 +- .../include/gudhi/Bitmap_cubical_complex.h | 117 +++++++++++---------- 2 files changed, 68 insertions(+), 60 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 c06678a1..00b39f01 100644 --- a/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h +++ b/src/Bitmap_cubical_complex/doc/Gudhi_Cubical_Complex_doc.h @@ -36,7 +36,7 @@ namespace Cubical_complex * @{ * -*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. +*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 @@ -93,7 +93,7 @@ namespace Cubical_complex 5 \endverbatim -\section Periodic boundary conditions +\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 @@ -106,8 +106,8 @@ in this direction have to be multiplied by -1. For instance: -3 3 1 -2 -3 +4 +6 8 20 4 @@ -118,6 +118,9 @@ in this direction have to be multiplied by -1. For instance: 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 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 82ea8672..b599a0d9 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -23,7 +23,7 @@ #pragma once #include -#include "Bitmap_cubical_complex_base.h" +#include "Bitmap_cubical_complex_base.h" #include "Bitmap_cubical_complex_periodic_boundary_conditions_base.h" @@ -35,10 +35,15 @@ namespace Cubical_complex { //global variable, was used just for debugging. -const bool globalDbg = false; - +const bool globalDbg = false; + template class is_before_in_filtration; +/** + *@class Bitmap_cubical_complex + *@brief Cubical complex represented as a bitmap. + *@ingroup cubical_complex + */ template class Bitmap_cubical_complex : public T { @@ -47,8 +52,8 @@ public: //Typedefs and typenames //*********************************************// typedef size_t Simplex_key; - typedef typename T::filtration_type Filtration_value; - typedef Simplex_key Simplex_handle; + typedef typename T::filtration_type Filtration_value; + typedef Simplex_key Simplex_handle; //*********************************************// @@ -65,7 +70,7 @@ public: **/ 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 ) @@ -75,7 +80,7 @@ public: //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(); + 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; } @@ -97,12 +102,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(); - } - + } + /** * 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. + * 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 ): @@ -117,7 +122,7 @@ 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(); - } + } //*********************************************// @@ -135,10 +140,10 @@ public: * 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(); - } + } /** @@ -184,10 +189,10 @@ public: **/ 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]; + 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(); } @@ -197,10 +202,10 @@ public: **/ 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 ]; + 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(); } @@ -210,8 +215,8 @@ public: **/ 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; + 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; } @@ -231,10 +236,10 @@ public: /** * 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; - + **/ + typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator; + typedef typename std::vector< Simplex_handle > Boundary_simplex_range; + /** @@ -301,8 +306,8 @@ public: { //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; + 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() @@ -328,19 +333,19 @@ public: /** * 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); + **/ + 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); } /** @@ -463,8 +468,8 @@ public: { //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; + 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() @@ -500,28 +505,28 @@ 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 ) { cerr << "void Bitmap_cubical_complex::initialize_elements_ordered_according_to_filtration() \n"; - } - this->simplex_associated_to_key = std::vector( this->data.size() ); + } + 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; + 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 { @@ -560,4 +565,4 @@ protected: } -} +} -- cgit v1.2.3 From 81d5f63b5107dd8229fd8b8576982d22acb9a57e Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 9 Feb 2016 14:35:03 +0000 Subject: Adding documentation to the bitmap cubical complex with periodic boundary conditions class. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1010 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e1d9516f57be5e824203037b74998ed897741261 --- .../include/gudhi/Bitmap_cubical_complex.h | 7 +- ...cal_complex_periodic_boundary_conditions_base.h | 666 +++++++++++---------- 2 files changed, 361 insertions(+), 312 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 b599a0d9..2ec7594d 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -37,7 +37,12 @@ namespace Cubical_complex //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 +* 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. +**/ /** *@class Bitmap_cubical_complex 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 38c218dc..f0fd785f 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 @@ -1,311 +1,355 @@ -#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 - -template -class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_cubical_complex_base -{ -public: - //constructors that take an extra parameter: - Bitmap_cubical_complex_periodic_boundary_conditions_base(){}; - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( const char* perseusStyleFile ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells , std::vector< bool > directions_in_which_periodic_b_cond_are_to_be_imposed ); - - //overwritten methods co compute boundary and coboundary - virtual std::vector< size_t > get_boundary_of_a_cell( size_t cell )const; - std::vector< size_t > get_coboundary_of_a_cell( size_t cell )const; - //inline unsigned get_dimension_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( std::vector sizes ); - Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector dimensions , std::vector topDimensionalCells ); - void construct_complex_based_on_top_dimensional_cells( std::vector dimensions , std::vector topDimensionalCells , 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( std::vector dimensions , std::vector topDimensionalCells , 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) - { - *it = topDimensionalCells[i]; - ++i; - } - this->impose_lower_star_filtration(); -} - -template -Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_complex_periodic_boundary_conditions_base( std::vector sizes , 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_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; - } - *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_begin() ; it != this->top_dimensional_cells_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( 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( std::vector dimensions , 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( std::vector dimensions , std::vector topDimensionalCells , 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 +/* 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" + +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 + + +/** +* 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 ); + + //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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + { + *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_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; + } + *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_begin() ; it != this->top_dimensional_cells_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 -- cgit v1.2.3 From 1ed10d89ae07c069cf408de2e178962f23723c8b Mon Sep 17 00:00:00 2001 From: pdlotko Date: Sat, 13 Feb 2016 12:21:41 +0000 Subject: removing phat relaed compontns. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1021 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d0c9c23ca3f3a5b2131179949ba80659b13f7777 --- .../example/Compute_persistence_with_phat.cpp | 60 ---- .../include/gudhi/Compute_persistence_with_phat.h | 242 --------------- .../gudhi/phat/algorithms/chunk_reduction.h | 240 --------------- .../include/gudhi/phat/algorithms/row_reduction.h | 55 ---- .../gudhi/phat/algorithms/standard_reduction.h | 45 --- .../gudhi/phat/algorithms/twist_reduction.h | 50 --- .../include/gudhi/phat/boundary_matrix.h | 336 --------------------- .../include/gudhi/phat/compute_persistence_pairs.h | 69 ----- .../include/gudhi/phat/helpers/dualize.h | 63 ---- .../include/gudhi/phat/helpers/misc.h | 74 ----- .../gudhi/phat/helpers/thread_local_storage.h | 52 ---- .../include/gudhi/phat/persistence_pairs.h | 151 --------- .../phat/representations/abstract_pivot_column.h | 158 ---------- .../phat/representations/bit_tree_pivot_column.h | 169 ----------- .../gudhi/phat/representations/full_pivot_column.h | 81 ----- .../phat/representations/sparse_pivot_column.h | 62 ---- .../gudhi/phat/representations/vector_list.h | 98 ------ .../gudhi/phat/representations/vector_set.h | 100 ------ .../gudhi/phat/representations/vector_vector.h | 93 ------ 19 files changed, 2198 deletions(-) delete mode 100644 src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h delete mode 100644 src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h (limited to 'src/Bitmap_cubical_complex') diff --git a/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp b/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp deleted file mode 100644 index f552a094..00000000 --- a/src/Bitmap_cubical_complex/example/Compute_persistence_with_phat.cpp +++ /dev/null @@ -1,60 +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 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 -#include - -using namespace Gudhi; -using namespace Gudhi::Cubical_complex; - -//standard stuff -#include -#include -#include - -using namespace std; - - -int main( int argc , char** argv ) -{ - 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] ); - cerr << "Cubical complex created \n"; - - - Compute_persistence_with_phat< Bitmap_cubical_complex< Bitmap_cubical_complex_base > , double > phat(&b); - phat::persistence_pairs pairs = phat.compute_persistence_pairs_standard_reduction(); - std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > persistence = phat.get_the_intervals( pairs ); - writeBettiNumbersAndPersistenceIntervalsToFile( "phat_persistence" , persistence ); - - return 0; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h b/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h deleted file mode 100644 index 9f4ada45..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/Compute_persistence_with_phat.h +++ /dev/null @@ -1,242 +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 "phat/compute_persistence_pairs.h" -#include "phat/representations/vector_vector.h" -#include "phat/algorithms/standard_reduction.h" -#include "phat/algorithms/chunk_reduction.h" -#include "phat/algorithms/row_reduction.h" -#include "phat/algorithms/twist_reduction.h" - - -namespace Gudhi -{ - - -//the only aim of this class is to have a ability to compute persistence with phat. -template -void writeBettiNumbersAndPersistenceIntervalsToFile( char* prefix , std::pair< std::vector > , std::vector< std::vector< std::pair > > > resutsFromPhat ) -{ - std::ostringstream filenameStr; - filenameStr << prefix << "_bettiNumbers"; - std::string str = filenameStr.str(); - const char* filename = str.c_str(); - ofstream out; - out.open( filename ); - for ( size_t dim = 0 ; dim != resutsFromPhat.first.size() ; ++dim ) - { - out << "Dimension : " << dim << endl; - for ( size_t i = 0 ; i != resutsFromPhat.first[dim].size() ; ++i ) - { - out << resutsFromPhat.first[dim][i] << endl; - } - out << endl; - } - out.close(); - - - cerr << "Write persistence to file \n"; - for ( size_t dim = 0 ; dim != resutsFromPhat.second.size() ; ++dim ) - { - cerr << "resutsFromPhat.second[dim].size() : " << resutsFromPhat.second[dim].size() << endl; - if ( resutsFromPhat.second[dim].size() == 0 )continue; - std::ostringstream filenameStr; - filenameStr << prefix << "_persistence_" << dim; - std::string str = filenameStr.str(); - const char* filename = str.c_str(); - ofstream out1; - out1.open( filename ); - for ( size_t i = 0 ; i != resutsFromPhat.second[dim].size() ; ++i ) - { - out1 << resutsFromPhat.second[dim][i].first << " " << resutsFromPhat.second[dim][i].second << endl; - } - out1.close(); - } -}//writeBettiNumbersAndPersistenceIntervalsToFile - - -template -class Compute_persistence_with_phat -{ -public: - Compute_persistence_with_phat( T* data_structure_ ); - std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > get_the_intervals( phat::persistence_pairs pairs ); - - phat::persistence_pairs compute_persistence_pairs_dualized_chunk_reduction(); - phat::persistence_pairs compute_persistence_pairs_twist_reduction(); - phat::persistence_pairs compute_persistence_pairs_standard_reduction(); - //phat::persistence_pairs compute_persistence_pairs_spectral_sequence_reduction(); -private: - void print_bd_matrix(); - phat::boundary_matrix< phat::vector_vector > boundary_matrix; - T* data_structure; -}; - -template -void Compute_persistence_with_phat::print_bd_matrix() -{ - std::cout << "The boundary matrix has " << this->boundary_matrix.get_num_cols() << " columns: " << std::endl; - for( phat::index col_idx = 0; col_idx < this->boundary_matrix.get_num_cols(); col_idx++ ) { - std::cout << "Colum " << col_idx << " represents a cell of dimension " << (int)this->boundary_matrix.get_dim( col_idx ) << ". "; - if( !this->boundary_matrix.is_empty( col_idx ) ) { - std::vector< phat::index > temp_col; - this->boundary_matrix.get_col( col_idx, temp_col ); - std::cout << "Its boundary consists of the cells"; - for( phat::index idx = 0; idx < (phat::index)temp_col.size(); idx++ ) - std::cout << " " << temp_col[ idx ]; - } - std::cout << std::endl; - } -} - -template -phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_dualized_chunk_reduction() -{ - phat::persistence_pairs pairs; - phat::compute_persistence_pairs_dualized< phat::chunk_reduction >( pairs, this->boundary_matrix ); - return pairs; -} - -template -phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_twist_reduction() -{ - phat::persistence_pairs pairs; - phat::compute_persistence_pairs< phat::twist_reduction >( pairs, this->boundary_matrix ); - return pairs; -} - -template -phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_standard_reduction() -{ - phat::persistence_pairs pairs; - phat::compute_persistence_pairs< phat::standard_reduction >( pairs, this->boundary_matrix ); - return pairs; -} - -//template -//phat::persistence_pairs Compute_persistence_with_phat::compute_persistence_pairs_spectral_sequence_reduction() -//{ -// phat::persistence_pairs pairs; -// phat::compute_persistence_pairs< phat::spectral_sequence_reduction >( pairs, this->boundary_matrix ); -// return pairs; -//} - -template -Compute_persistence_with_phat::Compute_persistence_with_phat( T* data_structure_ ):data_structure( data_structure_ ) -{ - bool dbg = false; - this->boundary_matrix.set_num_cols( this->data_structure->num_simplices() ); - - //setting up the dimensions of cells: - for ( size_t i = 0 ; i != this->data_structure->num_simplices() ; ++i ) - { - this->boundary_matrix.set_dim( i, this->data_structure->dimension( this->data_structure->simplex(i) ) ); - } - - - //now it is time to set up the boundary matrix: - typename T::Filtration_simplex_range range = this->data_structure->filtration_simplex_range(); - std::vector< phat::index > temp_col; - for ( typename T::Filtration_simplex_iterator it = range.begin() ; it != range.end() ; ++it ) - { - typename T::Boundary_simplex_range boundary_range = this->data_structure->boundary_simplex_range( *it ); - for ( typename T::Boundary_simplex_iterator bd = boundary_range.begin() ; bd != boundary_range.end() ; ++bd ) - { - temp_col.push_back( this->data_structure->key( *bd ) ); - } - //we do not know if the boundary elements are sorted according to filtration, that is why I am enforcing it here: - this->boundary_matrix.set_col( this->data_structure->key( *it ) , temp_col ); - temp_col.clear(); - } -} - -template -std::pair< std::vector< std::vector > , std::vector< std::vector< std::pair > > > Compute_persistence_with_phat::get_the_intervals( phat::persistence_pairs pairs ) -{ - bool dbg = false; - //in order to find the birth times of the infinite homology classes, we need to know which elements are not paired. To search for them, we will use this vector: - std::vector isTheElementPaired( this->data_structure->num_simplices() , false ); - - //now it is time to recover the finite persistence pairs and the Betti numbers: - std::vector< std::vector< std::pair > > finitePersistencePairs( this->data_structure->dimension() ); - for( phat::index idx = 0; idx < pairs.get_num_pairs(); idx++ ) - { - typename T::Simplex_key positionOfBeginOfInterval = pairs.get_pair( idx ).first; - typename T::Simplex_key positionOfEndOfInterval = pairs.get_pair( idx ).second; - - typename T::Simplex_handle first_simplex = this->data_structure->simplex(positionOfBeginOfInterval); - typename T::Simplex_handle second_simplex = this->data_structure->simplex(positionOfEndOfInterval); - - typename T::Filtration_value valueFirst = this->data_structure->filtration( first_simplex ); - typename T::Filtration_value valueSecond = this->data_structure->filtration( second_simplex ); - - if ( valueFirst > valueSecond ){std::swap( valueFirst , valueSecond );} - - unsigned dimFirst = this->data_structure->dimension(first_simplex); - unsigned dimSecond = this->data_structure->dimension(second_simplex); - unsigned dim = std::min( dimFirst , dimSecond ); - - - //we are ignoring trivial barcodes - if ( valueFirst != valueSecond ) - { - finitePersistencePairs[ dim ].push_back( std::make_pair(valueFirst , valueSecond) ); - if ( dbg ){cerr << "Adding barcode : " << valueFirst << "," << valueSecond << endl;} - } - - //isTheElementPaired[ positionOfBeginOfIntervalInBitmap ] = true; - //isTheElementPaired[ positionOfEndOfIntervalInBitmap ] = true; - isTheElementPaired[ pairs.get_pair( idx ).first ] = true; - isTheElementPaired[ pairs.get_pair( idx ).second ] = true; - } - - - std::vector< std::vector > birthTimesOfInfinitePersistnceClasses(this->data_structure->dimension()+1 ); - for ( size_t i = 0 ; i != this->data_structure->dimension()+1 ; ++i ) - { - std::vector v; - birthTimesOfInfinitePersistnceClasses[i] = v; - } - for ( size_t i = 0 ; i != isTheElementPaired.size() ; ++i ) - { - if ( isTheElementPaired[i] == false ) - { - //i-th element is not paired, therefore it gives an infinite class - typename T::Simplex_handle simplex = this->data_structure->simplex(i); - birthTimesOfInfinitePersistnceClasses[ this->data_structure->dimension( simplex ) ].push_back( this->data_structure->filtration(simplex) ); - } - } - - //sorting finite persistence pairs: - for ( size_t dim = 0 ; dim != finitePersistencePairs.size() ; ++dim ) - { - std::sort( finitePersistencePairs[dim].begin() , finitePersistencePairs[dim].end() ); - } - return std::make_pair( birthTimesOfInfinitePersistnceClasses , finitePersistencePairs ); -}//Compute_persistence_with_phat - - - -}//namespace Gudhi diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h deleted file mode 100644 index 352392a8..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/chunk_reduction.h +++ /dev/null @@ -1,240 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../boundary_matrix.h" - -namespace phat { - class chunk_reduction { - public: - enum column_type { GLOBAL - , LOCAL_POSITIVE - , LOCAL_NEGATIVE }; - - public: - template< typename Representation > - void operator() ( boundary_matrix< Representation >& boundary_matrix ) { - - const index nr_columns = boundary_matrix.get_num_cols(); - const dimension max_dim = boundary_matrix.get_max_dim(); - - std::vector< index > lowest_one_lookup( nr_columns, -1 ); - std::vector < column_type > column_type( nr_columns, GLOBAL ); - std::vector< char > is_active( nr_columns, false ); - - std::vector chunk_boundaries; - _get_chunks( boundary_matrix, chunk_boundaries ); - - // Phase 1: Reduce chunks locally -- 1st pass - #pragma omp parallel for schedule( guided, 1 ) - for( index chunk_id = 0; chunk_id < (index) chunk_boundaries.size() - 2; chunk_id += 2 ) - _local_chunk_reduction( boundary_matrix, lowest_one_lookup, column_type, max_dim, - chunk_boundaries[chunk_id], chunk_boundaries[chunk_id+2] - 1 ); - boundary_matrix.sync(); - - // Phase 1: Reduce chunks locally -- 2nd pass - #pragma omp parallel for schedule( guided, 1 ) - for( index chunk_id = 1; chunk_id < (index) chunk_boundaries.size() - 2; chunk_id += 2 ) - _local_chunk_reduction( boundary_matrix, lowest_one_lookup, column_type, max_dim, - chunk_boundaries[chunk_id], chunk_boundaries[chunk_id+2] - 1 ); - boundary_matrix.sync(); - - // get global columns - std::vector< index > global_columns; - for( index cur_col_idx = 0; cur_col_idx < nr_columns; cur_col_idx++ ) - if( column_type[ cur_col_idx ] == GLOBAL ) - global_columns.push_back( cur_col_idx ); - - // get active columns - #pragma omp parallel for - for( index idx = 0; idx < (index)global_columns.size(); idx++ ) - is_active[ global_columns[ idx ] ] = true; - _get_active_columns( boundary_matrix, lowest_one_lookup, column_type, global_columns, is_active ); - - // Phase 2+3: Simplify columns and reduce them - for( dimension cur_dim = max_dim; cur_dim >= 1; cur_dim-- ) { - // Phase 2: Simplify columns - std::vector< index > temp_col; - #pragma omp parallel for schedule( guided, 1 ), private( temp_col ) - for( index idx = 0; idx < (index)global_columns.size(); idx++ ) - if( boundary_matrix.get_dim( global_columns[ idx ] ) == cur_dim ) - _global_column_simplification( global_columns[ idx ], boundary_matrix, lowest_one_lookup, column_type, is_active, temp_col ); - boundary_matrix.sync(); - - // Phase 3: Reduce columns - for( index idx = 0; idx < (index)global_columns.size(); idx++ ) { - index cur_col = global_columns[ idx ]; - if( boundary_matrix.get_dim( cur_col ) == cur_dim && column_type[ cur_col ] == GLOBAL ) { - index lowest_one = boundary_matrix.get_max_index( cur_col ); - while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { - boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); - lowest_one = boundary_matrix.get_max_index( cur_col ); - } - if( lowest_one != -1 ) { - lowest_one_lookup[ lowest_one ] = cur_col; - boundary_matrix.clear( lowest_one ); - } - } - } - } - - boundary_matrix.sync(); - } - - protected: - template< typename Representation > - void _get_chunks( const boundary_matrix< Representation >& boundary_matrix - , std::vector< index >& chunk_boundaries) - { - chunk_boundaries.clear(); - std::vector temp_chunk_boundaries; - const index nr_columns = boundary_matrix.get_num_cols(); - - // size of chuks = sqrt(N) - const index chunk_size = (index) sqrt( (float)nr_columns ); - - // size of chunks = N / num_threads - //const index chunk_size = nr_columns / omp_get_max_threads(); - - for ( index cur_col = 0; cur_col < nr_columns; cur_col++ ) - if( cur_col % chunk_size == 0 ) - temp_chunk_boundaries.push_back( cur_col ); - temp_chunk_boundaries.push_back( nr_columns ); - - // subdivide chunks for interleaved 2 pass appraoch - for( index chunk_id = 0; chunk_id < (index) temp_chunk_boundaries.size(); chunk_id ++ ) { - chunk_boundaries.push_back( temp_chunk_boundaries[ chunk_id ] ); - if( chunk_id < (index) temp_chunk_boundaries.size() - 1 ) { - index midPoint = ( temp_chunk_boundaries[ chunk_id ] + temp_chunk_boundaries[ chunk_id + 1 ] ) / 2; - chunk_boundaries.push_back( midPoint ); - } - } - } - - template< typename Representation > - void _local_chunk_reduction( boundary_matrix< Representation >& boundary_matrix - , std::vector& lowest_one_lookup - , std::vector< column_type >& column_type - , const dimension max_dim - , const index chunk_begin - , const index chunk_end ) { - for( dimension cur_dim = max_dim; cur_dim >= 1; cur_dim-- ) { - for( index cur_col = chunk_begin; cur_col <= chunk_end; cur_col++ ) { - if( column_type[ cur_col ] == GLOBAL && boundary_matrix.get_dim( cur_col ) == cur_dim ) { - index lowest_one = boundary_matrix.get_max_index( cur_col ); - while( lowest_one != -1 && lowest_one >= chunk_begin && lowest_one_lookup[ lowest_one ] != -1 ) { - boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); - lowest_one = boundary_matrix.get_max_index( cur_col ); - } - if( lowest_one >= chunk_begin ) { - lowest_one_lookup[ lowest_one ] = cur_col; - column_type[ cur_col ] = LOCAL_NEGATIVE; - column_type[ lowest_one ] = LOCAL_POSITIVE; - boundary_matrix.clear( lowest_one ); - } - } - } - } - } - - template< typename Representation > - void _get_active_columns( const boundary_matrix< Representation >& boundary_matrix - , const std::vector< index >& lowest_one_lookup - , const std::vector< column_type >& column_type - , const std::vector< index >& global_columns - , std::vector< char >& is_active ) { - - const index nr_columns = boundary_matrix.get_num_cols(); - std::vector< char > finished( nr_columns, false ); - - std::vector< std::pair < index, index > > stack; - std::vector< index > cur_col_values; - #pragma omp parallel for schedule( guided, 1 ), private( stack, cur_col_values ) - for( index idx = 0; idx < (index)global_columns.size(); idx++ ) { - bool pop_next = false; - index start_col = global_columns[ idx ]; - stack.push_back( std::pair< index, index >( start_col, -1 ) ); - while( !stack.empty() ) { - index cur_col = stack.back().first; - index prev_col = stack.back().second; - if( pop_next ) { - stack.pop_back(); - pop_next = false; - if( prev_col != -1 ) { - if( is_active[ cur_col ] ) { - is_active[ prev_col ] = true; - } - if( prev_col == stack.back().first ) { - finished[ prev_col ] = true; - pop_next = true; - } - } - } else { - pop_next = true; - boundary_matrix.get_col( cur_col, cur_col_values ); - for( index idx = 0; idx < (index) cur_col_values.size(); idx++ ) { - index cur_row = cur_col_values[ idx ]; - if( ( column_type[ cur_row ] == GLOBAL ) ) { - is_active[ cur_col ] = true; - } else if( column_type[ cur_row ] == LOCAL_POSITIVE ) { - index next_col = lowest_one_lookup[ cur_row ]; - if( next_col != cur_col && !finished[ cur_col ] ) { - stack.push_back( std::make_pair( next_col, cur_col ) ); - pop_next = false; - } - } - } - } - } - } - } - - template< typename Representation > - void _global_column_simplification( const index col_idx - , boundary_matrix< Representation >& boundary_matrix - , const std::vector< index >& lowest_one_lookup - , const std::vector< column_type >& column_type - , const std::vector< char >& is_active - , std::vector< index >& temp_col ) - { - temp_col.clear(); - while( !boundary_matrix.is_empty( col_idx ) ) { - index cur_row = boundary_matrix.get_max_index( col_idx ); - switch( column_type[ cur_row ] ) { - case GLOBAL: - temp_col.push_back( cur_row ); - boundary_matrix.remove_max( col_idx ); - break; - case LOCAL_NEGATIVE: - boundary_matrix.remove_max( col_idx ); - break; - case LOCAL_POSITIVE: - if( is_active[ lowest_one_lookup[ cur_row ] ] ) - boundary_matrix.add_to( lowest_one_lookup[ cur_row ], col_idx ); - else - boundary_matrix.remove_max( col_idx ); - break; - } - } - std::reverse( temp_col.begin(), temp_col.end() ); - boundary_matrix.set_col( col_idx, temp_col ); - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h deleted file mode 100644 index 2047cafd..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/row_reduction.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../boundary_matrix.h" - -namespace phat { - class row_reduction { - public: - template< typename Representation > - void operator() ( boundary_matrix< Representation >& boundary_matrix ) { - - const index nr_columns = boundary_matrix.get_num_cols(); - std::vector< std::vector< index > > lowest_one_lookup( nr_columns ); - - for( index cur_col = nr_columns - 1; cur_col >= 0; cur_col-- ) { - if( !boundary_matrix.is_empty( cur_col ) ) - lowest_one_lookup[ boundary_matrix.get_max_index( cur_col ) ].push_back( cur_col ); - - if( !lowest_one_lookup[ cur_col ].empty() ) { - boundary_matrix.clear( cur_col ); - std::vector< index >& cols_with_cur_lowest = lowest_one_lookup[ cur_col ]; - index source = *min_element( cols_with_cur_lowest.begin(), cols_with_cur_lowest.end() ); - for( index idx = 0; idx < (index)cols_with_cur_lowest.size(); idx++ ) { - index target = cols_with_cur_lowest[ idx ]; - if( target != source && !boundary_matrix.is_empty( target ) ) { - boundary_matrix.add_to( source, target ); - if( !boundary_matrix.is_empty( target ) ) { - index lowest_one_of_target = boundary_matrix.get_max_index( target ); - lowest_one_lookup[ lowest_one_of_target ].push_back( target ); - } - } - } - } - } - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h deleted file mode 100644 index b2c91a85..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/standard_reduction.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../boundary_matrix.h" - -namespace phat { - class standard_reduction { - public: - template< typename Representation > - void operator() ( boundary_matrix< Representation >& boundary_matrix ) { - - const index nr_columns = boundary_matrix.get_num_cols(); - std::vector< index > lowest_one_lookup( nr_columns, -1 ); - - for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { - index lowest_one = boundary_matrix.get_max_index( cur_col ); - while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { - boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); - lowest_one = boundary_matrix.get_max_index( cur_col ); - } - if( lowest_one != -1 ) { - lowest_one_lookup[ lowest_one ] = cur_col; - } - } - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h b/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h deleted file mode 100644 index 1bdd8de2..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/algorithms/twist_reduction.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../boundary_matrix.h" - -namespace phat { - class twist_reduction { - public: - template< typename Representation > - void operator () ( boundary_matrix< Representation >& boundary_matrix ) { - - const index nr_columns = boundary_matrix.get_num_cols(); - std::vector< index > lowest_one_lookup( nr_columns, -1 ); - - for( index cur_dim = boundary_matrix.get_max_dim(); cur_dim >= 1 ; cur_dim-- ) { - for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { - if( boundary_matrix.get_dim( cur_col ) == cur_dim ) { - index lowest_one = boundary_matrix.get_max_index( cur_col ); - while( lowest_one != -1 && lowest_one_lookup[ lowest_one ] != -1 ) { - boundary_matrix.add_to( lowest_one_lookup[ lowest_one ], cur_col ); - lowest_one = boundary_matrix.get_max_index( cur_col ); - } - if( lowest_one != -1 ) { - lowest_one_lookup[ lowest_one ] = cur_col; - boundary_matrix.clear( lowest_one ); - } - } - } - } - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h b/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h deleted file mode 100644 index 941537da..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/boundary_matrix.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "helpers/misc.h" -#include "representations/bit_tree_pivot_column.h" - -// interface class for the main data structure -- implementations of the interface can be found in ./representations -namespace phat { - template< class Representation = bit_tree_pivot_column > - class boundary_matrix - { - - protected: - Representation rep; - - // interface functions -- actual implementation and complexity depends on chosen @Representation template - public: - // get overall number of columns in boundary_matrix - index get_num_cols() const { return rep._get_num_cols(); } - - // set overall number of columns in boundary_matrix - void set_num_cols( index nr_of_columns ) { rep._set_num_cols( nr_of_columns ); } - - // get dimension of given index - dimension get_dim( index idx ) const { return rep._get_dim( idx ); } - - // set dimension of given index - void set_dim( index idx, dimension dim ) { rep._set_dim( idx, dim ); } - - // replaces content of @col with boundary of given index - void get_col( index idx, column& col ) const { rep._get_col( idx, col ); } - - // set column @idx to the values contained in @col - void set_col( index idx, const column& col ) { rep._set_col( idx, col ); } - - // true iff boundary of given column is empty - bool is_empty( index idx ) const { return rep._is_empty( idx ); } - - // largest index of given column (new name for lowestOne()) - index get_max_index( index idx ) const { return rep._get_max_index( idx ); } - - // removes maximal index from given column - void remove_max( index idx ) { rep._remove_max( idx ); } - - // adds column @source to column @target' - void add_to( index source, index target ) { rep._add_to( source, target ); } - - // clears given column - void clear( index idx ) { rep._clear( idx ); } - - // syncronizes all internal data structures -- has to be called before and after any multithreaded access! - void sync() { rep._sync(); } - - // info functions -- independent of chosen 'Representation' - public: - // maximal dimension - dimension get_max_dim() const { - dimension cur_max_dim = 0; - for( index idx = 0; idx < get_num_cols(); idx++ ) - cur_max_dim = get_dim( idx ) > cur_max_dim ? get_dim( idx ) : cur_max_dim; - return cur_max_dim; - } - - // number of nonzero rows for given column @idx - index get_num_rows( index idx ) const { - column cur_col; - get_col( idx, cur_col ); - return cur_col.size(); - } - - // maximal number of nonzero rows of all columns - index get_max_col_entries() const { - index max_col_entries = -1; - const index nr_of_columns = get_num_cols(); - for( index idx = 0; idx < nr_of_columns; idx++ ) - max_col_entries = get_num_rows( idx ) > max_col_entries ? get_num_rows( idx ) : max_col_entries; - return max_col_entries; - } - - // maximal number of nonzero cols of all rows - index get_max_row_entries() const { - size_t max_row_entries = 0; - const index nr_of_columns = get_num_cols(); - std::vector< std::vector< index > > transposed_matrix( nr_of_columns ); - column temp_col; - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - get_col( cur_col, temp_col ); - for( index idx = 0; idx < (index)temp_col.size(); idx++) - transposed_matrix[ temp_col[ idx ] ].push_back( cur_col ); - } - for( index idx = 0; idx < nr_of_columns; idx++ ) - max_row_entries = transposed_matrix[ idx ].size() > max_row_entries ? transposed_matrix[ idx ].size() : max_row_entries; - return max_row_entries; - } - - // overall number of entries in the matrix - index get_num_entries() const { - index number_of_nonzero_entries = 0; - const index nr_of_columns = get_num_cols(); - for( index idx = 0; idx < nr_of_columns; idx++ ) - number_of_nonzero_entries += get_num_rows( idx ); - return number_of_nonzero_entries; - } - - // operators / constructors - public: - boundary_matrix() {}; - - template< class OtherRepresentation > - boundary_matrix( const boundary_matrix< OtherRepresentation >& other ) { - *this = other; - } - - template< typename OtherRepresentation > - bool operator==( const boundary_matrix< OtherRepresentation >& other_boundary_matrix ) const { - const index number_of_columns = this->get_num_cols(); - - if( number_of_columns != other_boundary_matrix.get_num_cols() ) - return false; - - column temp_col; - column other_temp_col; - for( index idx = 0; idx < number_of_columns; idx++ ) { - this->get_col( idx, temp_col ); - other_boundary_matrix.get_col( idx, other_temp_col ); - if( temp_col != other_temp_col || this->get_dim( idx ) != other_boundary_matrix.get_dim( idx ) ) - return false; - } - return true; - } - - template< typename OtherRepresentation > - bool operator!=( const boundary_matrix< OtherRepresentation >& other_boundary_matrix ) const { - return !( *this == other_boundary_matrix ); - } - - template< typename OtherRepresentation > - boundary_matrix< Representation >& operator=( const boundary_matrix< OtherRepresentation >& other ) - { - const index nr_of_columns = other.get_num_cols(); - this->set_num_cols( nr_of_columns ); - column temp_col; - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - this->set_dim( cur_col, other.get_dim( cur_col ) ); - other.get_col( cur_col, temp_col ); - this->set_col( cur_col, temp_col ); - } - - // by convention, always return *this - return *this; - } - - // I/O -- independent of chosen 'Representation' - public: - - // initializes boundary_matrix from (vector, vector) pair -- untested - template< typename index_type, typename dimemsion_type > - void load_vector_vector( const std::vector< std::vector< index_type > >& input_matrix, const std::vector< dimemsion_type >& input_dims ) { - const index nr_of_columns = (index)input_matrix.size(); - this->set_num_cols( nr_of_columns ); - column temp_col; - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - this->set_dim( cur_col, (dimension)input_dims[ cur_col ] ); - - index num_rows = input_matrix[ cur_col ].size(); - temp_col.resize( num_rows ); - for( index cur_row = 0; cur_row < num_rows; cur_row++ ) - temp_col[ cur_row ] = (index)input_matrix[ cur_col ][ cur_row ]; - this->set_col( cur_col, temp_col ); - } - } - - template< typename index_type, typename dimemsion_type > - void save_vector_vector( std::vector< std::vector< index_type > >& output_matrix, std::vector< dimemsion_type >& output_dims ) { - const index nr_of_columns = get_num_cols(); - output_matrix.resize( nr_of_columns ); - output_dims.resize( nr_of_columns ); - column temp_col; - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - output_dims[ cur_col ] = (dimemsion_type)get_dim( cur_col ); - get_col( cur_col, temp_col ); - index num_rows = temp_col.size(); - output_matrix[ cur_col ].clear(); - output_matrix[ cur_col ].resize( num_rows ); - for( index cur_row = 0; cur_row < num_rows; cur_row++ ) - output_matrix[ cur_col ][ cur_row ] = (index_type)temp_col[ cur_row ]; - } - } - - // Loads the boundary_matrix from given file in ascii format - // Format: each line represents a column, first number is dimension, other numbers are the content of the column. - // Ignores empty lines and lines starting with a '#'. - bool load_ascii( std::string filename ) { - // first count number of columns: - std::string cur_line; - std::ifstream dummy( filename .c_str() ); - if( dummy.fail() ) - return false; - - index number_of_columns = 0; - while( getline( dummy, cur_line ) ) { - cur_line.erase(cur_line.find_last_not_of(" \t\n\r\f\v") + 1); - if( cur_line != "" && cur_line[ 0 ] != '#' ) - number_of_columns++; - - } - this->set_num_cols( number_of_columns ); - dummy.close(); - - std::ifstream input_stream( filename.c_str() ); - if( input_stream.fail() ) - return false; - - column temp_col; - index cur_col = -1; - while( getline( input_stream, cur_line ) ) { - cur_line.erase(cur_line.find_last_not_of(" \t\n\r\f\v") + 1); - if( cur_line != "" && cur_line[ 0 ] != '#' ) { - cur_col++; - std::stringstream ss( cur_line ); - - int64_t temp_dim; - ss >> temp_dim; - this->set_dim( cur_col, (dimension) temp_dim ); - - int64_t temp_index; - temp_col.clear(); - while( ss.good() ) { - ss >> temp_index; - temp_col.push_back( (index)temp_index ); - } - std::sort( temp_col.begin(), temp_col.end() ); - this->set_col( cur_col, temp_col ); - } - } - - input_stream.close(); - return true; - } - - // Saves the boundary_matrix to given file in ascii format - // Format: each line represents a column, first number is dimension, other numbers are the content of the column - bool save_ascii( std::string filename ) { - std::ofstream output_stream( filename.c_str() ); - if( output_stream.fail() ) - return false; - - const index nr_columns = this->get_num_cols(); - column tempCol; - for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { - output_stream << (int64_t)this->get_dim( cur_col ); - this->get_col( cur_col, tempCol ); - for( index cur_row_idx = 0; cur_row_idx < (index)tempCol.size(); cur_row_idx++ ) - output_stream << " " << tempCol[ cur_row_idx ]; - output_stream << std::endl; - } - - output_stream.close(); - return true; - } - - // Loads boundary_matrix from given file - // Format: nr_columns % dim1 % N1 % row1 row2 % ...% rowN1 % dim2 % N2 % ... - bool load_binary( std::string filename ) { - std::ifstream input_stream( filename.c_str(), std::ios_base::binary | std::ios_base::in ); - if( input_stream.fail() ) - return false; - - int64_t nr_columns; - input_stream.read( (char*)&nr_columns, sizeof( int64_t ) ); - this->set_num_cols( (index)nr_columns ); - - column temp_col; - for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { - int64_t cur_dim; - input_stream.read( (char*)&cur_dim, sizeof( int64_t ) ); - this->set_dim( cur_col, (dimension) cur_dim ); - int64_t nr_rows; - input_stream.read( (char*)&nr_rows, sizeof( int64_t ) ); - temp_col.resize( (std::size_t)nr_rows ); - for( index idx = 0; idx < nr_rows; idx++ ) { - int64_t cur_row; - input_stream.read( (char*)&cur_row, sizeof( int64_t ) ); - temp_col[ idx ] = (index)cur_row; - } - this->set_col( cur_col, temp_col ); - } - - input_stream.close(); - return true; - } - - // Saves the boundary_matrix to given file in binary format - // Format: nr_columns % dim1 % N1 % row1 row2 % ...% rowN1 % dim2 % N2 % ... - bool save_binary( std::string filename ) { - std::ofstream output_stream( filename.c_str(), std::ios_base::binary | std::ios_base::out ); - if( output_stream.fail() ) - return false; - - const int64_t nr_columns = this->get_num_cols(); - output_stream.write( (char*)&nr_columns, sizeof( int64_t ) ); - column tempCol; - for( index cur_col = 0; cur_col < nr_columns; cur_col++ ) { - int64_t cur_dim = this->get_dim( cur_col ); - output_stream.write( (char*)&cur_dim, sizeof( int64_t ) ); - this->get_col( cur_col, tempCol ); - int64_t cur_nr_rows = tempCol.size(); - output_stream.write( (char*)&cur_nr_rows, sizeof( int64_t ) ); - for( index cur_row_idx = 0; cur_row_idx < (index)tempCol.size(); cur_row_idx++ ) { - int64_t cur_row = tempCol[ cur_row_idx ]; - output_stream.write( (char*)&cur_row, sizeof( int64_t ) ); - } - } - - output_stream.close(); - return true; - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h b/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h deleted file mode 100644 index f5b04d5a..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/compute_persistence_pairs.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "persistence_pairs.h" -#include "boundary_matrix.h" -#include "helpers/dualize.h" -#include "algorithms/twist_reduction.h" - -namespace phat { - - template< typename ReductionAlgorithm, typename Representation > - void compute_persistence_pairs( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { - ReductionAlgorithm reduce; - reduce( boundary_matrix ); - pairs.clear(); - for( index idx = 0; idx < boundary_matrix.get_num_cols(); idx++ ) { - if( !boundary_matrix.is_empty( idx ) ) { - index birth = boundary_matrix.get_max_index( idx ); - index death = idx; - pairs.append_pair( birth, death ); - } - } - } - - template< typename ReductionAlgorithm, typename Representation > - void compute_persistence_pairs_dualized( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { - ReductionAlgorithm reduce; - const index nr_columns = boundary_matrix.get_num_cols(); - dualize( boundary_matrix ); - reduce( boundary_matrix ); - pairs.clear(); - for( index idx = 0; idx < nr_columns; idx++ ) { - if( !boundary_matrix.is_empty( idx ) ) { - index death = nr_columns - 1 - boundary_matrix.get_max_index( idx ); - index birth = nr_columns - 1 - idx; - pairs.append_pair( birth, death ); - } - } - } - - template< typename Representation > - void compute_persistence_pairs( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { - phat::compute_persistence_pairs< twist_reduction >( pairs, boundary_matrix ); - } - - - template< typename Representation > - void compute_persistence_pairs_dualized( persistence_pairs& pairs, boundary_matrix< Representation >& boundary_matrix ) { - compute_persistence_pairs_dualized< twist_reduction >( pairs, boundary_matrix ); - } - -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h deleted file mode 100644 index 60caa05c..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/dualize.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "misc.h" -#include "../boundary_matrix.h" - -namespace phat { - template< typename Representation > - void dualize( boundary_matrix< Representation >& boundary_matrix ) { - - std::vector< dimension > dual_dims; - std::vector< std::vector< index > > dual_matrix; - - index nr_of_columns = boundary_matrix.get_num_cols(); - dual_matrix.resize( nr_of_columns ); - dual_dims.resize( nr_of_columns ); - - std::vector< index > dual_sizes( nr_of_columns, 0 ); - - column temp_col; - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - boundary_matrix.get_col( cur_col, temp_col ); - for( index idx = 0; idx < (index)temp_col.size(); idx++) - dual_sizes[ nr_of_columns - 1 - temp_col[ idx ] ]++; - } - - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - dual_matrix[cur_col].reserve(dual_sizes[cur_col]); - } - - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) { - boundary_matrix.get_col( cur_col, temp_col ); - for( index idx = 0; idx < (index)temp_col.size(); idx++) - dual_matrix[ nr_of_columns - 1 - temp_col[ idx ] ].push_back( nr_of_columns - 1 - cur_col ); - } - - const dimension max_dim = boundary_matrix.get_max_dim(); - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) - dual_dims[ nr_of_columns - 1 - cur_col ] = max_dim - boundary_matrix.get_dim( cur_col ); - - for( index cur_col = 0; cur_col < nr_of_columns; cur_col++ ) - std::reverse( dual_matrix[ cur_col ].begin(), dual_matrix[ cur_col ].end() ); - - boundary_matrix.load_vector_vector( dual_matrix, dual_dims ); - } -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h deleted file mode 100644 index abbf8d53..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/misc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -// STL includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// VS2008 and below unfortunately do not support stdint.h -#if defined(_MSC_VER)&& _MSC_VER < 1600 - typedef __int8 int8_t; - typedef unsigned __int8 uint8_t; - typedef __int16 int16_t; - typedef unsigned __int16 uint16_t; - typedef __int32 int32_t; - typedef unsigned __int32 uint32_t; - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -#else - #include -#endif - -// basic types. index can be changed to int32_t to save memory on small instances -namespace phat { - typedef int64_t index; - typedef int8_t dimension; - typedef std::vector< index > column; -} - -// OpenMP (proxy) functions -#if defined _OPENMP - #include -#else - #define omp_get_thread_num() 0 - #define omp_get_max_threads() 1 - #define omp_get_num_threads() 1 - void omp_set_num_threads( int ) {}; - #include - #define omp_get_wtime() (float)clock() / (float)CLOCKS_PER_SEC -#endif - -#include "thread_local_storage.h" - - - diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h b/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h deleted file mode 100644 index 06e95c20..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/helpers/thread_local_storage.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "misc.h" - -// should ideally be equal to the cache line size of the CPU -#define PHAT_TLS_SPACING_FACTOR 64 - -// ThreadLocalStorage with some spacing to avoid "false sharing" (see wikipedia) -template< typename T > -class thread_local_storage -{ -public: - - thread_local_storage() : per_thread_storage( omp_get_max_threads() * PHAT_TLS_SPACING_FACTOR ) {}; - - T& operator()() { - return per_thread_storage[ omp_get_thread_num() * PHAT_TLS_SPACING_FACTOR ]; - } - - const T& operator()() const { - return per_thread_storage[ omp_get_thread_num() * PHAT_TLS_SPACING_FACTOR ]; - } - - T& operator[]( int tid ) { - return per_thread_storage[ tid * PHAT_TLS_SPACING_FACTOR ]; - } - - const T& operator[]( int tid ) const { - return per_thread_storage[ tid * PHAT_TLS_SPACING_FACTOR ]; - } - -protected: - std::vector< T > per_thread_storage; -}; diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h b/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h deleted file mode 100644 index f8006353..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/persistence_pairs.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "helpers/misc.h" - -namespace phat { - class persistence_pairs { - - protected: - std::vector< std::pair< index, index > > pairs; - - public: - index get_num_pairs() const { - return (index)pairs.size(); - } - - void append_pair( index birth, index death ) { - pairs.push_back( std::make_pair( birth, death ) ); - } - - std::pair< index, index > get_pair( index idx ) const { - return pairs[ idx ]; - } - - void clear() { - pairs.clear(); - } - - void sort() { - std::sort( pairs.begin(), pairs.end() ); - } - - // Loads the persistence pairs from given file in asci format - // Format: nr_pairs % newline % birth1 % death1 % newline % birth2 % death2 % newline ... - bool load_ascii( std::string filename ) { - std::ifstream input_stream( filename.c_str() ); - if( input_stream.fail() ) - return false; - - int64_t nr_pairs; - input_stream >> nr_pairs; - pairs.clear(); - for( index idx = 0; idx < nr_pairs; idx++ ) { - int64_t birth; - input_stream >> birth; - int64_t death; - input_stream >> death; - append_pair( (index)birth, (index)death ); - } - - input_stream.close(); - return true; - } - - // Saves the persistence pairs to given file in binary format - // Format: nr_pairs % newline % birth1 % death1 % newline % birth2 % death2 % newline ... - bool save_ascii( std::string filename ) { - std::ofstream output_stream( filename.c_str() ); - if( output_stream.fail() ) - return false; - - this->sort(); - output_stream << get_num_pairs() << std::endl; - for( std::size_t idx = 0; idx < pairs.size(); idx++ ) { - output_stream << pairs[idx].first << " " << pairs[idx].second << std::endl; - } - - output_stream.close(); - return true; - } - - // Loads the persistence pairs from given file in binary format - // Format: nr_pairs % birth1 % death1 % birth2 % death2 ... - bool load_binary( std::string filename ) { - std::ifstream input_stream( filename.c_str(), std::ios_base::binary | std::ios_base::in ); - if( input_stream.fail() ) - return false; - - int64_t nr_pairs; - input_stream.read( (char*)&nr_pairs, sizeof( int64_t ) ); - for( index idx = 0; idx < nr_pairs; idx++ ) { - int64_t birth; - input_stream.read( (char*)&birth, sizeof( int64_t ) ); - int64_t death; - input_stream.read( (char*)&death, sizeof( int64_t ) ); - append_pair( (index)birth, (index)death ); - } - - input_stream.close(); - return true; - } - - // Saves the persistence pairs to given file in binary format - // Format: nr_pairs % birth1 % death1 % birth2 % death2 ... - bool save_binary( std::string filename ) { - std::ofstream output_stream( filename.c_str(), std::ios_base::binary | std::ios_base::out ); - if( output_stream.fail() ) - return false; - - this->sort(); - int64_t nr_pairs = get_num_pairs(); - output_stream.write( (char*)&nr_pairs, sizeof( int64_t ) ); - for( std::size_t idx = 0; idx < pairs.size(); idx++ ) { - int64_t birth = pairs[ idx ].first; - output_stream.write( (char*)&birth, sizeof( int64_t ) ); - int64_t death = pairs[ idx ].second; - output_stream.write( (char*)&death, sizeof( int64_t ) ); - } - - output_stream.close(); - return true; - } - - bool operator==( persistence_pairs& other_pairs ) { - this->sort(); - other_pairs.sort(); - if( pairs.size() != (std::size_t)other_pairs.get_num_pairs() ) - return false; - - for( index idx = 0; idx < (index)pairs.size(); idx++ ) - if( get_pair( idx ) != other_pairs.get_pair( idx ) ) - return false; - - return true; - } - - bool operator!=( persistence_pairs& other_pairs ) { - return !( *this == other_pairs ); - } - }; - - - -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h deleted file mode 100644 index 41104108..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/abstract_pivot_column.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../representations/vector_vector.h" - -namespace phat { - - // Note: We could even make the rep generic in the underlying Const representation - // But I cannot imagine that anything else than vector> would - // make sense - template< typename PivotColumn > - class abstract_pivot_column : public vector_vector { - public: - - protected: - typedef vector_vector Base; - typedef PivotColumn pivot_column; - - // For parallization purposes, it could be more than one full column - mutable thread_local_storage< pivot_column > _pivot_columns; - mutable thread_local_storage< index > pos_of_pivot_columns; - - pivot_column& get_pivot_column() const { - return _pivot_columns(); - } - - bool is_represented_by_pivot_column( index idx ) const { - return pos_of_pivot_columns() == idx; - } - - void unset_pos_of_pivot_column() { - index idx = pos_of_pivot_columns(); - if( idx != -1 ) { - _pivot_columns().get_column_and_clear( this->matrix[ idx ] ); - } - pos_of_pivot_columns() = -1; - } - - void represent_by_pivot_column( index idx ) { - pos_of_pivot_columns() = idx; - get_pivot_column().add_column( matrix[ idx ] ); - } - - public: - - void _set_num_cols( index nr_of_columns ) { - #pragma omp parallel for - for( int tid = 0; tid < omp_get_num_threads(); tid++ ) { - _pivot_columns[ tid ].init( nr_of_columns ); - pos_of_pivot_columns[ tid ] = -1; - } - Base::_set_num_cols( nr_of_columns ); - } - // replaces(!) content of 'col' with boundary of given index - void _get_col( index idx, column& col ) const { - col.clear(); - if( is_represented_by_pivot_column( idx ) ) { - pivot_column& pivot_column = get_pivot_column(); - pivot_column.get_column_and_clear( col ); - pivot_column.add_column( col ); - } else { - Base::_get_col( idx, col ); - } - } - - // true iff boundary of given idx is empty - bool _is_empty( index idx ) const { - return is_represented_by_pivot_column( idx ) ? get_pivot_column().empty() : Base::_is_empty( idx ); - } - - // largest row index of given column idx (new name for lowestOne()) - index _get_max_index( index idx ) const { - if( is_represented_by_pivot_column( idx ) ) { - pivot_column& pivot_column = get_pivot_column(); - if( pivot_column.empty() ) { - return -1; - } else { - return pivot_column.max_index(); - } - } else { - return Base::_get_max_index( idx ); - } - } - - // adds column 'source' to column 'target' - void _add_to( index source, index target ) { - if( !is_represented_by_pivot_column( target ) ) { - unset_pos_of_pivot_column(); - represent_by_pivot_column( target ); - } - get_pivot_column().add_column( matrix[source] ); - } - - // clears given column - void _clear( index idx ) { - if( is_represented_by_pivot_column( idx ) ) { - column dummy; - get_pivot_column().get_column_and_clear(dummy); - } else { - Base::_clear( idx ); - } - } - - void _set_col( index idx, const column& col ) { - if( is_represented_by_pivot_column( idx ) ) { - column dummy; - pivot_column& pivot_column = get_pivot_column(); - pivot_column.get_column_and_clear( dummy ); - pivot_column.add_column( col ); - } else { - Base::_set_col( idx, col ); - } - } - - // removes the maximal index of a column - void _remove_max( index idx ) { - _toggle( idx, _get_max_index( idx ) ); - } - - //// toggles given index pair - void _toggle( index col_idx, index row_idx ) { - if( !is_represented_by_pivot_column( col_idx ) ) { - unset_pos_of_pivot_column(); - represent_by_pivot_column( col_idx ); - } - get_pivot_column().add_index( row_idx ); - } - - // syncronizes all data structures (essential for openmp stuff) - // has to be called before and after any multithreaded access! - void _sync() { - #pragma omp parallel for - for( int tid = 0; tid < omp_get_num_threads(); tid++ ) - unset_pos_of_pivot_column(); - } - - }; -} - - diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h deleted file mode 100644 index 34366d6a..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/bit_tree_pivot_column.h +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Hubert Wagner - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" -#include "../representations/abstract_pivot_column.h" - -namespace phat { - - // This is a bitset indexed with a 64-ary tree. Each node in the index - // has 64 bits; i-th bit says that the i-th subtree is non-empty. - // Supports practically O(1), inplace, zero-allocation: insert, remove, max_element - // and clear in O(number of ones in the bitset). - // 'add_index' is still the real bottleneck in practice. - class bit_tree_column - { - size_t offset; // data[i + offset] = ith block of the data-bitset - typedef uint64_t block_type; - std::vector< block_type > data; - - // this static is not a problem with OMP, it's initialized just after program starts - static const size_t debrujin_magic_table[64]; - - enum { block_size_in_bits = 64 }; - enum { block_shift = 6 }; - - // Some magic: http://graphics.stanford.edu/~seander/bithacks.html - // Gets the position of the rightmost bit of 'x'. 0 means the most significant bit. - // (-x)&x isolates the rightmost bit. - // The whole method is much faster than calling log2i, and very comparable to using ScanBitForward/Reverse intrinsic, - // which should be one CPU instruction, but is not portable. - size_t rightmost_pos(const block_type value) const - { - return 64 - 1 - debrujin_magic_table[((value & (-(int64_t)value))*0x07EDD5E59A4E28C2) >> 58]; - } - - public: - - void init(index num_cols) - { - int64_t n = 1; // in case of overflow - int64_t bottom_blocks_needed = (num_cols+block_size_in_bits-1)/block_size_in_bits; - int64_t upper_blocks = 1; - - // How many blocks/nodes of index needed to index the whole bitset? - while(n * block_size_in_bits < bottom_blocks_needed) - { - n *= block_size_in_bits; - upper_blocks += n; - } - - offset = upper_blocks; - data.resize(upper_blocks + bottom_blocks_needed, 0); - } - - index max_index() const - { - if (!data[0]) - return -1; - - const size_t size = data.size(); - size_t n = 0; - - while(true) - { - const block_type val = data[n]; - const size_t index = rightmost_pos(val); - const size_t newn = (n << block_shift) + index + 1; - - if (newn >= size) - { - const size_t bottom_index = n - offset; - return (bottom_index << block_shift) + index; - } - - n = newn; - } - - return -1; - } - - bool empty() const - { - return data[0] == 0; - } - - void add_index(const size_t entry) - { - const block_type ONE = 1; - const block_type block_modulo_mask = ((ONE << block_shift) - 1); - size_t index_in_level = entry >> block_shift; - size_t address = index_in_level + offset; - size_t index_in_block = entry & block_modulo_mask; - - block_type mask = (ONE << (block_size_in_bits - index_in_block - 1)); - - while(true) - { - data[address]^=mask; - - // First we check if we reached the root. - // Also, if anyone else was in this block, we don't need to update the path up. - if (!address || (data[address] & ~mask)) - return; - - index_in_block = index_in_level & block_modulo_mask; - index_in_level >>= block_shift; - --address; - address >>= block_shift; - mask = (ONE << (block_size_in_bits - index_in_block - 1)); - } - } - - void get_column_and_clear(column &out) - { - out.clear(); - while(true) - { - index mx = this->max_index(); - if (mx == -1) - break; - out.push_back(mx); - add_index(mx); - } - - std::reverse(out.begin(), out.end()); - } - - void add_column(const column &col) - { - for (size_t i = 0; i < col.size(); ++i) - { - add_index(col[i]); - } - } - - bool empty() { - return !data[0]; - } - }; - - const size_t bit_tree_column::debrujin_magic_table[64] = { - 63, 0, 58, 1, 59, 47, 53, 2, - 60, 39, 48, 27, 54, 33, 42, 3, - 61, 51, 37, 40, 49, 18, 28, 20, - 55, 30, 34, 11, 43, 14, 22, 4, - 62, 57, 46, 52, 38, 26, 32, 41, - 50, 36, 17, 19, 29, 10, 13, 21, - 56, 45, 25, 31, 35, 16, 9, 12, - 44, 24, 15, 8, 23, 7, 6, 5}; - - typedef abstract_pivot_column bit_tree_pivot_column; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h deleted file mode 100644 index 9e0c348d..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/full_pivot_column.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include -#include - -namespace phat { - class full_column { - - protected: - std::priority_queue< index > m_history; - std::vector< char > m_isInHistory; - std::vector< char > m_data; - - public: - void init( const index total_size ) { - m_data.resize( total_size, false ); - m_isInHistory.resize( total_size, false ); - } - - void add_column( const column& col ) { - for( index idx = 0; idx < (index) col.size(); idx++ ) { - add_index( col[ idx ] ); - } - } - void add_index( const index idx ) { - if( !m_isInHistory[ idx ] ) { - m_history.push( idx ); - m_isInHistory[ idx ] = true; - } - - m_data[ idx ] = !m_data[ idx ]; - } - - index max_index() { - while( m_history.size() > 0 ) { - index topIndex = m_history.top(); - if( m_data[ topIndex ] ) { - return topIndex; - } else { - m_history.pop(); - m_isInHistory[ topIndex ] = false; - } - } - - return -1; - } - - void get_column_and_clear( column& col ) { - col.clear(); - while( !empty() ) { - col.push_back( max_index() ); - add_index( max_index() ); - } - std::reverse( col.begin(), col.end() ); - } - - bool empty() { - return (max_index() == -1); - } - }; - - typedef abstract_pivot_column< full_column > full_pivot_column; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h deleted file mode 100644 index c851a2b5..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/sparse_pivot_column.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include -#include - -namespace phat { - class sparse_column { - - protected: - std::set< index > m_data; - - public: - void init( const index total_size ) { - m_data.clear(); - } - - void add_column( const column& col ) { - for( index idx = 0; idx < (index) col.size(); idx++ ) - add_index( col[ idx ] ); - } - - void add_index( const index idx ) { - std::pair< std::set< index >::iterator, bool > result = m_data.insert( idx ); - if( result.second == false ) - m_data.erase( result.first ); - } - - index max_index() { - return m_data.empty() ? -1 : *m_data.rbegin(); - } - - void get_column_and_clear( column& col ) { - col.clear(); - col.assign( m_data.begin(), m_data.end() ); - m_data.clear(); - } - - bool empty() { - return m_data.empty(); - } - }; - - typedef abstract_pivot_column< sparse_column > sparse_pivot_column; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h deleted file mode 100644 index 38e3090c..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_list.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include - -namespace phat { - class vector_list { - - protected: - typedef std::list< index > internal_column; - std::vector< dimension > dims; - std::vector< internal_column > matrix; - - public: - // overall number of cells in boundary_matrix - index _get_num_cols() const { - return (index)matrix.size(); - } - void _set_num_cols( index nr_of_columns ) { - dims.resize( nr_of_columns ); - matrix.resize( nr_of_columns ); - } - - // dimension of given index - dimension _get_dim( index idx ) const { - return dims[ idx ]; - } - void _set_dim( index idx, dimension dim ) { - dims[ idx ] = dim; - } - - // replaces(!) content of 'col' with boundary of given index - void _get_col( index idx, column& col ) const { - col.clear(); - col.reserve( matrix[idx].size() ); - std::copy (matrix[idx].begin(), matrix[idx].end(), std::back_inserter(col) ); - } - - void _set_col( index idx, const column& col ) { - matrix[ idx ].clear(); - matrix[ idx ].resize( col.size() ); - std::copy (col.begin(), col.end(), matrix[ idx ].begin() ); - } - - // true iff boundary of given idx is empty - bool _is_empty( index idx ) const { - return matrix[ idx ].empty(); - } - - // largest row index of given column idx (new name for lowestOne()) - index _get_max_index( index idx ) const { - return matrix[ idx ].empty() ? -1 : *matrix[ idx ].rbegin(); - } - - // removes the maximal index of a column - void _remove_max( index idx ) { - internal_column::iterator it = matrix[ idx ].end(); - it--; - matrix[ idx ].erase( it ); - } - - // clears given column - void _clear( index idx ) { - matrix[ idx ].clear(); - } - - // syncronizes all data structures (essential for openmp stuff) - void _sync() {} - - // adds column 'source' to column 'target' - void _add_to( index source, index target ) { - internal_column& source_col = matrix[ source ]; - internal_column& target_col = matrix[ target ]; - internal_column temp_col; - target_col.swap( temp_col ); - std::set_symmetric_difference( temp_col.begin(), temp_col.end(), - source_col.begin(), source_col.end(), - std::back_inserter( target_col ) ); - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h deleted file mode 100644 index dadf1b34..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_set.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include - -namespace phat { - class vector_set { - - protected: - typedef std::set< index > internal_column; - std::vector< dimension > dims; - std::vector< internal_column > matrix; - - public: - // overall number of cells in boundary_matrix - index _get_num_cols() const { - return (index)matrix.size(); - } - void _set_num_cols( index nr_of_columns ) { - dims.resize( nr_of_columns ); - matrix.resize( nr_of_columns ); - } - - // dimension of given index - dimension _get_dim( index idx ) const { - return dims[ idx ]; - } - void _set_dim( index idx, dimension dim ) { - dims[ idx ] = dim; - } - - // replaces(!) content of 'col' with boundary of given index - void _get_col( index idx, column& col ) const { - col.clear(); - col.reserve( matrix[idx].size() ); - std::copy (matrix[idx].begin(), matrix[idx].end(), std::back_inserter(col) ); - } - void _set_col( index idx, const column& col ) { - matrix[ idx ].clear(); - matrix[ idx ].insert( col.begin(), col.end() ); - } - - // true iff boundary of given idx is empty - bool _is_empty( index idx ) const { - return matrix[ idx ].empty(); - } - - // largest row index of given column idx (new name for lowestOne()) - index _get_max_index( index idx ) const { - return matrix[ idx ].empty() ? -1 : *matrix[ idx ].rbegin(); - } - - // removes the maximal index of a column - void _remove_max( index idx ) { - internal_column::iterator it = matrix[ idx ].end(); - it--; - matrix[ idx ].erase( it ); - } - - // clears given column - void _clear( index idx ) { - matrix[ idx ].clear(); - } - - // syncronizes all data structures (essential for openmp stuff) - void _sync() {} - - // adds column 'source' to column 'target' - void _add_to( index source, index target ) { - for( internal_column::iterator it = matrix[ source ].begin(); it != matrix[ source ].end(); it++ ) - _toggle( target, *it ); - } - - //// toggles given index pair - void _toggle( index col_idx, index row_idx ) { - internal_column& col = matrix[ col_idx ]; - std::pair< internal_column::iterator, bool > result = col.insert( row_idx ); - if( !result.second ) { - col.erase( result.first ); - } - } - }; -} diff --git a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h b/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h deleted file mode 100644 index efe8de4d..00000000 --- a/src/Bitmap_cubical_complex/include/gudhi/phat/representations/vector_vector.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright 2013 IST Austria - Contributed by: Ulrich Bauer, Michael Kerber, Jan Reininghaus - - This file is part of PHAT. - - PHAT is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - PHAT 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PHAT. If not, see . */ - -#pragma once - -#include "../helpers/misc.h" - -namespace phat { - class vector_vector { - - protected: - std::vector< dimension > dims; - std::vector< column > matrix; - - thread_local_storage< column > temp_column_buffer; - - public: - // overall number of cells in boundary_matrix - index _get_num_cols() const { - return (index)matrix.size(); - } - void _set_num_cols( index nr_of_columns ) { - dims.resize( nr_of_columns ); - matrix.resize( nr_of_columns ); - } - - // dimension of given index - dimension _get_dim( index idx ) const { - return dims[ idx ]; - } - void _set_dim( index idx, dimension dim ) { - dims[ idx ] = dim; - } - - // replaces(!) content of 'col' with boundary of given index - void _get_col( index idx, column& col ) const { - col = matrix[ idx ]; - } - void _set_col( index idx, const column& col ) { - matrix[ idx ] = col; - } - - // true iff boundary of given idx is empty - bool _is_empty( index idx ) const { - return matrix[ idx ].empty(); - } - - // largest row index of given column idx (new name for lowestOne()) - index _get_max_index( index idx ) const { - return matrix[ idx ].empty() ? -1 : matrix[ idx ].back(); - } - - // removes the maximal index of a column - void _remove_max( index idx ) { - matrix[ idx ].pop_back(); - } - - // clears given column - void _clear( index idx ) { - matrix[ idx ].clear(); - } - - // syncronizes all data structures (essential for openmp stuff) - void _sync() {} - - // adds column 'source' to column 'target' - void _add_to( index source, index target ) { - column& source_col = matrix[ source ]; - column& target_col = matrix[ target ]; - column& temp_col = temp_column_buffer(); - temp_col.clear(); - std::set_symmetric_difference( target_col.begin(), target_col.end(), - source_col.begin(), source_col.end(), - std::back_inserter( temp_col ) ); - target_col.swap( temp_col ); - } - }; -} -- cgit v1.2.3 From ff41ff166c9ea66fcc1187056053e43bf7d7be8f Mon Sep 17 00:00:00 2001 From: glisse Date: Mon, 15 Feb 2016 11:51:20 +0000 Subject: typo git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1022 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d6068c0b757949d2e404ba99812ae7a0b8a8908d --- src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 2ec7594d..70f19e03 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -40,8 +40,8 @@ const bool globalDbg = false; 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 -* 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. +* 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. **/ /** -- 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') 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 d133f17dede836cee1dfff47d2e00532573b9ead Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 17 Mar 2016 08:43:58 +0000 Subject: cleanning up the stuff with iterators in Bitmap_cubical_complex_base.h class. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1049 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9630d6df6a2ecdb51ab25150454a563cd928b09a --- .../example/Random_bitmap_cubical_complex.cpp | 7 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 515 +++++++++++++-------- ...cal_complex_periodic_boundary_conditions_base.h | 4 +- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 183 +++++++- 4 files changed, 500 insertions(+), 209 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 97347162..8b7f6a04 100644 --- a/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp +++ b/src/Bitmap_cubical_complex/example/Random_bitmap_cubical_complex.cpp @@ -70,11 +70,12 @@ The program will create random cubical complex of that sizes and compute persist 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 ); + + - Bitmap_cubical_complex< Bitmap_cubical_complex_base > b( sizes , data ); // Compute the persistence diagram of the 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 807be335..6d2b705c 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 @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include "Bitmap_cubical_complex/counter.h" @@ -69,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. @@ -96,11 +96,11 @@ public: * 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(){} + **/ + virtual ~Bitmap_cubical_complex_base(){} /** * The functions get_boundary_of_a_cell, get_coboundary_of_a_cell, get_dimension_of_a_cell @@ -130,7 +130,9 @@ public: **/ 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. + * 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 ); @@ -162,27 +164,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 ); + + /** - * 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 ) + * 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( size_t number_of_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( 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 + * 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 ); - + 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 @@ -191,76 +193,179 @@ 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; /** * Constant iterator through all cells in the complex (in order they appear in the structure -- i.e. * in lexicographical order). **/ - typedef typename std::vector< T >::const_iterator all_cells_const_iterator; - + //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(); - } - - + //all_cells_const_iterator all_cells_const_begin()const + //{ + // return this->data.begin(); + //} + + /** * 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_const_end()const + //{ + // return this->data.end(); + //} + + /** + * Function returning an iterator to the first cell of the bitmap. + **/ + //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_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_end() const + //{ + // return this->data.end(); + //} + + /** + * 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 > { - return this->data.end(); - } + 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); + } + size_t operator*() + { + return this->counter; + } + friend class Bitmap_cubical_complex_base; + protected: + size_t counter; + }; + /** - * Function returning an iterator to the first cell of the bitmap. + * Function returning a All_cells_iterator to the first cell of the bitmap. **/ - all_cells_iterator all_cells_begin() + All_cells_iterator all_cells_iterator_begin() { - return this->data.begin(); - } - + All_cells_iterator a; + return a; + } + /** - * Function returning a constant iterator to the first cell of the bitmap. + * Function returning a All_cells_iterator to the last cell of the bitmap. **/ - all_cells_const_iterator all_cells_begin() const + All_cells_iterator all_cells_iterator_end() { - return this->data.begin(); - } - + All_cells_iterator a; + a.counter = this->data.size(); + return a; + } + /** - * Function returning an iterator to the last cell of the bitmap. + * Boundary_range class provides ranges for boundary iterators. + **/ + typedef typename std::vector< size_t >::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. **/ - all_cells_iterator all_cells_end() + Boundary_range boundary_range(size_t sh) { - return this->data.end(); - } - + return this->get_boundary_of_a_cell(sh); + } + /** - * Function returning a constant iterator to the last cell of the bitmap. + * Coboundary_range class provides ranges for boundary iterators. + **/ + typedef typename std::vector< size_t >::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. **/ - all_cells_const_iterator all_cells_end() const + Coboundary_range coboundary_range(size_t sh) { - return this->data.end(); - } + 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, double > + 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 ); - } + 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: @@ -308,15 +413,20 @@ public: 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]; + //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 operator*() + { + return this->compute_index_in_bitmap(); } size_t compute_index_in_bitmap()const @@ -327,7 +437,8 @@ public: index += (2*this->counter[i]+1)*this->b.multipliers[i]; } return index; - } + } + void print_counter()const { @@ -340,19 +451,19 @@ 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. + * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell of the bitmap. **/ Top_dimensional_cells_iterator top_dimensional_cells_begin() { 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. + * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell of the bitmap. **/ Top_dimensional_cells_iterator top_dimensional_cells_end() { @@ -370,11 +481,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; } //****************************************************************************************************************// @@ -412,7 +523,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 ) { @@ -421,59 +532,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( 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( 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 @@ -494,10 +605,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; @@ -523,22 +634,22 @@ void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells size_t index = 0; for ( it = this->top_dimensional_cells_begin() ; it != this->top_dimensional_cells_end() ; ++it ) { - (*it) = top_dimensional_cells[index]; + this->get_cell_data(*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 ); @@ -547,7 +658,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 ) { @@ -564,7 +675,7 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu while ( !inFiltration.eof() ) { - double filtrationLevel; + T filtrationLevel; inFiltration >> filtrationLevel; if ( dbg ) { @@ -574,35 +685,35 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) << " get the value : " << filtrationLevel << endl; } - *it = filtrationLevel; + 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 + 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 @@ -615,29 +726,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 { @@ -662,8 +773,8 @@ std::vector< size_t > Bitmap_cubical_complex_base::get_coboundary_of_a_cell( cell1 = cell1%this->multipliers[i-1]; } return coboundary_elements; -} - +} + @@ -712,14 +823,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. @@ -745,20 +856,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 ) @@ -797,4 +908,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 8c1254db..9a5ef0eb 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 @@ -121,7 +121,7 @@ void Bitmap_cubical_complex_periodic_boundary_conditions_base::construct_comp size_t i = 0; for ( typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it = this->top_dimensional_cells_begin() ; it != this->top_dimensional_cells_end() ; ++it ) { - *it = topDimensionalCells[i]; + this->get_cell_data(*it) = topDimensionalCells[i]; ++i; } this->impose_lower_star_filtration(); @@ -178,7 +178,7 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_comp << this->get_dimension_of_a_cell(it.compute_index_in_bitmap()) << " get the value : " << filtrationLevel << endl; } - *it = filtrationLevel; + this->get_cell_data(*it) = filtrationLevel; ++it; } inFiltration.close(); diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index 968483a3..c1c846c9 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -95,13 +95,13 @@ BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { int i = 0; for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator it = increasing.top_dimensional_cells_begin(); it != increasing.top_dimensional_cells_end(); ++it) { - BOOST_CHECK(*it == expectedFiltrationValues2[i]); + BOOST_CHECK(increasing.get_cell_data(*it) == expectedFiltrationValues2[i]); ++i; } i = 0; for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator it = hole.top_dimensional_cells_begin(); it != hole.top_dimensional_cells_end(); ++it) { - BOOST_CHECK(*it == expectedFiltrationValues1[i]); + BOOST_CHECK(hole.get_cell_data(*it) == expectedFiltrationValues1[i]); ++i; } } @@ -884,3 +884,182 @@ BOOST_AUTO_TEST_CASE(bitmap_2d_with_periodic_bcond_filtration) { 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; + } +} -- cgit v1.2.3 From 10083c1ed5ae478b54b6bb1b17be3325838533fe Mon Sep 17 00:00:00 2001 From: pdlotko Date: Sun, 20 Mar 2016 17:41:52 +0000 Subject: answering Marc's comments git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1059 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2f0e6e894c0c48ffc80a0864f4a4992066fd2273 --- src/Bitmap_cubical_complex/example/CMakeLists.txt | 5 +- .../include/gudhi/Bitmap_cubical_complex_base.h | 137 +++---- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 426 +++++++++++++++++++++ 3 files changed, 493 insertions(+), 75 deletions(-) (limited to 'src/Bitmap_cubical_complex') diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index 14c94e8e..088e6fbd 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -14,4 +14,7 @@ add_executable ( Bitmap_cubical_complex_periodic_boundary_conditions Bitmap_cubi 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 +#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/include/gudhi/Bitmap_cubical_complex_base.h b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex_base.h index 6d2b705c..e081764c 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 @@ -161,96 +161,35 @@ public: } /** - * Writing to stream operator. + * 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. Sometimes if most of the cells have different birth-death times, the performance of the algorithms to compute persistence gets + * 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_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_to_bins( size_t number_of_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 + * 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_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 ); + 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). - **/ - //typedef typename std::vector< T >::iterator all_cells_iterator; - - - /** - * Constant iterator through all cells in the complex (in order they appear in the structure -- i.e. - * in lexicographical order). - **/ - //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 a constant iterator to the last cell of the bitmap. - **/ - //all_cells_const_iterator all_cells_const_end()const - //{ - // return this->data.end(); - //} - - /** - * Function returning an iterator to the first cell of the bitmap. - **/ - //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_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_end() const - //{ - // return this->data.end(); - //} - + //ITERATORS /** * Iterator through all cells in the complex (in order they appear in the structure -- i.e. * in lexicographical order). @@ -288,7 +227,12 @@ public: { 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; @@ -317,10 +261,31 @@ public: return a; } + + /** + * All_cells_iterator_range class provides ranges for All_cells_iterator + **/ + class All_cells_iterator_range + { + public: + All_cells_iterator_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; + }; + + /** * Boundary_range class provides ranges for boundary iterators. **/ - typedef typename std::vector< size_t >::iterator Boundary_iterator; + typedef typename std::vector< size_t >::const_iterator Boundary_iterator; typedef typename std::vector< size_t > Boundary_range; /** @@ -424,6 +389,11 @@ public: // 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(); @@ -474,7 +444,26 @@ public: } a.counter[0]++; return a; - } + } + + /** + * All_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range + **/ + class Top_dimensional_cells_iterator_range + { + public: + Top_dimensional_cells_iterator_range(Bitmap_cubical_complex_base* b):b(b){}; + Top_dimensional_cells_iterator begin() + { + return b->top_dimensional_cells_begin(); + } + Top_dimensional_cells_iterator end() + { + return b->top_dimensional_cells_end(); + } + private: + Bitmap_cubical_complex_base* b; + }; //****************************************************************************************************************// @@ -542,7 +531,7 @@ protected: template -void Bitmap_cubical_complex_base::put_data_toBins( size_t number_of_bins ) +void Bitmap_cubical_complex_base::put_data_to_bins( size_t number_of_bins ) { bool bdg = false; @@ -559,7 +548,7 @@ void Bitmap_cubical_complex_base::put_data_toBins( size_t number_of_bins ) } template -void Bitmap_cubical_complex_base::put_data_toBins( T diameter_of_bin ) +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(); diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index c1c846c9..b7a1c8b6 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -1063,3 +1063,429 @@ BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical ++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_iterator_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_iterator_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(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_iterator_range range(&ba); + 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 From 04c63ee74520c966451b0cb1713df8b3e9ca5bfb Mon Sep 17 00:00:00 2001 From: pdlotko Date: Mon, 21 Mar 2016 08:21:22 +0000 Subject: Answers to comments. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1063 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 99cebe0573d75c98c8559ae4572b8f510e5cd9c0 --- .../include/gudhi/Bitmap_cubical_complex_base.h | 46 +++++++++++++--------- ...cal_complex_periodic_boundary_conditions_base.h | 6 +-- src/Bitmap_cubical_complex/test/Bitmap_test.cpp | 10 ++--- 3 files changed, 36 insertions(+), 26 deletions(-) (limited to 'src/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 e081764c..f0517a86 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 @@ -170,7 +170,7 @@ public: /** * 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_toBins( size_t number_of_bins ) + * 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 ); @@ -178,7 +178,7 @@ public: /** * 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_toBins( T diameter_of_bin ) is + * 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. **/ @@ -263,12 +263,12 @@ public: /** - * All_cells_iterator_range class provides ranges for All_cells_iterator + * All_cells_range class provides ranges for All_cells_iterator **/ - class All_cells_iterator_range + class All_cells_range { public: - All_cells_iterator_range(Bitmap_cubical_complex_base* b):b(b){}; + All_cells_range(Bitmap_cubical_complex_base* b):b(b){}; All_cells_iterator begin() { return b->all_cells_iterator_begin(); @@ -279,7 +279,12 @@ public: } private: Bitmap_cubical_complex_base* b; - }; + }; + + All_cells_range all_cells_range() + { + return All_cells_range(this); + } /** @@ -300,7 +305,7 @@ public: /** * Coboundary_range class provides ranges for boundary iterators. **/ - typedef typename std::vector< size_t >::iterator Coboundary_iterator; + typedef typename std::vector< size_t >::const_iterator Coboundary_iterator; typedef typename std::vector< size_t > Coboundary_range; /** @@ -426,7 +431,7 @@ public: /** * Function returning a Top_dimensional_cells_iterator to the first top dimensional cell of the bitmap. **/ - Top_dimensional_cells_iterator top_dimensional_cells_begin() + Top_dimensional_cells_iterator top_dimensional_cells_iterator_begin() { Top_dimensional_cells_iterator a(*this); return a; @@ -435,7 +440,7 @@ public: /** * Function returning a Top_dimensional_cells_iterator to the last top dimensional cell of the bitmap. **/ - Top_dimensional_cells_iterator top_dimensional_cells_end() + Top_dimensional_cells_iterator top_dimensional_cells_iterator_end() { Top_dimensional_cells_iterator a(*this); for ( size_t i = 0 ; i != this->dimension() ; ++i ) @@ -447,23 +452,28 @@ public: } /** - * All_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range + * Top_dimensional_cells_iterator_range class provides ranges for Top_dimensional_cells_iterator_range **/ - class Top_dimensional_cells_iterator_range + class Top_dimensional_cells_range { public: - Top_dimensional_cells_iterator_range(Bitmap_cubical_complex_base* b):b(b){}; + Top_dimensional_cells_range(Bitmap_cubical_complex_base* b):b(b){}; Top_dimensional_cells_iterator begin() { - return b->top_dimensional_cells_begin(); + return b->top_dimensional_cells_iterator_begin(); } Top_dimensional_cells_iterator end() { - return b->top_dimensional_cells_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); + } //****************************************************************************************************************// @@ -621,7 +631,7 @@ void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells 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 ) + 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; @@ -660,7 +670,7 @@ void Bitmap_cubical_complex_base::read_perseus_style_file( const char* perseu this->set_up_containers( sizes ); Bitmap_cubical_complex_base::Top_dimensional_cells_iterator it(*this); - it = this->top_dimensional_cells_begin(); + it = this->top_dimensional_cells_iterator_begin(); while ( !inFiltration.eof() ) { @@ -824,7 +834,7 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() //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 ) + 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() ); } 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 9a5ef0eb..956e74a7 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 @@ -119,7 +119,7 @@ void Bitmap_cubical_complex_periodic_boundary_conditions_base::construct_comp 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + 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; @@ -162,7 +162,7 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_comp this->set_up_containers( sizes ); typename Bitmap_cubical_complex_periodic_boundary_conditions_base::Top_dimensional_cells_iterator it(*this); - it = this->top_dimensional_cells_begin(); + it = this->top_dimensional_cells_iterator_begin(); while ( !inFiltration.eof() ) { @@ -230,7 +230,7 @@ Bitmap_cubical_complex_periodic_boundary_conditions_base::Bitmap_cubical_comp 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_begin() ; it != this->top_dimensional_cells_end() ; ++it ) + 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; diff --git a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp index b7a1c8b6..35c54ade 100644 --- a/src/Bitmap_cubical_complex/test/Bitmap_test.cpp +++ b/src/Bitmap_cubical_complex/test/Bitmap_test.cpp @@ -94,13 +94,13 @@ BOOST_AUTO_TEST_CASE(topDimensionalCellsIterator_test) { int i = 0; for (Bitmap_cubical_complex< Bitmap_cubical_complex_base >::Top_dimensional_cells_iterator - it = increasing.top_dimensional_cells_begin(); it != increasing.top_dimensional_cells_end(); ++it) { + 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 - it = hole.top_dimensional_cells_begin(); it != hole.top_dimensional_cells_end(); ++it) { + 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; } @@ -1229,7 +1229,7 @@ BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical int bd_it = 0; int cbd_it = 0; - Bitmap_cubical_complex_base::All_cells_iterator_range range(&ba); + 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 ) ); @@ -1415,7 +1415,7 @@ BOOST_AUTO_TEST_CASE(all_cells_iterator_and_boundary_iterators_in_Bitmap_cubical int bd_it = 0; int cbd_it = 0; - Bitmap_cubical_complex_base::All_cells_iterator_range range(&ba); + 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 ) ); @@ -1481,7 +1481,7 @@ BOOST_AUTO_TEST_CASE(Top_dimensional_cells_iterator_range_check) Bitmap_cubical_complex_base ba( sizes , data ); int i = 0; - Bitmap_cubical_complex_base::Top_dimensional_cells_iterator_range range(&ba); + 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 ) ); -- 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') 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 From 019a4fd1f7e624603f85740cbec859f3daab39d4 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 29 Mar 2016 19:33:05 +0000 Subject: Add include numeric for std::iota git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1076 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 6bb361c7ff62c5a8812db125cfd0375d64696504 --- src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Bitmap_cubical_complex') 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 1fd36914..adfe33b5 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -30,6 +30,7 @@ #include // for pair<> #include // for sort #include +#include // for iota namespace Gudhi { -- cgit v1.2.3 From c3f3b627da09dc85616ae4a43787ea5f1fdeaf1f Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 30 Mar 2016 05:45:58 +0000 Subject: Fix cppcheck/cpplint Add TBB for parallel sort git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1077 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8d4692b14e59bf7a6556bc7f69dbdc18582d6c0d --- .../include/gudhi/Bitmap_cubical_complex.h | 16 +- .../include/gudhi/Bitmap_cubical_complex/counter.h | 244 +++++++++------------ .../include/gudhi/Bitmap_cubical_complex_base.h | 40 ++-- ...cal_complex_periodic_boundary_conditions_base.h | 2 +- 4 files changed, 137 insertions(+), 165 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 adfe33b5..86bfbd56 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -26,6 +26,10 @@ #include #include +#ifdef GUDHI_USE_TBB +#include +#endif + #include #include // for pair<> #include // for sort @@ -129,7 +133,7 @@ class Bitmap_cubical_complex : public T { /** * Destructor of the Bitmap_cubical_complex class. **/ - virtual ~Bitmap_cubical_complex(){} + virtual ~Bitmap_cubical_complex() {} //*********************************************// // Other 'easy' functions @@ -259,7 +263,7 @@ class Bitmap_cubical_complex : public T { public: Filtration_simplex_iterator(Bitmap_cubical_complex* b) : b(b), position(0) { } - Filtration_simplex_iterator() : b(NULL) { } + Filtration_simplex_iterator() : b(NULL), position(0) { } Filtration_simplex_iterator operator++() { if (globalDbg) { @@ -537,9 +541,11 @@ void Bitmap_cubical_complex::initialize_simplex_associated_to_key() { } 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)); +#ifdef GUDHI_USE_TBB + tbb::parallel_sort(filtration_vect_, is_before_in_filtration(this)); +#else + std::sort(simplex_associated_to_key.begin(), simplex_associated_to_key.end(), is_before_in_filtration(this)); +#endif // we still need to deal here with a key_associated_to_simplex: for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) 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 index c13d96e1..266ce051 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex/counter.h @@ -20,152 +20,124 @@ * along with this program. If not, see . */ -#pragma once +#ifndef BITMAP_CUBICAL_COMPLEX_COUNTER_H_ +#define BITMAP_CUBICAL_COMPLEX_COUNTER_H_ #include #include -using namespace std; +namespace Gudhi { -namespace Gudhi -{ - -namespace Cubical_complex -{ +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(const std::vector& 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(const std::vector< unsigned >& beginn , const 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( const 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; + * 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(const std::vector& endd) : begin(endd.size(), 0), end(endd), current(endd.size(), 0) { } + + /** + * 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(const std::vector< unsigned >& beginn, const 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; } - /** - * 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; + if (i == this->end.size())return false; + ++this->current[i]; + for (size_t j = 0; j != i; ++j) { + this->current[j] = this->begin[j]; } - - /** - * 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; + 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(const 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); + } } -private: - std::vector< unsigned > begin; - std::vector< unsigned > end; - std::vector< unsigned > current; + 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() << 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 +} // namespace Cubical_complex + +} // namespace Gudhi + +#endif // BITMAP_CUBICAL_COMPLEX_COUNTER_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 62776019..d858f3c5 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 @@ -204,7 +204,7 @@ class Bitmap_cubical_complex_base { } All_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: ++this->counter; return *this; } @@ -317,14 +317,13 @@ class Bitmap_cubical_complex_base { **/ 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 ); + // 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: + // 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; @@ -499,7 +498,7 @@ void Bitmap_cubical_complex_base::put_data_to_bins(size_t number_of_bins) { 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: + // 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; @@ -518,7 +517,7 @@ void Bitmap_cubical_complex_base::put_data_to_bins(T diameter_of_bin) { 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: + // 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; @@ -542,7 +541,7 @@ std::pair< T, T > Bitmap_cubical_complex_base::min_max_filtration() { } template -ostream& operator<<(ostream & out, const Bitmap_cubical_complex_base& b) { +std::ostream& operator<<(std::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 << " "; @@ -565,16 +564,13 @@ void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells 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." << 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."); + 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." + << 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); @@ -610,7 +606,6 @@ void Bitmap_cubical_complex_base::read_perseus_style_file(const char* perseus 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; @@ -738,8 +733,7 @@ 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 is_this_cell_considered(this->data.size(), false); size_t size_to_reserve = 1; @@ -749,8 +743,8 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() { 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. + // 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()); @@ -799,7 +793,7 @@ bool compareFirstElementsOfTuples(const std::pair< std::pair< T, size_t >, char if (first.first.first > second.first.first) { return false; } - //in this case first.first.first == second.first.first, so we need to compare dimensions + // in this case first.first.first == second.first.first, so we need to compare dimensions return first.second < second.second; } } 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 2c0d77fe..8afa342e 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 @@ -84,7 +84,7 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c /** * Destructor of the Bitmap_cubical_complex_periodic_boundary_conditions_base class. **/ - virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base(){} + virtual ~Bitmap_cubical_complex_periodic_boundary_conditions_base() {} // overwritten methods co compute boundary and coboundary /** -- cgit v1.2.3 From bea7dab826c2dcff4632df3d99480adc94be3f8d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 30 Mar 2016 06:14:43 +0000 Subject: cpplint/cppcheck fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1078 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 794e42d37fa8417489d92d6d67d05399225d6fcd --- .../include/gudhi/Bitmap_cubical_complex.h | 2 + .../include/gudhi/Bitmap_cubical_complex_base.h | 77 +++++++++++++--------- ...cal_complex_periodic_boundary_conditions_base.h | 19 +++--- 3 files changed, 59 insertions(+), 39 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 86bfbd56..de463d8e 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -285,6 +285,7 @@ class Bitmap_cubical_complex : public T { } this->b = rhs.b; this->position = rhs.position; + return (*this); } bool operator==(const Filtration_simplex_iterator& rhs)const { @@ -454,6 +455,7 @@ class Bitmap_cubical_complex : public T { this->b = rhs.b; this->position = rhs.position; this->dimension = rhs.dimension; + return (*this); } bool operator==(const Skeleton_simplex_iterator& rhs)const { 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 d858f3c5..2258b581 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 @@ -140,7 +140,7 @@ class Bitmap_cubical_complex_base { * 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. + void impose_lower_star_filtration(); // assume that top dimensional cells are already set. /** * Returns dimension of a complex. @@ -198,7 +198,6 @@ class Bitmap_cubical_complex_base { **/ class All_cells_iterator : std::iterator< std::input_iterator_tag, T > { public: - All_cells_iterator() { this->counter = 0; } @@ -215,7 +214,7 @@ class Bitmap_cubical_complex_base { return result; } - All_cells_iterator operator=(const All_cells_iterator& rhs) { + All_cells_iterator& operator=(const All_cells_iterator& rhs) { this->counter = rhs.counter; return *this; } @@ -230,8 +229,10 @@ class Bitmap_cubical_complex_base { } /* - * 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 + * 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*() { @@ -264,8 +265,7 @@ class Bitmap_cubical_complex_base { **/ class All_cells_range { public: - - All_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }; + All_cells_range(Bitmap_cubical_complex_base* b) : b(b) { } All_cells_iterator begin() { return b->all_cells_iterator_begin(); @@ -344,7 +344,7 @@ class Bitmap_cubical_complex_base { return result; } - Top_dimensional_cells_iterator operator=(const Top_dimensional_cells_iterator& rhs) { + Top_dimensional_cells_iterator& operator=(const Top_dimensional_cells_iterator& rhs) { this->counter = rhs.counter; this->b = rhs.b; return *this; @@ -364,8 +364,10 @@ class Bitmap_cubical_complex_base { } /* - * 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 + * 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*() { @@ -416,8 +418,7 @@ class Bitmap_cubical_complex_base { **/ class Top_dimensional_cells_range { public: - - Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) { }; + Top_dimensional_cells_range(Bitmap_cubical_complex_base* b) : b(b) { } Top_dimensional_cells_iterator begin() { return b->top_dimensional_cells_iterator_begin(); @@ -485,10 +486,13 @@ class Bitmap_cubical_complex_base { 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); + 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); + Bitmap_cubical_complex_base(const std::vector& dimensions, + const std::vector& top_dimensional_cells, + std::vector directions); }; template @@ -556,7 +560,8 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base } 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) { +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; @@ -568,7 +573,7 @@ void Bitmap_cubical_complex_base::setup_bitmap_based_on_top_dimensional_cells << ", 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." << std::endl; - throw ("Error in constructor Bitmap_cubical_complex_base( std::vector sizes_in_following_directions," + 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."); } @@ -591,7 +596,7 @@ Bitmap_cubical_complex_base::Bitmap_cubical_complex_base template void Bitmap_cubical_complex_base::read_perseus_style_file(const char* perseus_style_file) { bool dbg = false; - std::ifstream inFiltration, inIds; + std::ifstream inFiltration; inFiltration.open(perseus_style_file); unsigned dimensionOfData; inFiltration >> dimensionOfData; @@ -634,23 +639,30 @@ void Bitmap_cubical_complex_base::read_perseus_style_file(const char* perseus } 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. +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 boundary + // 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. +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 boundary + // 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. +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 boundary + // conditions. + // It ignores the last parameter of the function. this->setup_bitmap_based_on_top_dimensional_cells_list(dimensions, top_dimensional_cells); } @@ -663,7 +675,7 @@ 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. + // Speed traded of for memory. Check if it is better in practice. boundary_elements.reserve(this->dimension()*2); size_t cell1 = cell; @@ -763,14 +775,17 @@ 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) { - 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; + 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; + std::cerr << "Setting the value of a cell : " << bd[boundaryIt] << " to : " + << this->data[ indices_to_consider[i] ] << std::endl; getchar(); } } @@ -798,8 +813,8 @@ bool compareFirstElementsOfTuples(const std::pair< std::pair< T, size_t >, char } } -} // namespace Cubical_complex +} // namespace Cubical_complex -} // namespace Gudhi +} // 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 8afa342e..a446c0e8 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 @@ -44,9 +44,10 @@ namespace Cubical_complex { * @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. -*/ + * 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: @@ -88,14 +89,16 @@ class Bitmap_cubical_complex_periodic_boundary_conditions_base : public Bitmap_c // 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. + * 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; + 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. + * 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; + 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; @@ -132,7 +135,7 @@ void Bitmap_cubical_complex_periodic_boundary_conditions_base::construct_comp 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) { + for (auto it = this->top_dimensional_cells_iterator_begin(); it != this->top_dimensional_cells_iterator_end(); ++it) { this->get_cell_data(*it) = topDimensionalCells[i]; ++i; } -- cgit v1.2.3 From dea986187f3a214db300a909f8f8a02cf3d9014d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 30 Mar 2016 06:31:24 +0000 Subject: cpplint/cppcheck fixes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/bitmap@1079 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 812004416560ad653025d02ea7ff05677ec5b3fc --- src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h | 6 +++--- .../include/gudhi/Bitmap_cubical_complex_base.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/Bitmap_cubical_complex') 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 de463d8e..7bf9617e 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -397,7 +397,8 @@ class Bitmap_cubical_complex : public T { } // 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."); + 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]); } @@ -550,8 +551,7 @@ void Bitmap_cubical_complex::initialize_simplex_associated_to_key() { #endif // we still need to deal here with a key_associated_to_simplex: - for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) - { + for ( size_t i = 0 ; i != simplex_associated_to_key.size() ; ++i ) { this->key_associated_to_simplex[ simplex_associated_to_key[i] ] = i; } } 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 2258b581..7294da98 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 @@ -779,7 +779,6 @@ void Bitmap_cubical_complex_base::impose_lower_star_filtration() { << " 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] ]; -- cgit v1.2.3