From ef61b085afd77976a2c7fc5dfa13bc4b293b4f95 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 28 Sep 2017 13:43:58 +0000 Subject: Remove python rips_complex construction from files as it can lead to errors with correlation matrix Add examples for doxygen Cythonization of rips correlation matrix git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@2727 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8aae33839fa27f9d26897e625904671b2c05e0e7 --- src/common/doc/main_page.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/common') diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index 1a7994a5..91535ee6 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -456,11 +456,15 @@ make doxygen * @example Persistent_cohomology/persistence_from_simple_simplex_tree.cpp * @example Persistent_cohomology/plain_homology.cpp * @example Persistent_cohomology/rips_multifield_persistence.cpp + * @example Persistent_cohomology/rips_correlation_matrix_persistence.cpp * @example Persistent_cohomology/rips_distance_matrix_persistence.cpp * @example Persistent_cohomology/rips_persistence.cpp * @example Persistent_cohomology/custom_persistence_sort.cpp * @example Persistent_cohomology/rips_persistence_step_by_step.cpp + * @example Rips_complex/example_one_skeleton_rips_from_correlation_matrix.cpp + * @example Rips_complex/example_one_skeleton_rips_from_distance_matrix.cpp * @example Rips_complex/example_one_skeleton_rips_from_points.cpp + * @example Rips_complex/example_rips_complex_from_csv_distance_matrix_file.cpp * @example Rips_complex/example_rips_complex_from_off_file.cpp * @example Simplex_tree/mini_simplex_tree.cpp * @example Simplex_tree/simple_simplex_tree.cpp -- cgit v1.2.3 From 0729a55a67503c068e4843c63930d6b29e76f7ac Mon Sep 17 00:00:00 2001 From: pdlotko Date: Fri, 3 Nov 2017 05:10:17 +0000 Subject: a few more changes git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@2823 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: d12b2413620003883e82b3022f8d933aa05e2856 --- .../rips_correlation_matrix_persistence.cpp | 56 +++++++- ...e_one_skeleton_rips_from_correlation_matrix.cpp | 15 +- src/common/include/gudhi/file_writer.h | 157 +++++++++++++++++++++ 3 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 src/common/include/gudhi/file_writer.h (limited to 'src/common') diff --git a/src/Persistent_cohomology/example/rips_correlation_matrix_persistence.cpp b/src/Persistent_cohomology/example/rips_correlation_matrix_persistence.cpp index 41cf915a..6f12dada 100644 --- a/src/Persistent_cohomology/example/rips_correlation_matrix_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_correlation_matrix_persistence.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -38,6 +39,7 @@ using Rips_complex = Gudhi::rips_complex::Rips_complex; using Field_Zp = Gudhi::persistent_cohomology::Field_Zp; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; using Correlation_matrix = std::vector>; +using intervals_common = Gudhi::Persistence_interval_common< double , int >; void program_options(int argc, char* argv[], std::string& csv_matrix_file, std::string& filediag, Filtration_value& threshold, int& dim_max, int& p, Filtration_value& min_persistence); @@ -66,6 +68,13 @@ int main(int argc, char* argv[]) { } } + //If the treshold, being minimal corelation is in the range [0,1], + //change it to 1-threshold + if ( ( threshold>=0 ) && ( threshold<=1 ) ) + { + threshold = 1-threshold; + } + Rips_complex rips_complex_from_file(correlations, threshold); // Construct the Rips complex in a Simplex Tree @@ -82,15 +91,34 @@ int main(int argc, char* argv[]) { Persistent_cohomology pcoh(simplex_tree); // initializes the coefficient field for homology pcoh.init_coefficients(p); - + //compute persistence pcoh.compute_persistent_cohomology(min_persistence); - - // Output the diagram in filediag + + + //invert the persistence diagram + auto pairs = pcoh.get_persistent_pairs(); + std::vector< intervals_common > processed_persistence_intervals; + processed_persistence_intervals.reserve( pairs.size() ); + for (auto pair :pairs ) + { + double birth = 1-simplex_tree.filtration( get<0>(pair) ); + double death = 1-simplex_tree.filtration( get<1>(pair) ); + unsigned dimension = (unsigned)simplex_tree.dimension( get<0>(pair) ); + int field = get<2>(pair); + processed_persistence_intervals.push_back( + intervals_common(birth, death,dimension,field) + ); + } + + //sort the processed intervals: + std::sort( processed_persistence_intervals.begin() , processed_persistence_intervals.end() ); + + //and write them to a file if (filediag.empty()) { - pcoh.output_diagram(); + write_persistence_intervals_to_stream(processed_persistence_intervals); } else { std::ofstream out(filediag); - pcoh.output_diagram(out); + write_persistence_intervals_to_stream(processed_persistence_intervals,out); out.close(); } return 0; @@ -103,6 +131,9 @@ void program_options(int argc, char* argv[], std::string& csv_matrix_file, std:: hidden.add_options()( "input-file", po::value(&csv_matrix_file), "Name of file containing a distance matrix. Can be square or lower triangular matrix. Separator is ';'."); + hidden.add_options() + ("input-file", po::value(&csv_matrix_file), + "Name of file containing a corelation matrix. Can be square or lower triangular matrix. Separator is ';'."); po::options_description visible("Allowed options", 100); visible.add_options()("help,h", "produce help message")( @@ -118,6 +149,19 @@ void program_options(int argc, char* argv[], std::string& csv_matrix_file, std:: "min-persistence,m", po::value(&min_persistence), "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length " "intervals"); + visible.add_options() + ("help,h", "produce help message") + ("output-file,o", po::value(&filediag)->default_value(std::string()), + "Name of file in which the persistence diagram is written. Default print in std::cout") + ("min-edge-corelation,c", + po::value(&threshold)->default_value(std::numeric_limits::infinity()), + "Minimal corelation of an edge for the Rips complex construction.") + ("cpx-dimension,d", po::value(&dim_max)->default_value(1), + "Maximal dimension of the Rips complex we want to compute.") + ("field-charac,p", po::value(&p)->default_value(11), + "Characteristic p of the coefficient field Z/pZ for computing homology.") + ("min-persistence,m", po::value(&min_persistence), + "Minimal lifetime of homology feature to be recorded. Default is 0. Enter a negative value to see zero length intervals"); po::positional_options_description pos; pos.add("input-file", 1); @@ -132,7 +176,7 @@ void program_options(int argc, char* argv[], std::string& csv_matrix_file, std:: if (vm.count("help") || !vm.count("input-file")) { std::cout << std::endl; std::cout << "Compute the persistent homology with coefficient field Z/pZ \n"; - std::cout << "of a Rips complex defined on a set of distance matrix.\n \n"; + std::cout << "of a Rips complex defined on a corelation matrix.\n \n"; std::cout << "The output diagram contains one bar per line, written with the convention: \n"; std::cout << " p dim b d \n"; std::cout << "where dim is the dimension of the homological feature,\n"; diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp index ae347a00..d1ccbf31 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp @@ -42,17 +42,28 @@ int main() { } //----------------------------------------------------------------------------- - // Now the correlation matrix is really the distance matrix and can be processed further. + // Now the correlation matrix is a distance matrix and can be processed further. //----------------------------------------------------------------------------- Distance_matrix distances = correlations; + //------------------------------------------------------------------------------ + //Note that this treshold mean that the points in the distance 1, i.e. corelation + //0 will be connected. + //------------------------------------------------------------------------------ double threshold = 1.0; + + Rips_complex rips_complex_from_points(distances, threshold); Simplex_tree stree; rips_complex_from_points.create_complex(stree, 1); // ---------------------------------------------------------------------------- - // Display information about the one skeleton Rips complex + // Display information about the one skeleton Rips complex. Note that + // the filtration displayed here comes from the distance matrix computed + // above, which is 1 - initial correlation matrix. Only this way, we obtain + // a complex with filtration. If a correlation matrix is used instead, we would + // have a reverse filtration (i.e. filtration of boundary of each simplex S + // is greater or equal to the filtration of S). // ---------------------------------------------------------------------------- std::cout << "Rips complex is of dimension " << stree.dimension() << " - " << stree.num_simplices() << " simplices - " << stree.num_vertices() << " vertices." << std::endl; diff --git a/src/common/include/gudhi/file_writer.h b/src/common/include/gudhi/file_writer.h new file mode 100644 index 00000000..1b59ae46 --- /dev/null +++ b/src/common/include/gudhi/file_writer.h @@ -0,0 +1,157 @@ +/* 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) 2017 Swansea University, UK + * + * 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 FILE_WRITER_ +#define FILE_WRITER_ + +#include +#include +#include + +namespace Gudhi { + + +/** +* This is a class to store persistence intervals. Its main purpose is to +* exchange data in between different packages and provide unified way +* of writing a collection of persistence intervals to file. +**/ +template +class Persistence_interval_common +{ +public: + Persistence_interval_common( Filtration_type birth , Filtration_type death ): + birth_(birth),death_(death),dimension_(std::numeric_limits::max), + Arith_element_(std::numeric_limits::max() ){} + + Persistence_interval_common( Filtration_type birth , Filtration_type death, + unsigned dim ): + birth_(birth),death_(death),dimension_(dim), + Arith_element_(std::numeric_limits::max()){} + + Persistence_interval_common( Filtration_type birth , Filtration_type death, + unsigned dim , Coefficient_field field ): + birth_(birth),death_(death),dimension_(dim), + Arith_element_(field){} + + + inline bool operator == ( const Persistence_interval_common &i2) + { + return ( + (this->birth_ == i2.birth_) && (this->death_ == i2.death_) && + (this->dimension_ == i2.dimension_) && (this->Arith_element_ == i2.Arith_element_) + ); + } + + inline bool operator != ( const Persistence_interval_common &i2) + { + return (!((*this)==i2)); + } + + + /** + * Note that this operator do not take Arith_element into account when doing comparisions. + **/ + inline bool operator < ( const Persistence_interval_common &i2) + { + if ( this->birth_ < i2.birth_ ) + { + return true; + } + else + { + if ( this->birth_ > i2.birth_ ) + { + return false; + } + else + { + //in this case this->birth_ == i2.birth_ + if ( this->death_ > i2.death_ ) + { + return true; + } + else + { + if ( this->death_ < i2.death_ ) + { + return false; + } + else + { + //in this case this->death_ == i2.death_ + if ( this->dimension_ < i2.dimension_ ) + { + return true; + } + else + { + //in this case this->dimension >= i2.dimension + return false; + } + } + } + } + } + } + + friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) + { + if ( it.Arith_element_ != std::numeric_limits::max() ) + { + out << it.Arith_element_ << " "; + } + if ( it.dimension_ != std::numeric_limits::max() ) + { + out << it.dimension_ << " "; + } + out << it.birth_ << " " << it.death_ << " "; + return out; + } + +private: + Filtration_type birth_; + Filtration_type death_; + unsigned dimension_; + Coefficient_field Arith_element_; +};//Persistence_interval_common + + +/** + * This function write a vector to a stream +**/ +template +void write_persistence_intervals_to_stream( +const std::vector< Persistence_interval_common >& intervals, + std::ostream& out = std::cout ) +{ + for ( auto interval : intervals ) + { + out << interval << std::endl; + } +}//write_persistence_intervals_to_stream + + + +} + +#endif //FILE_WRITER_ -- cgit v1.2.3 From fe97343e5b53fe9d93e6aab3312021c53f2f0923 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 8 Feb 2018 09:57:19 +0000 Subject: Commit to remove one file. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@3231 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 5795ef0322c1ba328e8bee068009a27f18b7224c --- src/common/include/gudhi/file_writer.h | 19 +-- .../include/gudhi/writing_persistence_to_file.h | 158 +++++++++++++++++++++ 2 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 src/common/include/gudhi/writing_persistence_to_file.h (limited to 'src/common') diff --git a/src/common/include/gudhi/file_writer.h b/src/common/include/gudhi/file_writer.h index 1b59ae46..53c83533 100644 --- a/src/common/include/gudhi/file_writer.h +++ b/src/common/include/gudhi/file_writer.h @@ -41,24 +41,24 @@ class Persistence_interval_common public: Persistence_interval_common( Filtration_type birth , Filtration_type death ): birth_(birth),death_(death),dimension_(std::numeric_limits::max), - Arith_element_(std::numeric_limits::max() ){} + arith_element_(std::numeric_limits::max() ){} Persistence_interval_common( Filtration_type birth , Filtration_type death, unsigned dim ): birth_(birth),death_(death),dimension_(dim), - Arith_element_(std::numeric_limits::max()){} + arith_element_(std::numeric_limits::max()){} Persistence_interval_common( Filtration_type birth , Filtration_type death, unsigned dim , Coefficient_field field ): birth_(birth),death_(death),dimension_(dim), - Arith_element_(field){} + arith_element_(field){} inline bool operator == ( const Persistence_interval_common &i2) { return ( (this->birth_ == i2.birth_) && (this->death_ == i2.death_) && - (this->dimension_ == i2.dimension_) && (this->Arith_element_ == i2.Arith_element_) + (this->dimension_ == i2.dimension_) && (this->arith_element_ == i2.arith_element_) ); } @@ -116,9 +116,9 @@ public: friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) { - if ( it.Arith_element_ != std::numeric_limits::max() ) + if ( it.arith_element_ != std::numeric_limits::max() ) { - out << it.Arith_element_ << " "; + out << it.arith_element_ << " "; } if ( it.dimension_ != std::numeric_limits::max() ) { @@ -132,7 +132,7 @@ private: Filtration_type birth_; Filtration_type death_; unsigned dimension_; - Coefficient_field Arith_element_; + Coefficient_field arith_element_; };//Persistence_interval_common @@ -141,12 +141,13 @@ private: **/ template void write_persistence_intervals_to_stream( -const std::vector< Persistence_interval_common >& intervals, +//const std::vector< Persistence_interval_common >& intervals, + std::ostream& out = std::cout ) { for ( auto interval : intervals ) { - out << interval << std::endl; + out << interval << "\n"; } }//write_persistence_intervals_to_stream diff --git a/src/common/include/gudhi/writing_persistence_to_file.h b/src/common/include/gudhi/writing_persistence_to_file.h new file mode 100644 index 00000000..53c83533 --- /dev/null +++ b/src/common/include/gudhi/writing_persistence_to_file.h @@ -0,0 +1,158 @@ +/* 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) 2017 Swansea University, UK + * + * 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 FILE_WRITER_ +#define FILE_WRITER_ + +#include +#include +#include + +namespace Gudhi { + + +/** +* This is a class to store persistence intervals. Its main purpose is to +* exchange data in between different packages and provide unified way +* of writing a collection of persistence intervals to file. +**/ +template +class Persistence_interval_common +{ +public: + Persistence_interval_common( Filtration_type birth , Filtration_type death ): + birth_(birth),death_(death),dimension_(std::numeric_limits::max), + arith_element_(std::numeric_limits::max() ){} + + Persistence_interval_common( Filtration_type birth , Filtration_type death, + unsigned dim ): + birth_(birth),death_(death),dimension_(dim), + arith_element_(std::numeric_limits::max()){} + + Persistence_interval_common( Filtration_type birth , Filtration_type death, + unsigned dim , Coefficient_field field ): + birth_(birth),death_(death),dimension_(dim), + arith_element_(field){} + + + inline bool operator == ( const Persistence_interval_common &i2) + { + return ( + (this->birth_ == i2.birth_) && (this->death_ == i2.death_) && + (this->dimension_ == i2.dimension_) && (this->arith_element_ == i2.arith_element_) + ); + } + + inline bool operator != ( const Persistence_interval_common &i2) + { + return (!((*this)==i2)); + } + + + /** + * Note that this operator do not take Arith_element into account when doing comparisions. + **/ + inline bool operator < ( const Persistence_interval_common &i2) + { + if ( this->birth_ < i2.birth_ ) + { + return true; + } + else + { + if ( this->birth_ > i2.birth_ ) + { + return false; + } + else + { + //in this case this->birth_ == i2.birth_ + if ( this->death_ > i2.death_ ) + { + return true; + } + else + { + if ( this->death_ < i2.death_ ) + { + return false; + } + else + { + //in this case this->death_ == i2.death_ + if ( this->dimension_ < i2.dimension_ ) + { + return true; + } + else + { + //in this case this->dimension >= i2.dimension + return false; + } + } + } + } + } + } + + friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) + { + if ( it.arith_element_ != std::numeric_limits::max() ) + { + out << it.arith_element_ << " "; + } + if ( it.dimension_ != std::numeric_limits::max() ) + { + out << it.dimension_ << " "; + } + out << it.birth_ << " " << it.death_ << " "; + return out; + } + +private: + Filtration_type birth_; + Filtration_type death_; + unsigned dimension_; + Coefficient_field arith_element_; +};//Persistence_interval_common + + +/** + * This function write a vector to a stream +**/ +template +void write_persistence_intervals_to_stream( +//const std::vector< Persistence_interval_common >& intervals, + + std::ostream& out = std::cout ) +{ + for ( auto interval : intervals ) + { + out << interval << "\n"; + } +}//write_persistence_intervals_to_stream + + + +} + +#endif //FILE_WRITER_ -- cgit v1.2.3 From 82764fe1fa117f5a3d1cce0eb7dc7dddd7af974f Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 8 Feb 2018 09:57:39 +0000 Subject: The file has been removed. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@3232 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 4e6e6b2c1939506e19bb76a7bb507f869160577b --- src/common/include/gudhi/file_writer.h | 158 --------------------------------- 1 file changed, 158 deletions(-) delete mode 100644 src/common/include/gudhi/file_writer.h (limited to 'src/common') diff --git a/src/common/include/gudhi/file_writer.h b/src/common/include/gudhi/file_writer.h deleted file mode 100644 index 53c83533..00000000 --- a/src/common/include/gudhi/file_writer.h +++ /dev/null @@ -1,158 +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) 2017 Swansea University, UK - * - * 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 FILE_WRITER_ -#define FILE_WRITER_ - -#include -#include -#include - -namespace Gudhi { - - -/** -* This is a class to store persistence intervals. Its main purpose is to -* exchange data in between different packages and provide unified way -* of writing a collection of persistence intervals to file. -**/ -template -class Persistence_interval_common -{ -public: - Persistence_interval_common( Filtration_type birth , Filtration_type death ): - birth_(birth),death_(death),dimension_(std::numeric_limits::max), - arith_element_(std::numeric_limits::max() ){} - - Persistence_interval_common( Filtration_type birth , Filtration_type death, - unsigned dim ): - birth_(birth),death_(death),dimension_(dim), - arith_element_(std::numeric_limits::max()){} - - Persistence_interval_common( Filtration_type birth , Filtration_type death, - unsigned dim , Coefficient_field field ): - birth_(birth),death_(death),dimension_(dim), - arith_element_(field){} - - - inline bool operator == ( const Persistence_interval_common &i2) - { - return ( - (this->birth_ == i2.birth_) && (this->death_ == i2.death_) && - (this->dimension_ == i2.dimension_) && (this->arith_element_ == i2.arith_element_) - ); - } - - inline bool operator != ( const Persistence_interval_common &i2) - { - return (!((*this)==i2)); - } - - - /** - * Note that this operator do not take Arith_element into account when doing comparisions. - **/ - inline bool operator < ( const Persistence_interval_common &i2) - { - if ( this->birth_ < i2.birth_ ) - { - return true; - } - else - { - if ( this->birth_ > i2.birth_ ) - { - return false; - } - else - { - //in this case this->birth_ == i2.birth_ - if ( this->death_ > i2.death_ ) - { - return true; - } - else - { - if ( this->death_ < i2.death_ ) - { - return false; - } - else - { - //in this case this->death_ == i2.death_ - if ( this->dimension_ < i2.dimension_ ) - { - return true; - } - else - { - //in this case this->dimension >= i2.dimension - return false; - } - } - } - } - } - } - - friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) - { - if ( it.arith_element_ != std::numeric_limits::max() ) - { - out << it.arith_element_ << " "; - } - if ( it.dimension_ != std::numeric_limits::max() ) - { - out << it.dimension_ << " "; - } - out << it.birth_ << " " << it.death_ << " "; - return out; - } - -private: - Filtration_type birth_; - Filtration_type death_; - unsigned dimension_; - Coefficient_field arith_element_; -};//Persistence_interval_common - - -/** - * This function write a vector to a stream -**/ -template -void write_persistence_intervals_to_stream( -//const std::vector< Persistence_interval_common >& intervals, - - std::ostream& out = std::cout ) -{ - for ( auto interval : intervals ) - { - out << interval << "\n"; - } -}//write_persistence_intervals_to_stream - - - -} - -#endif //FILE_WRITER_ -- cgit v1.2.3 From b5667b282e8cee9e1d2bfcf90bdfbbf2bc0030b2 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 8 Feb 2018 10:00:57 +0000 Subject: random commit. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@3233 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9a3ccdd8a000bd3fd79bab61b35e50bd707cfb29 --- .../include/gudhi/Bitmap_cubical_complex.h | 2 +- ...e_one_skeleton_rips_from_correlation_matrix.cpp | 23 +++++++++++----------- .../include/gudhi/writing_persistence_to_file.h | 10 +++++----- 3 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src/common') 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 969daba6..770eb55f 100644 --- a/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h +++ b/src/Bitmap_cubical_complex/include/gudhi/Bitmap_cubical_complex.h @@ -383,7 +383,7 @@ class Bitmap_cubical_complex : public T { std::vector 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; + std::cerr << "bdry.size() : " << bdry.size() << "\n"; } // this method returns two first elements from the boundary of sh. if (bdry.size() < 2) diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp index 0da1dc20..f66c4b04 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp @@ -31,26 +31,27 @@ int main() { // ---------------------------------------------------------------------------- // Convert correlation matrix to a distance matrix: // ---------------------------------------------------------------------------- + double threshold = 0; for (size_t i = 0; i != correlations.size(); ++i) { for (size_t j = 0; j != correlations[i].size(); ++j) { - correlations[i][j] = 1 - correlations[i][j]; - if (correlations[i][j] < 0) { - std::cerr << "The input matrix is not a correlation matrix. \n"; - throw "The input matrix is not a correlation matrix. \n"; - } + //Here we check if our data comes from corelation matrix. + if ( (correlations[i][j]<-1) || (correlations[i][j]>1) ) + { + std::cerr << "The input matrix is not a correlation matrix. The program will now terminate.\n"; + throw "The input matrix is not a correlation matrix. The program will now terminate.\n"; + } + correlations[i][j] = 1 - correlations[i][j]; } + //Here we make sure that we will get the treshold value equal to maximal + //distance in the matrix. + if ( correlations[i][j] > threshold )threshold = correlations[i][j]; } //----------------------------------------------------------------------------- // Now the correlation matrix is a distance matrix and can be processed further. //----------------------------------------------------------------------------- Distance_matrix distances = correlations; - - //------------------------------------------------------------------------------ - // Note that this treshold mean that the points in the distance 1, i.e. corelation - // 0 will be connected. - //------------------------------------------------------------------------------ - double threshold = 1.0; + Rips_complex rips_complex_from_points(distances, threshold); diff --git a/src/common/include/gudhi/writing_persistence_to_file.h b/src/common/include/gudhi/writing_persistence_to_file.h index 53c83533..5767c06e 100644 --- a/src/common/include/gudhi/writing_persistence_to_file.h +++ b/src/common/include/gudhi/writing_persistence_to_file.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef FILE_WRITER_ -#define FILE_WRITER_ +#ifndef WRITING_PERSISTENCE_TO_FILE_H +#define WRITING_PERSISTENCE_TO_FILE_H #include #include @@ -141,8 +141,8 @@ private: **/ template void write_persistence_intervals_to_stream( -//const std::vector< Persistence_interval_common >& intervals, - +const std::vector< Persistence_interval_common >& intervals, +//TODO: change to ranges when it is clear how to do that. std::ostream& out = std::cout ) { for ( auto interval : intervals ) @@ -155,4 +155,4 @@ void write_persistence_intervals_to_stream( } -#endif //FILE_WRITER_ +#endif //WRITING_PERSISTENCE_TO_FILE_H -- cgit v1.2.3 From 82c0652b06949b0b002781688565d7ecf30f04fe Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 8 Feb 2018 10:37:21 +0000 Subject: Fixed comments from Marc and Vincent. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@3234 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 8b5e08c38cd05512ba8b2824f13a62d35f39bac3 --- ...e_one_skeleton_rips_from_correlation_matrix.cpp | 10 +- .../rips_correlation_matrix_persistence.cpp | 40 ++++---- .../include/gudhi/writing_persistence_to_file.h | 102 ++++++++++++--------- 3 files changed, 86 insertions(+), 66 deletions(-) (limited to 'src/common') diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp index f66c4b04..a34ce15c 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_correlation_matrix.cpp @@ -40,11 +40,11 @@ int main() { std::cerr << "The input matrix is not a correlation matrix. The program will now terminate.\n"; throw "The input matrix is not a correlation matrix. The program will now terminate.\n"; } - correlations[i][j] = 1 - correlations[i][j]; - } - //Here we make sure that we will get the treshold value equal to maximal - //distance in the matrix. - if ( correlations[i][j] > threshold )threshold = correlations[i][j]; + correlations[i][j] = 1 - correlations[i][j]; + //Here we make sure that we will get the treshold value equal to maximal + //distance in the matrix. + if ( correlations[i][j] > threshold )threshold = correlations[i][j]; + } } //----------------------------------------------------------------------------- diff --git a/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp index 3fe0edb0..95bce491 100644 --- a/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp +++ b/src/Rips_complex/utilities/rips_correlation_matrix_persistence.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include @@ -57,28 +57,23 @@ int main(int argc, char* argv[]) { Correlation_matrix correlations = Gudhi::read_lower_triangular_matrix_from_csv_file(csv_matrix_file); + Filtration_value threshold = 0; + // Given a correlation matrix M, we compute component-wise M'[i,j] = 1-M[i,j] to get a distance matrix: for (size_t i = 0; i != correlations.size(); ++i) { for (size_t j = 0; j != correlations[i].size(); ++j) { correlations[i][j] = 1 - correlations[i][j]; - if (correlations[i][j] < 0) { - std::cerr << "The input matrix is not a correlation matrix. \n"; - throw "The input matrix is not a correlation matrix. \n"; + //Here we make sure that the values of corelations lie between -1 and 1. + //If not, we throw an exception. + if ((correlations[i][j] < -1) || (correlations[i][j] > 1)) + { + std::cerr << "The input matrix is not a correlation matrix. The program will now terminate. \n"; + throw "The input matrix is not a correlation matrix. The program will now terminate. \n"; } + if ( correlations[i][j] > threshold ) threshold = correlations[i][j]; } } - Filtration_value threshold; - // If the correlation_min, being minimal corelation is in the range [0,1], - // change it to 1-correlation_min - if ((correlation_min >= 0) && (correlation_min <= 1)) { - threshold = 1 - correlation_min; - } else { - std::cout - << "Wrong value of the treshold corelation (should be between 0 and 1). The program will now terminate.\n"; - return 1; - } - Rips_complex rips_complex_from_file(correlations, threshold); // Construct the Rips complex in a Simplex Tree @@ -95,10 +90,16 @@ int main(int argc, char* argv[]) { Persistent_cohomology pcoh(simplex_tree); // initializes the coefficient field for homology pcoh.init_coefficients(p); - // compute persistence + //compute persistence pcoh.compute_persistent_cohomology(min_persistence); - - // invert the persistence diagram + + + //invert the persistence diagram. The reason for this procedure is the following: + //The input to the program is a corelation matrix M. When processing it, it is + //turned into 1-M and the obtained persistence intervals are in '1-M' units. + //Below we reverse every (birth,death) pair into (1-birth, 1-death) pair + //so that the input and the output to the program is expressed in the same + //units. auto pairs = pcoh.get_persistent_pairs(); std::vector processed_persistence_intervals; processed_persistence_intervals.reserve(pairs.size()); @@ -118,8 +119,7 @@ int main(int argc, char* argv[]) { write_persistence_intervals_to_stream(processed_persistence_intervals); } else { std::ofstream out(filediag); - write_persistence_intervals_to_stream(processed_persistence_intervals, out); - out.close(); + write_persistence_intervals_to_stream(processed_persistence_intervals, out); } return 0; } diff --git a/src/common/include/gudhi/writing_persistence_to_file.h b/src/common/include/gudhi/writing_persistence_to_file.h index 5767c06e..5457cf48 100644 --- a/src/common/include/gudhi/writing_persistence_to_file.h +++ b/src/common/include/gudhi/writing_persistence_to_file.h @@ -39,21 +39,35 @@ template class Persistence_interval_common { public: + /** + * Constructor taking as an input birth and death of the pair. + **/ Persistence_interval_common( Filtration_type birth , Filtration_type death ): birth_(birth),death_(death),dimension_(std::numeric_limits::max), arith_element_(std::numeric_limits::max() ){} + /** + * Constructor taking as an input birth, death and dimension of the pair. + **/ Persistence_interval_common( Filtration_type birth , Filtration_type death, unsigned dim ): birth_(birth),death_(death),dimension_(dim), arith_element_(std::numeric_limits::max()){} + /** + * Constructor taking as an input birth, death, dimension of the pair as well + * as the number p such that this interval is present over Z_p field. + **/ Persistence_interval_common( Filtration_type birth , Filtration_type death, unsigned dim , Coefficient_field field ): birth_(birth),death_(death),dimension_(dim), arith_element_(field){} - + /** + * Operator to compare two persistence pairs. During the comparision all the + * fields: birth, death, dimensiona and arith_element_ are taken into account + * and they all have to be equal for two pairs to be equal. + **/ inline bool operator == ( const Persistence_interval_common &i2) { return ( @@ -62,6 +76,9 @@ public: ); } + /** + * Check if two persistence paris are not equal. + **/ inline bool operator != ( const Persistence_interval_common &i2) { return (!((*this)==i2)); @@ -69,49 +86,52 @@ public: /** + * Operator to compare objects of a type Persistence_interval_common. + * One intervals is smaller than the other if it has lower persistence. * Note that this operator do not take Arith_element into account when doing comparisions. **/ inline bool operator < ( const Persistence_interval_common &i2) - { - if ( this->birth_ < i2.birth_ ) - { - return true; - } - else - { - if ( this->birth_ > i2.birth_ ) - { - return false; - } - else - { - //in this case this->birth_ == i2.birth_ - if ( this->death_ > i2.death_ ) - { - return true; - } - else - { - if ( this->death_ < i2.death_ ) - { - return false; - } - else - { - //in this case this->death_ == i2.death_ - if ( this->dimension_ < i2.dimension_ ) - { - return true; - } - else - { - //in this case this->dimension >= i2.dimension - return false; - } - } - } - } - } + { + return fabs( this->death_-this->birth_ ) < fabs( i2.death_-i2.birth_ ); + //if ( this->birth_ < i2.birth_ ) + //{ + // return true; + //} + //else + //{ + // if ( this->birth_ > i2.birth_ ) + // { + // return false; + // } + // else + // { + // //in this case this->birth_ == i2.birth_ + // if ( this->death_ > i2.death_ ) + // { + // return true; + // } + // else + // { + // if ( this->death_ < i2.death_ ) + // { + // return false; + // } + // else + // { + // //in this case this->death_ == i2.death_ + // if ( this->dimension_ < i2.dimension_ ) + // { + // return true; + // } + // else + // { + // //in this case this->dimension >= i2.dimension + // return false; + // } + // } + // } + // } + //} } friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) -- cgit v1.2.3 From a6b1719067462f93a7ee3b7f8f632b85fe27117d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 3 Apr 2018 08:40:05 +0000 Subject: Add warnings for rips persistence from correlation matrix (points under the diagonal). Use range instead of vector in write_persistence_intervals_to_stream git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_from_correlation_matrix@3326 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ea0fdc32c91f1927c5a9f2a3864360895ce8128a --- src/Rips_complex/doc/Intro_rips_complex.h | 3 + src/Rips_complex/utilities/ripscomplex.md | 5 + .../include/gudhi/writing_persistence_to_file.h | 212 ++++++++------------- src/cython/doc/rips_complex_user.rst | 5 + ...istence_from_correlation_matrix_file_example.py | 5 + 5 files changed, 93 insertions(+), 137 deletions(-) (limited to 'src/common') diff --git a/src/Rips_complex/doc/Intro_rips_complex.h b/src/Rips_complex/doc/Intro_rips_complex.h index 3f02206b..496c4218 100644 --- a/src/Rips_complex/doc/Intro_rips_complex.h +++ b/src/Rips_complex/doc/Intro_rips_complex.h @@ -170,6 +170,9 @@ namespace rips_complex { * All the other constructions discussed for Rips complex for distance matrix can be also performed for Rips complexes * construction from correlation matrices. * + * @warning As persistence diagrams points will be under the diagonal, bottleneck distance and persistence graphical + * tool will not work properly, this is a known issue. + * */ /** @} */ // end defgroup rips_complex diff --git a/src/Rips_complex/utilities/ripscomplex.md b/src/Rips_complex/utilities/ripscomplex.md index 3f064e67..857e6293 100644 --- a/src/Rips_complex/utilities/ripscomplex.md +++ b/src/Rips_complex/utilities/ripscomplex.md @@ -68,3 +68,8 @@ Please refer to data/correlation_matrix/lower_triangular_correlation_matrix.csv **Example** `rips_correlation_matrix_persistence data/distance_matrix/full_square_distance_matrix.csv -r 15 -d 3 -p 3 -m 0` + +**Warning** + +As persistence diagrams points will be under the diagonal, bottleneck distance and persistence graphical tool will not work +properly, this is a known issue. diff --git a/src/common/include/gudhi/writing_persistence_to_file.h b/src/common/include/gudhi/writing_persistence_to_file.h index 5457cf48..5020b5fb 100644 --- a/src/common/include/gudhi/writing_persistence_to_file.h +++ b/src/common/include/gudhi/writing_persistence_to_file.h @@ -29,150 +29,88 @@ namespace Gudhi { - /** -* This is a class to store persistence intervals. Its main purpose is to +* This is a class to store persistence intervals. Its main purpose is to * exchange data in between different packages and provide unified way -* of writing a collection of persistence intervals to file. +* of writing a collection of persistence intervals to file. **/ -template -class Persistence_interval_common -{ -public: - /** - * Constructor taking as an input birth and death of the pair. - **/ - Persistence_interval_common( Filtration_type birth , Filtration_type death ): - birth_(birth),death_(death),dimension_(std::numeric_limits::max), - arith_element_(std::numeric_limits::max() ){} - - /** - * Constructor taking as an input birth, death and dimension of the pair. - **/ - Persistence_interval_common( Filtration_type birth , Filtration_type death, - unsigned dim ): - birth_(birth),death_(death),dimension_(dim), - arith_element_(std::numeric_limits::max()){} - - /** - * Constructor taking as an input birth, death, dimension of the pair as well - * as the number p such that this interval is present over Z_p field. - **/ - Persistence_interval_common( Filtration_type birth , Filtration_type death, - unsigned dim , Coefficient_field field ): - birth_(birth),death_(death),dimension_(dim), - arith_element_(field){} - - /** - * Operator to compare two persistence pairs. During the comparision all the - * fields: birth, death, dimensiona and arith_element_ are taken into account - * and they all have to be equal for two pairs to be equal. - **/ - inline bool operator == ( const Persistence_interval_common &i2) - { - return ( - (this->birth_ == i2.birth_) && (this->death_ == i2.death_) && - (this->dimension_ == i2.dimension_) && (this->arith_element_ == i2.arith_element_) - ); - } - - /** - * Check if two persistence paris are not equal. - **/ - inline bool operator != ( const Persistence_interval_common &i2) - { - return (!((*this)==i2)); - } - - - /** - * Operator to compare objects of a type Persistence_interval_common. - * One intervals is smaller than the other if it has lower persistence. - * Note that this operator do not take Arith_element into account when doing comparisions. - **/ - inline bool operator < ( const Persistence_interval_common &i2) - { - return fabs( this->death_-this->birth_ ) < fabs( i2.death_-i2.birth_ ); - //if ( this->birth_ < i2.birth_ ) - //{ - // return true; - //} - //else - //{ - // if ( this->birth_ > i2.birth_ ) - // { - // return false; - // } - // else - // { - // //in this case this->birth_ == i2.birth_ - // if ( this->death_ > i2.death_ ) - // { - // return true; - // } - // else - // { - // if ( this->death_ < i2.death_ ) - // { - // return false; - // } - // else - // { - // //in this case this->death_ == i2.death_ - // if ( this->dimension_ < i2.dimension_ ) - // { - // return true; - // } - // else - // { - // //in this case this->dimension >= i2.dimension - // return false; - // } - // } - // } - // } - //} - } - - friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) - { - if ( it.arith_element_ != std::numeric_limits::max() ) - { - out << it.arith_element_ << " "; - } - if ( it.dimension_ != std::numeric_limits::max() ) - { - out << it.dimension_ << " "; - } - out << it.birth_ << " " << it.death_ << " "; - return out; - } - -private: - Filtration_type birth_; - Filtration_type death_; - unsigned dimension_; - Coefficient_field arith_element_; -};//Persistence_interval_common +template +class Persistence_interval_common { + public: + /** + * Constructor taking as an input birth and death of the pair. + **/ + Persistence_interval_common(Filtration_type birth, Filtration_type death) + : birth_(birth), + death_(death), + dimension_(std::numeric_limits::max), + arith_element_(std::numeric_limits::max()) {} + /** + * Constructor taking as an input birth, death and dimension of the pair. + **/ + Persistence_interval_common(Filtration_type birth, Filtration_type death, unsigned dim) + : birth_(birth), death_(death), dimension_(dim), arith_element_(std::numeric_limits::max()) {} -/** - * This function write a vector to a stream -**/ -template -void write_persistence_intervals_to_stream( -const std::vector< Persistence_interval_common >& intervals, -//TODO: change to ranges when it is clear how to do that. - std::ostream& out = std::cout ) -{ - for ( auto interval : intervals ) - { - out << interval << "\n"; - } -}//write_persistence_intervals_to_stream + /** +* Constructor taking as an input birth, death, dimension of the pair as well +* as the number p such that this interval is present over Z_p field. +**/ + Persistence_interval_common(Filtration_type birth, Filtration_type death, unsigned dim, Coefficient_field field) + : birth_(birth), death_(death), dimension_(dim), arith_element_(field) {} + + /** + * Operator to compare two persistence pairs. During the comparision all the + * fields: birth, death, dimensiona and arith_element_ are taken into account + * and they all have to be equal for two pairs to be equal. + **/ + inline bool operator==(const Persistence_interval_common& i2) { + return ((this->birth_ == i2.birth_) && (this->death_ == i2.death_) && (this->dimension_ == i2.dimension_) && + (this->arith_element_ == i2.arith_element_)); + } + + /** + * Check if two persistence paris are not equal. + **/ + inline bool operator!=(const Persistence_interval_common& i2) { return (!((*this) == i2)); } + /** + * Operator to compare objects of a type Persistence_interval_common. + * One intervals is smaller than the other if it has lower persistence. + * Note that this operator do not take Arith_element into account when doing comparisions. + **/ + inline bool operator<(const Persistence_interval_common& i2) { + return fabs(this->death_ - this->birth_) < fabs(i2.death_ - i2.birth_); + } + friend std::ostream& operator<<(std::ostream& out, const Persistence_interval_common& it) { + if (it.arith_element_ != std::numeric_limits::max()) { + out << it.arith_element_ << " "; + } + if (it.dimension_ != std::numeric_limits::max()) { + out << it.dimension_ << " "; + } + out << it.birth_ << " " << it.death_ << " "; + return out; + } + private: + Filtration_type birth_; + Filtration_type death_; + unsigned dimension_; + Coefficient_field arith_element_; +}; + +/** + * This function write a vector to a stream +**/ +template +void write_persistence_intervals_to_stream(const Persistence_interval_range& intervals, + std::ostream& out = std::cout) { + for (auto interval : intervals) { + out << interval << "\n"; + } +} } -#endif //WRITING_PERSISTENCE_TO_FILE_H +#endif // WRITING_PERSISTENCE_TO_FILE_H diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst index b80ff7fe..7738aef0 100644 --- a/src/cython/doc/rips_complex_user.rst +++ b/src/cython/doc/rips_complex_user.rst @@ -305,3 +305,8 @@ until dimension 1 - one skeleton graph in other words), the output is: [2, 4] -> 0.97 [0, 3] -> 0.99 [1, 3] -> 0.99 + +.. note:: + As persistence diagrams points will be under the diagonal, + bottleneck distance and persistence graphical tool will not work properly, + this is a known issue. diff --git a/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py index ad990fdc..aa82ef71 100755 --- a/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py +++ b/src/cython/example/rips_complex_diagram_persistence_from_correlation_matrix_file_example.py @@ -49,6 +49,11 @@ if not (-1. < args.min_edge_correlation < 1.): print("Wrong value of the treshold corelation (should be between -1 and 1).") sys.exit(1) +print("#####################################################################") +print("Caution: as persistence diagrams points will be under the diagonal,") +print("bottleneck distance and persistence graphical tool will not work") +print("properly, this is a known issue.") + print("#####################################################################") print("RipsComplex creation from correlation matrix read in a csv file") -- cgit v1.2.3