From e2c0166fcbf17e91cf5ed7b6159f80d64b49cc0b Mon Sep 17 00:00:00 2001 From: pdlotko Date: Mon, 14 Aug 2017 19:43:45 +0000 Subject: Adding a code that use Clement's procedure to read files. Correcting some samll errors. Now the code is ready. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/persistence_representation_integration@2610 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b2947d1c484d661eca6c32fe5386461e741b76f9 --- .../doc/Persistence_representations_doc.h | 2 +- .../gudhi/Persistence_intervals_with_distances.h | 1 + .../include/gudhi/Persistence_landscape.h | 28 +-- .../include/gudhi/read_persistence_from_file.h | 192 ++++++++------------- .../test/persistence_intervals_test.cpp | 3 +- .../test/persistence_lanscapes_on_grid_test.cpp | 4 +- .../test/persistence_lanscapes_test.cpp | 40 ++++- .../test/read_persistence_from_file_test.cpp | 15 +- .../test/vector_representation_test.cpp | 5 +- 9 files changed, 137 insertions(+), 153 deletions(-) (limited to 'src') diff --git a/src/Persistence_representations/doc/Persistence_representations_doc.h b/src/Persistence_representations/doc/Persistence_representations_doc.h index 49a1cdd0..c77e75e2 100644 --- a/src/Persistence_representations/doc/Persistence_representations_doc.h +++ b/src/Persistence_representations/doc/Persistence_representations_doc.h @@ -139,7 +139,7 @@ namespace Persistence_representations { possible ways to proceed: \li Use non exact representation on a grid described in the Section \ref sec_landscapes_on_grid. - \li Compute just a number of initial nonzero landscapes. This option is available from C++ level. + \li Compute just a number of initial nonzero landscapes. This option is available from C++ level as a last parameter of the constructor of persistence landscape (set by default to std::numeric_limits::max()). diff --git a/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h b/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h index e476d28a..d5ab04b4 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h +++ b/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h @@ -26,6 +26,7 @@ #include #include + #include namespace Gudhi { diff --git a/src/Persistence_representations/include/gudhi/Persistence_landscape.h b/src/Persistence_representations/include/gudhi/Persistence_landscape.h index c86e68d3..63e45bc9 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_landscape.h +++ b/src/Persistence_representations/include/gudhi/Persistence_landscape.h @@ -77,16 +77,16 @@ class Persistence_landscape { Persistence_landscape() { this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } /** - * Constructor that takes as an input a vector of birth-death pairs. - **/ - Persistence_landscape(const std::vector >& p); + * Constructor that takes as an input a vector of birth-death pairs. + **/ + Persistence_landscape(const std::vector >& p, size_t number_of_levels = std::numeric_limits::max() ); /** * Constructor that reads persistence intervals from file and creates persistence landscape. The format of the *input file is the following: in each line we put birth-death pair. Last line is assumed * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. **/ - Persistence_landscape(const char* filename, size_t dimension = std::numeric_limits::max()); + Persistence_landscape(const char* filename, size_t dimension = std::numeric_limits::max() , size_t number_of_levels = std::numeric_limits::max() ); /** * This procedure loads a landscape from file. It erase all the data that was previously stored in this landscape. @@ -451,7 +451,7 @@ class Persistence_landscape { size_t number_of_functions_for_vectorization; size_t number_of_functions_for_projections_to_reals; - void construct_persistence_landscape_from_barcode(const std::vector >& p); + void construct_persistence_landscape_from_barcode(const std::vector >& p , size_t number_of_levels = std::numeric_limits::max()); Persistence_landscape multiply_lanscape_by_real_number_not_overwrite(double x) const; void multiply_lanscape_by_real_number_overwrite(double x); friend double compute_maximal_distance_non_symmetric(const Persistence_landscape& pl1, @@ -464,14 +464,14 @@ class Persistence_landscape { } }; -Persistence_landscape::Persistence_landscape(const char* filename, size_t dimension) { +Persistence_landscape::Persistence_landscape(const char* filename, size_t dimension, size_t number_of_levels) { std::vector > barcode; if (dimension < std::numeric_limits::max()) { barcode = read_persistence_intervals_in_one_dimension_from_file(filename, dimension); } else { barcode = read_persistence_intervals_in_one_dimension_from_file(filename); } - this->construct_persistence_landscape_from_barcode(barcode); + this->construct_persistence_landscape_from_barcode(barcode,number_of_levels); this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } @@ -504,13 +504,14 @@ bool Persistence_landscape::operator==(const Persistence_landscape& rhs) const { return true; } -Persistence_landscape::Persistence_landscape(const std::vector >& p) { - this->construct_persistence_landscape_from_barcode(p); +Persistence_landscape::Persistence_landscape(const std::vector >& p,size_t number_of_levels) { + this->construct_persistence_landscape_from_barcode(p,number_of_levels); this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } void Persistence_landscape::construct_persistence_landscape_from_barcode( - const std::vector >& p) { + const std::vector >& p, size_t number_of_levels) + { bool dbg = false; if (dbg) { std::cerr << "Persistence_landscape::Persistence_landscape( const std::vector< std::pair< double , double > >& p )" @@ -536,6 +537,7 @@ void Persistence_landscape::construct_persistence_landscape_from_barcode( std::make_pair((bars[i].first + bars[i].second) / 2.0, (bars[i].second - bars[i].first) / 2.0); } std::vector > > Persistence_landscape; + size_t number_of_levels_in_the_landscape = 0; while (!characteristicPoints.empty()) { if (dbg) { for (size_t i = 0; i != characteristicPoints.size(); ++i) { @@ -644,6 +646,12 @@ void Persistence_landscape::construct_persistence_landscape_from_barcode( lambda_n.erase(std::unique(lambda_n.begin(), lambda_n.end()), lambda_n.end()); this->land.push_back(lambda_n); + + ++number_of_levels_in_the_landscape; + if ( number_of_levels == number_of_levels_in_the_landscape ) + { + break; + } } } diff --git a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h index ad3d4e83..770da15b 100644 --- a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h +++ b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace Gudhi { namespace Persistence_representations { @@ -49,130 +50,81 @@ namespace Persistence_representations { * The procedure returns vector of persistence pairs. **/ std::vector > read_persistence_intervals_in_one_dimension_from_file( - std::string const& filename, int dimension = -1, double what_to_substitute_for_infinite_bar = -1) { + std::string const& filename, int dimension = -1, double what_to_substitute_for_infinite_bar = -1) { bool dbg = false; - std::ifstream in; - in.open(filename); - // checking if the file exist: - if (!in.good()) { - std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n"; - throw "The persistence landscape file do not exist. The program will now terminate \n"; - } std::string line; - std::vector > barcode; - - int number_of_entries_per_line = -1; - - while (!in.eof()) { - getline(in, line); - if (dbg) std::cerr << "Reading line : " << line << std::endl; - if (!(line.length() == 0 || line[0] == '#')) { - // If we do not know how many entries per line we have, we check it in below. - if (number_of_entries_per_line == -1) { - number_of_entries_per_line = 0; - std::string line_copy(line); - if (line_copy.find("inf") != std::string::npos) { - size_t np = line_copy.find("inf"); - // replace symbols 'inf' in line_copy with white spaces: - line_copy[np] = ' '; - line_copy[np + 1] = ' '; - line_copy[np + 2] = ' '; - number_of_entries_per_line = 1; - } - // check how many entries we have in the line. - std::stringstream ss(line_copy); - double number; - std::vector this_line; - while (ss >> number) { - this_line.push_back(number); - } - number_of_entries_per_line += static_cast(this_line.size()); - if (dbg) { - std::cerr << "number_of_entries_per_line : " << number_of_entries_per_line - << ". This number was obtained by analyzing this line : " << line << std::endl; - } - if ((number_of_entries_per_line < 2) || (number_of_entries_per_line > 4)) { - std::cerr << "The input file you have provided have wrong number of numerical entries per line. The program " - "will now terminate. \n"; - throw "Wrong number of numerical entries per line in the input file. The program will now terminate. \n"; - } - } - // In case there is an 'inf' string in this line, we are dealing with this situation in below. - if (line.find("inf") != std::string::npos) { - if (dbg) { - std::cerr << "This line: " << line << " contains infinite interval. \n"; - } - // first we substitute inf by white spaces: - size_t np = line.find("inf"); - line[np] = ' '; - line[np + 1] = ' '; - line[np + 2] = ' '; - if (what_to_substitute_for_infinite_bar != -1) { - double beginn, field, dim; - std::stringstream lineSS(line); - if (number_of_entries_per_line == 4) lineSS >> field; - if (number_of_entries_per_line >= 3) { - lineSS >> dim; - } else { - dim = dimension; - } - lineSS >> beginn; - if (dim == dimension) { - if (beginn > what_to_substitute_for_infinite_bar) { - barcode.push_back(std::make_pair(what_to_substitute_for_infinite_bar, beginn)); - } else { - barcode.push_back(std::make_pair(beginn, what_to_substitute_for_infinite_bar)); - } - if (dbg) { - std::cerr << "this is the line that is going to the output : " << beginn << " , " - << what_to_substitute_for_infinite_bar << std::endl; - } - } - } else { - // this is a line with infinity. Since the variable what_to_substitute_for_infinite_bar have not been set up, - // it means that this line will be skipped. - if (dbg) { - std::cerr << "We will skip it \n"; - } - } - continue; - } else { - // Then, we read the content of the line. We know that it do not contain 'inf' substring. - std::stringstream lineSS(line); - double beginn, endd, field, dim; - if (number_of_entries_per_line == 4) lineSS >> field; - if (number_of_entries_per_line >= 3) { - lineSS >> dim; - } else { - dim = dimension; - } - lineSS >> beginn; - lineSS >> endd; - if (beginn > endd) { - std::swap(beginn, endd); - } - if (dim == dimension) { - barcode.push_back(std::make_pair(beginn, endd)); - if (dbg) { - std::cerr << "This is a line that is going to the output : " << beginn << " , " << endd << std::endl; - } - } else { - if ((number_of_entries_per_line == 3) && (dimension == -1)) { - barcode.push_back(std::make_pair(beginn, endd)); - } - } - } - } else { - if (dbg) { - std::cerr << "This is a comment line \n"; - } - } + std::vector > barcode_initial = read_persistence_intervals_in_dimension(filename,(int)dimension); + std::vector > final_barcode; + final_barcode.reserve( barcode_initial.size() ); + + if ( dbg ) + { + std::cerr << "Here are the intervals that we read from the file : \n"; + for ( size_t i = 0 ; i != barcode_initial.size() ; ++i ) + { + std::cout << barcode_initial[i].first << " " << barcode_initial[i].second << std::endl; + } + getchar(); } - in.close(); - if (dbg) std::cerr << "End of reading \n"; - - return barcode; + + for ( size_t i = 0 ; i != barcode_initial.size() ; ++i ) + { + if ( dbg ) + { + std::cout << "COnsidering interval : " << barcode_initial[i].first << " " << barcode_initial[i].second << std::endl; + } + // if ( barcode_initial[i].first == barcode_initial[i].second ) + //{ + // if ( dbg )std::cout << "It has zero length \n"; + // continue;//zero length intervals are not relevant, so we skip all of them. + //} + + if ( barcode_initial[i].first > barcode_initial[i].second )//note that in this case barcode_initial[i].second != std::numeric_limits::infinity() + { + if ( dbg )std::cout << "Swap and enter \n"; + //swap them to make sure that birth < death + final_barcode.push_back( std::pair( barcode_initial[i].second , barcode_initial[i].first ) ); + continue; + } + else + { + if ( barcode_initial[i].second != std::numeric_limits::infinity() ) + { + if ( dbg )std::cout << "Simply enters\n"; + //in this case, due to the previous conditions we know that barcode_initial[i].first < barcode_initial[i].second, so we put them as they are + final_barcode.push_back( std::pair( barcode_initial[i].first , barcode_initial[i].second ) ); + } + } + + if ( (barcode_initial[i].second == std::numeric_limits::infinity() ) && ( what_to_substitute_for_infinite_bar != -1 ) ) + { + if ( barcode_initial[i].first < what_to_substitute_for_infinite_bar )//if only birth < death. + { + final_barcode.push_back( std::pair( barcode_initial[i].first , what_to_substitute_for_infinite_bar ) ); + } + } + else + { + //if the variable what_to_substitute_for_infinite_bar is not set, then we ignore all the infinite bars. + } + } + + + if ( dbg ) + { + std::cerr << "Here are the final bars that we are sending further : \n"; + for ( size_t i = 0 ; i != final_barcode.size() ; ++i ) + { + std::cout << final_barcode[i].first << " " << final_barcode[i].second << std::endl; + } + std::cerr << "final_barcode.size() : " << final_barcode.size() << std::endl; + getchar(); + } + + + + return final_barcode; } // read_persistence_intervals_in_one_dimension_from_file } // namespace Persistence_representations diff --git a/src/Persistence_representations/test/persistence_intervals_test.cpp b/src/Persistence_representations/test/persistence_intervals_test.cpp index 51d8a0f9..545330c4 100644 --- a/src/Persistence_representations/test/persistence_intervals_test.cpp +++ b/src/Persistence_representations/test/persistence_intervals_test.cpp @@ -36,6 +36,7 @@ double epsilon = 0.0000005; // cout << "Left most end of the interval : " << min_max_.first << std::endl; // cout << "Right most end of the interval : " << min_max_.second << std::endl; BOOST_AUTO_TEST_CASE(check_min_max_function) { + std::cerr << "First test \n"; Persistence_intervals p("data/file_with_diagram"); std::pair min_max_ = p.get_x_range(); @@ -148,7 +149,7 @@ BOOST_AUTO_TEST_CASE(check_characteristic_function_of_diagram) { std::cerr << char_funct_diag[i] << " " << template_char_funct_diag[i] << std::endl; std::cerr << fabs(char_funct_diag[i] - template_char_funct_diag[i]) << std::endl; std::cerr << 0.0001 << std::endl; - getchar(); + //getchar(); } BOOST_CHECK(fabs(char_funct_diag[i] - template_char_funct_diag[i]) <= 0.0001); } diff --git a/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp b/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp index 8ab7449e..6b1608fe 100644 --- a/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp +++ b/src/Persistence_representations/test/persistence_lanscapes_on_grid_test.cpp @@ -199,11 +199,11 @@ BOOST_AUTO_TEST_CASE(check_computations_of_maxima_and_norms) { BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) { std::vector > diag = - read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); + read_persistence_intervals_in_dimension("data/file_with_diagram"); Persistence_landscape_on_grid p(diag, 0., 1., 100); std::vector > diag1 = - read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1"); + read_persistence_intervals_in_dimension("data/file_with_diagram_1"); Persistence_landscape_on_grid q(diag1, 0., 1., 100); double dist_numeric_limit_max = p.distance(q, std::numeric_limits::max()); diff --git a/src/Persistence_representations/test/persistence_lanscapes_test.cpp b/src/Persistence_representations/test/persistence_lanscapes_test.cpp index 22686560..206035c7 100644 --- a/src/Persistence_representations/test/persistence_lanscapes_test.cpp +++ b/src/Persistence_representations/test/persistence_lanscapes_test.cpp @@ -34,12 +34,12 @@ using namespace Gudhi::Persistence_representations; double epsilon = 0.0000005; -BOOST_AUTO_TEST_CASE(check_construction_of_landscape) { +BOOST_AUTO_TEST_CASE(check_construction_of_landscape) { std::vector > diag = - read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); + read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); Persistence_landscape p(diag); - Persistence_landscape q; - q.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram"); + Persistence_landscape q; + q.load_landscape_from_file("data/file_with_landscape_from_file_with_diagram"); BOOST_CHECK(p == q); } @@ -47,10 +47,12 @@ BOOST_AUTO_TEST_CASE(check_construction_of_landscape_form_gudhi_style_file) { Persistence_landscape p("data/persistence_file_with_four_entries_per_line", 1); // p.print_to_file("persistence_file_with_four_entries_per_line_landscape"); Persistence_landscape q; - q.load_landscape_from_file("data/persistence_file_with_four_entries_per_line_landscape"); + q.load_landscape_from_file("data/persistence_file_with_four_entries_per_line_landscape"); BOOST_CHECK(p == q); } + + BOOST_AUTO_TEST_CASE(check_computations_of_integrals) { std::vector > diag = read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); @@ -217,9 +219,7 @@ BOOST_AUTO_TEST_CASE(check_computations_of_distances) { Persistence_landscape q(diag2); BOOST_CHECK(fabs(p.distance(q) - 25.5824) <= 0.00005); BOOST_CHECK(fabs(p.distance(q, 2) - 2.12636) <= 0.00001); - BOOST_CHECK(fabs(p.distance(q, std::numeric_limits::max()) - 0.359068) <= 0.00001); - std::cerr << "p.distance( q , std::numeric_limits::max() ) : " - << p.distance(q, std::numeric_limits::max()) << std::endl; + BOOST_CHECK(fabs(p.distance(q, std::numeric_limits::max()) - 0.359068) <= 0.00001); } BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) { @@ -232,6 +232,30 @@ BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) { BOOST_CHECK(fabs(p.compute_scalar_product(q) - 0.754498) <= 0.00001); } + + + + + + + + + + + + + + + + + + + + + + + + // Below I am storing the code used to generate tests for that functionality. /* if ( argc != 2 ) diff --git a/src/Persistence_representations/test/read_persistence_from_file_test.cpp b/src/Persistence_representations/test/read_persistence_from_file_test.cpp index 31dbed61..76d7cdb0 100644 --- a/src/Persistence_representations/test/read_persistence_from_file_test.cpp +++ b/src/Persistence_representations/test/read_persistence_from_file_test.cpp @@ -23,7 +23,6 @@ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MODULE "Persistence_representations" #include -#include #include #include @@ -31,6 +30,8 @@ using namespace Gudhi; using namespace Gudhi::Persistence_representations; + + BOOST_AUTO_TEST_CASE(test_read_file_with_four_elements_per_line) { std::vector > what_we_should_get; what_we_should_get.push_back(std::make_pair(0, 2)); @@ -38,7 +39,7 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_four_elements_per_line) { what_we_should_get.push_back(std::make_pair(10, 90)); what_we_should_get.push_back(std::make_pair(4, 4)); std::vector > what_we_get = read_persistence_intervals_in_one_dimension_from_file( - "data/persistence_file_with_four_entries_per_line", 1, 1000); + "data/persistence_file_with_four_entries_per_line", 1, 1000); // for ( size_t i = 0 ; i != what_we_get.size() ; ++i ) //{ @@ -75,6 +76,7 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_three_elements_per_line) { } } + BOOST_AUTO_TEST_CASE(test_read_file_with_two_elements_per_line) { std::vector > what_we_should_get; what_we_should_get.push_back(std::make_pair(4, 10)); @@ -83,16 +85,11 @@ BOOST_AUTO_TEST_CASE(test_read_file_with_two_elements_per_line) { what_we_should_get.push_back(std::make_pair(1, 4)); std::vector > what_we_get = - read_persistence_intervals_in_one_dimension_from_file("data/persistence_file_with_two_entries_per_line", 1, 9999); - - // for ( size_t i = 0 ; i != what_we_get.size() ; ++i ) - //{ - // std::cerr << what_we_get[i].first << " , " << what_we_get[i].second << std::endl; - //} - + read_persistence_intervals_in_one_dimension_from_file("data/persistence_file_with_two_entries_per_line", -1, 9999); BOOST_CHECK(what_we_should_get.size() == what_we_get.size()); for (size_t i = 0; i != what_we_get.size(); ++i) { BOOST_CHECK(what_we_should_get[i] == what_we_get[i]); } } + diff --git a/src/Persistence_representations/test/vector_representation_test.cpp b/src/Persistence_representations/test/vector_representation_test.cpp index 5a29c109..3f3e2abe 100644 --- a/src/Persistence_representations/test/vector_representation_test.cpp +++ b/src/Persistence_representations/test/vector_representation_test.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #define BOOST_TEST_DYN_LINK @@ -295,11 +296,11 @@ BOOST_AUTO_TEST_CASE(check_distance_computations) { BOOST_AUTO_TEST_CASE(check_default_parameters_of_distances) { std::vector > diag = - read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram"); + read_persistence_intervals_in_dimension("data/file_with_diagram"); Vector_distances_in_diagram p(diag, 100); std::vector > diag1 = - read_persistence_intervals_in_one_dimension_from_file("data/file_with_diagram_1"); + read_persistence_intervals_in_dimension("data/file_with_diagram_1"); Vector_distances_in_diagram q(diag1, 100); double dist_numeric_limit_max = p.distance(q, std::numeric_limits::max()); -- cgit v1.2.3