From 305e25eb80fab69188e04336fc55635cd58e8273 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 28 Jun 2016 11:31:34 +0000 Subject: now it compiles! git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@1347 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 11d98fbee0ac009d75a1c101f2e28208a199f4a7 --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e55e4395..e1db3a3b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,7 @@ else() add_subdirectory(example/Bitmap_cubical_complex) add_subdirectory(example/Witness_complex) add_subdirectory(example/Alpha_complex) + add_subdirectory(example/Gudhi_stat) # data points generator add_subdirectory(data/points/generator) -- cgit v1.2.3 From c7697cbc6bb80b18d3319c0310d3cf4afe58e8ef Mon Sep 17 00:00:00 2001 From: pdlotko Date: Tue, 26 Jul 2016 07:13:08 +0000 Subject: aaa git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@1395 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0adfec650245761402f8a062f0682c4f7afd6513 --- src/CMakeLists.txt | 3 +- src/Gudhi_stat/example/CMakeLists.txt | 11 + src/Gudhi_stat/example/persistence_intervals.cpp | 2 +- .../gudhi/concretizations/Persistence_intervals.h | 1234 ++++++++++---------- .../gudhi/concretizations/Persistence_landscapes.h | 95 +- .../concretizations/Vector_distances_in_diagram.h | 25 +- 6 files changed, 713 insertions(+), 657 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1db3a3b..fcf38a51 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,7 +92,8 @@ else() add_subdirectory(example/Bitmap_cubical_complex) add_subdirectory(example/Witness_complex) add_subdirectory(example/Alpha_complex) - add_subdirectory(example/Gudhi_stat) + add_subdirectory(example/Bottleneck) + # data points generator add_subdirectory(data/points/generator) diff --git a/src/Gudhi_stat/example/CMakeLists.txt b/src/Gudhi_stat/example/CMakeLists.txt index ec2afc09..aadfc83b 100644 --- a/src/Gudhi_stat/example/CMakeLists.txt +++ b/src/Gudhi_stat/example/CMakeLists.txt @@ -4,10 +4,21 @@ project(GUDHI_STAT) add_executable ( persistence_landscape persistence_landscape.cpp ) target_link_libraries(persistence_landscape ${Boost_SYSTEM_LIBRARY}) +add_executable ( average_landscapes average_landscapes.cpp ) +target_link_libraries(average_landscapes ${Boost_SYSTEM_LIBRARY}) + +add_executable ( create_landscapes create_landscapes.cpp ) +target_link_libraries(create_landscapes ${Boost_SYSTEM_LIBRARY}) + +add_executable ( plot_landscapes plot_landscapes.cpp ) +target_link_libraries(plot_landscapes ${Boost_SYSTEM_LIBRARY}) + add_executable ( persistence_intervals persistence_intervals.cpp ) target_link_libraries(persistence_intervals ${Boost_SYSTEM_LIBRARY}) +add_executable ( plot_persistence_intervals plot_persistence_intervals.cpp ) +target_link_libraries( plot_persistence_intervals ${Boost_SYSTEM_LIBRARY}) add_executable ( vector_representation vector_representation.cpp ) target_link_libraries(vector_representation ${Boost_SYSTEM_LIBRARY}) diff --git a/src/Gudhi_stat/example/persistence_intervals.cpp b/src/Gudhi_stat/example/persistence_intervals.cpp index 0f374b07..cf8c37c6 100644 --- a/src/Gudhi_stat/example/persistence_intervals.cpp +++ b/src/Gudhi_stat/example/persistence_intervals.cpp @@ -24,7 +24,7 @@ #include #include -#include "gudhi/concretizations/Persistence_intervals.h" +#include #include diff --git a/src/Gudhi_stat/include/gudhi/concretizations/Persistence_intervals.h b/src/Gudhi_stat/include/gudhi/concretizations/Persistence_intervals.h index a2d16aa0..ecb69a2f 100644 --- a/src/Gudhi_stat/include/gudhi/concretizations/Persistence_intervals.h +++ b/src/Gudhi_stat/include/gudhi/concretizations/Persistence_intervals.h @@ -1,599 +1,637 @@ -/* 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 Persistence_intervals_H_ -#define Persistence_intervals_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Gudhi -{ -namespace Gudhi_stat -{ - -class Persistence_intervals : public Abs_Vectorized_topological_data , public Abs_Topological_data_with_distances, public Abs_Real_valued_topological_data -{ -public: - /** - * This is a constructor of a class Persistence_intervals from a text file. Each line of the input file is supposed to contain two numbers of a type doube (or convertable to double) - * representing the birth and the death of the persistence interval. If the pairs are not sorted so that birth <= death, then the constructor will sort then that way. - **/ - Persistence_intervals( const char* filename ); - - /** - * This is a constructor of a class Persistence_intervals from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elemnets of pairs - * are smaller or equal the second elements of pairs. - **/ - Persistence_intervals( const std::vector< std::pair< double,double > >& intervals ); - - /** - * The procedure returns a pair the first element of which is the leftmost end of the interval, and the second element of which is the rightmost end of the interval. - **/ - std::pair min_max(); - - /** - * Procedure that compute the vector of lengths of the dominant (i.e. the longest) persistence intervals. The list is truncated at the parameter of the call where_to_cut (set by default to 100). - **/ - std::vector length_of_dominant_intervals( size_t where_to_cut = 100 ); - - - /** - * Procedure that compute the vector of the dominant (i.e. the longest) persistence intervals. The parameter of the procedure (set by default to 100) is the number of dominant intervals returned by the procedure. - **/ - std::vector< std::pair > dominant_intervals( size_t where_to_cut = 100 ); - - /** - * Procedure to compute a histogram of interva's length. A histogram is a block plot. The number of blocks is determined by the first parameter of the function (set by default to 10). - * For the sake of argument let us assume that the length of the longest interval is 1 and the number of bins is 10. In this case the i-th block correspond to a range between i-1/10 and i10. - * The vale of a block supported at the interval is the number of persistence intervals of a length between x_0 and x_1. - **/ - std::vector< size_t > histograms_of_lengths( size_t number_of_bins = 10 ); - - /** - * Based on a histogram of intervals lengts computed by the function histograms_of_lengths H the procedure below computes the cumulative histogram. The i-th position of the resulting histogram - * is the sume of values of H for the positions from 0 to i. - **/ - std::vector< size_t > cumulative_histograms_of_lengths( size_t number_of_bins = 10 ); - - /** - * In this procedure we assume that each barcode is a characteristic function of a hight equal to its length. The persistence diagram is a sum of such a functions. The procedure below construct a function being a - * sum of the characteristic functions of persistence intervals. The first two parameters are the range in which the function is to be computed and the last parameter is the number of bins in - * the discretization of the interval [_min,_max]. - **/ - std::vector< double > characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins = 10 ); - - /** - * Cumulative version of the function characteristic_function_of_diagram - **/ - std::vector< double > cumulative_characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins = 10 ); - - /** - * Compute the funtion of persistence Betti numbers. The returned value is a vector of pair. First element of each pair is a place where persistence Betti numbers change. - * Second element of each pair is the value of Persistence Betti numbers at that point. - **/ - std::vector< std::pair< double , size_t > > compute_persistent_betti_numbers(); - - /** - *This is a non optimal procedure that compute vector of distances from each point of diagram to its k-th nearest neighbor (k is a parameted of the program). The resulting vector is by default truncated to 10 - *elements (this value can be changed by using the second parameter of the program). The points are returned in order from the ones which are farthest away from their k-th nearest neighbors. - **/ - std::vector< double > k_n_n( size_t k , size_t where_to_cut = 10 ); - - /** - * Operator that send the diagram to a stream. - **/ - - friend ostream& operator << ( ostream& out , const Persistence_intervals& intervals ) - { - for ( size_t i = 0 ; i != intervals.intervals.size() ; ++i ) - { - out << intervals.intervals[i].first << " " << intervals.intervals[i].second << endl; - } - return out; - } - - - /** - * Return a familly of vectors obtained from the persistence diagram. The i-th vector consist of the lenfth of i dominant persistence intervals. - **/ - std::vector vectorize( int number_of_function )//comment: in this case, number_of_functions (a static member of Abs_Vectorized_topological_data cannot be set a priori. - //In this cas, maybe it is better not to make this parameter static. - { - return this->length_of_dominant_intervals( number_of_function ); - } - - /** - * Retun numbr of points in the diagram. - **/ - size_t size()const{return this->intervals.size();} - - /** - * Return the persistence interval at the given position. Note that intervals are not sorted with respect to their lengths. - **/ - inline std::pair< double,double > operator [](size_t i) - { - if ( i >= this->intervals.size() )throw("Index out of range! Operator [], one_d_gaussians class\n"); - return this->intervals[i]; - } - - /** - *Computations of distance from the current persistnce diagram to the persistence diagram given as a parameter of this function. - *The last parameter, power, is here in case we would like to compute p=th Wasserstein distance. At the moment, for the bottleneck distances, it will be ignored. - **/ - double distance( const Abs_Topological_data_with_distances* second , double power = 1) - { - return 1; - //waiting for Francois Godi for the code. We will compute here the Bottleneck distnace. - } - - /** - * This is a simple function projectig the persistence intervals to a real number. The function we use here is a sum of squared lendgths of intervals. It can be naturally interpreted as - * sum of step function, where the step hight it equal to the length of the interval. - **/ - double project_to_R( int number_of_function ); - - - //For visualization use output from vectorize and build histograms. - std::vector< std::pair< double,double > > output_for_visualization() - { - return this->intervals; - } - -protected: - - void set_up_numbers_of_functions_for_vectorization_and_projections_to_reals() - { - //warning, this function can be only called after filling in the intervals vector. - this->number_of_functions_for_vectorization = this->intervals.size(); - this->number_of_functions_for_projections_to_reals = 1; - } - - std::vector< std::pair< double,double > > intervals; -}; - - -Persistence_intervals::Persistence_intervals( const char* filename ) -{ - bool dbg = false; - ifstream in; - in.open( filename ); - - if ( !in.good() ) - { - throw("File with the persistence diagram do not exist, the program will now terminate.\n"); - } - - while ( true ) - { - double first; - double second; - in >> first >> second; - - if ( first > second ) - { - double buf = first; - first = second; - second = buf; - } - - if ( in.eof() )break; - this->intervals.push_back( std::make_pair( first,second ) ); - if ( dbg ) - { - cerr << "Adding interval [ " << first << " , " << second << " ]\n"; - getchar(); - } - } - in.close(); - this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); -}//Persistence_intervals - - -Persistence_intervals::Persistence_intervals( const std::vector< std::pair< double , double > >& intervals_ ) -{ - std::vector< std::pair< double,double > > aaa( intervals_ ); - this->intervals = aaa; - this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); -} - - -std::vector< double > Persistence_intervals::length_of_dominant_intervals( size_t where_to_cut ) -{ - this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); - std::vector< double > result( this->intervals.size() ); - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - result[i] = this->intervals[i].second - this->intervals[i].first; - } - std::sort( result.begin() , result.end() , std::greater() ); - - - result.resize( std::min(where_to_cut,result.size()) ); +/* 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 Persistence_intervals_H_ +#define Persistence_intervals_H_ + +//gudhi include +#include +#include +#include +#include + +//standard include +#include +#include +#include +#include +#include +#include +#include + +namespace Gudhi +{ +namespace Gudhi_stat +{ + +class Persistence_intervals : public Abs_Vectorized_topological_data , public Abs_Topological_data_with_distances, public Abs_Real_valued_topological_data +{ +public: + /** + * This is a constructor of a class Persistence_intervals from a text file. Each line of the input file is supposed to contain two numbers of a type doube (or convertable to double) + * representing the birth and the death of the persistence interval. If the pairs are not sorted so that birth <= death, then the constructor will sort then that way. + **/ + Persistence_intervals( const char* filename ); + + /** + * This is a constructor of a class Persistence_intervals from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elemnets of pairs + * are smaller or equal the second elements of pairs. + **/ + Persistence_intervals( const std::vector< std::pair< double,double > >& intervals ); + + /** + * The procedure returns a pair the first element of which is the leftmost end of the interval, and the second element of which is the rightmost end of the interval. + **/ + std::pair min_max(); + + /** + * Procedure that compute the vector of lengths of the dominant (i.e. the longest) persistence intervals. The list is truncated at the parameter of the call where_to_cut (set by default to 100). + **/ + std::vector length_of_dominant_intervals( size_t where_to_cut = 100 ); + + + /** + * Procedure that compute the vector of the dominant (i.e. the longest) persistence intervals. The parameter of the procedure (set by default to 100) is the number of dominant intervals returned by the procedure. + **/ + std::vector< std::pair > dominant_intervals( size_t where_to_cut = 100 ); + + /** + * Procedure to compute a histogram of interva's length. A histogram is a block plot. The number of blocks is determined by the first parameter of the function (set by default to 10). + * For the sake of argument let us assume that the length of the longest interval is 1 and the number of bins is 10. In this case the i-th block correspond to a range between i-1/10 and i10. + * The vale of a block supported at the interval is the number of persistence intervals of a length between x_0 and x_1. + **/ + std::vector< size_t > histograms_of_lengths( size_t number_of_bins = 10 ); + + /** + * Based on a histogram of intervals lengts computed by the function histograms_of_lengths H the procedure below computes the cumulative histogram. The i-th position of the resulting histogram + * is the sume of values of H for the positions from 0 to i. + **/ + std::vector< size_t > cumulative_histograms_of_lengths( size_t number_of_bins = 10 ); + + /** + * In this procedure we assume that each barcode is a characteristic function of a hight equal to its length. The persistence diagram is a sum of such a functions. The procedure below construct a function being a + * sum of the characteristic functions of persistence intervals. The first two parameters are the range in which the function is to be computed and the last parameter is the number of bins in + * the discretization of the interval [_min,_max]. + **/ + std::vector< double > characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins = 10 ); + + /** + * Cumulative version of the function characteristic_function_of_diagram + **/ + std::vector< double > cumulative_characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins = 10 ); + + /** + * Compute the funtion of persistence Betti numbers. The returned value is a vector of pair. First element of each pair is a place where persistence Betti numbers change. + * Second element of each pair is the value of Persistence Betti numbers at that point. + **/ + std::vector< std::pair< double , size_t > > compute_persistent_betti_numbers(); + + /** + *This is a non optimal procedure that compute vector of distances from each point of diagram to its k-th nearest neighbor (k is a parameted of the program). The resulting vector is by default truncated to 10 + *elements (this value can be changed by using the second parameter of the program). The points are returned in order from the ones which are farthest away from their k-th nearest neighbors. + **/ + std::vector< double > k_n_n( size_t k , size_t where_to_cut = 10 ); + + /** + * Operator that send the diagram to a stream. + **/ + friend ostream& operator << ( ostream& out , const Persistence_intervals& intervals ) + { + for ( size_t i = 0 ; i != intervals.intervals.size() ; ++i ) + { + out << intervals.intervals[i].first << " " << intervals.intervals[i].second << endl; + } + return out; + } + + /** + * Generating gnuplot script to plot the interval. + **/ + void plot( const char* filename ) + { + //this program create a gnuplot script file that allows to plot persistence diagram. + ofstream out; + + std::ostringstream nameSS; + nameSS << filename << "_GnuplotScript"; + std::string nameStr = nameSS.str(); + out.open( (char*)nameStr.c_str() ); + std::pair min_max_values = this->min_max(); + out << "set xrange [" << min_max_values.first - 0.1*(min_max_values.second-min_max_values.first) << " : " << min_max_values.second + 0.1*(min_max_values.second-min_max_values.first) << " ]" << endl; + out << "set yrange [" << min_max_values.first - 0.1*(min_max_values.second-min_max_values.first) << " : " << min_max_values.second + 0.1*(min_max_values.second-min_max_values.first) << " ]" << endl; + out << "plot '-' using 1:2 notitle \"" << filename << "\", \\" << endl; + out << " '-' using 1:2 notitle with lp" << endl; + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + out << this->intervals[i].first << " " << this->intervals[i].second << endl; + } + out << "EOF" << endl; + out << min_max_values.first - 0.1*(min_max_values.second-min_max_values.first) << " " << min_max_values.first - 0.1*(min_max_values.second-min_max_values.first) << endl; + out << min_max_values.second + 0.1*(min_max_values.second-min_max_values.first) << " " << min_max_values.second + 0.1*(min_max_values.second-min_max_values.first) << endl; + + out.close(); + + cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '" << nameStr << "' in gnuplot to visualize." << endl; + } + + /** + * Return a familly of vectors obtained from the persistence diagram. The i-th vector consist of the lenfth of i dominant persistence intervals. + **/ + std::vector vectorize( int number_of_function )//comment: in this case, number_of_functions (a static member of Abs_Vectorized_topological_data cannot be set a priori. + //In this cas, maybe it is better not to make this parameter static. + { + return this->length_of_dominant_intervals( number_of_function ); + } + + /** + * Retun numbr of points in the diagram. + **/ + size_t size()const{return this->intervals.size();} + + /** + * Return the persistence interval at the given position. Note that intervals are not sorted with respect to their lengths. + **/ + inline std::pair< double,double > operator [](size_t i) + { + if ( i >= this->intervals.size() )throw("Index out of range! Operator [], one_d_gaussians class\n"); + return this->intervals[i]; + } + + /** + *Computations of distance from the current persistnce diagram to the persistence diagram given as a parameter of this function. + *The last parameter, power, is here in case we would like to compute p=th Wasserstein distance. At the moment, for the bottleneck distances, it will be ignored. + **/ + double distance( const Abs_Topological_data_with_distances* second , double power = 1) + { + return 1; + //waiting for Francois Godi for the code. We will compute here the Bottleneck distnace. + } + + /** + * This is a simple function projectig the persistence intervals to a real number. The function we use here is a sum of squared lendgths of intervals. It can be naturally interpreted as + * sum of step function, where the step hight it equal to the length of the interval. + **/ + double project_to_R( int number_of_function ); + + + //For visualization use output from vectorize and build histograms. + std::vector< std::pair< double,double > > output_for_visualization() + { + return this->intervals; + } + +protected: + + void set_up_numbers_of_functions_for_vectorization_and_projections_to_reals() + { + //warning, this function can be only called after filling in the intervals vector. + this->number_of_functions_for_vectorization = this->intervals.size(); + this->number_of_functions_for_projections_to_reals = 1; + } + + std::vector< std::pair< double,double > > intervals; +}; + + +Persistence_intervals::Persistence_intervals( const char* filename ) +{ + //bool dbg = false; + //ifstream in; + //in.open( filename ); + + //if ( !in.good() ) + //{ + // throw("File with the persistence diagram do not exist, the program will now terminate.\n"); + //} + + //while ( true ) + //{ + // double first; + // double second; + // in >> first >> second; + + // if ( first > second ) + // { + // double buf = first; + // first = second; + // second = buf; + // } + + // if ( in.eof() )break; + // this->intervals.push_back( std::make_pair( first,second ) ); + // if ( dbg ) + // { + // cerr << "Adding interval [ " << first << " , " << second << " ]\n"; + // getchar(); + // } + //} + //in.close(); + //standard file with barcode + std::vector< std::pair< double , double > > barcode = read_standard_file( filename ); + //gudhi file with barcode + //std::vector< std::pair< double , double > > barcode = read_gudhi_file( filename , dimension ); + + this->intervals = barcode; + this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); +}//Persistence_intervals + + +Persistence_intervals::Persistence_intervals( const std::vector< std::pair< double , double > >& intervals_ ) +{ + std::vector< std::pair< double,double > > aaa( intervals_ ); + this->intervals = aaa; + this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); +} + + +std::vector< double > Persistence_intervals::length_of_dominant_intervals( size_t where_to_cut ) +{ + this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); + std::vector< double > result( this->intervals.size() ); + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + result[i] = this->intervals[i].second - this->intervals[i].first; + } + std::sort( result.begin() , result.end() , std::greater() ); + + + result.resize( std::min(where_to_cut,result.size()) ); + return result; +}//length_of_dominant_intervals + + + +bool compare( const std::pair< size_t , double >& first , const std::pair< size_t , double >& second ) +{ + return first.second > second.second; +} + + +std::vector< std::pair > Persistence_intervals::dominant_intervals( size_t where_to_cut ) +{ + bool dbg = false; + std::vector< std::pair< size_t , double > > position_length_vector( this->intervals.size() ); + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + position_length_vector[i] = std::make_pair( i , this->intervals[i].second - this->intervals[i].first ); + } + + std::sort( position_length_vector.begin() , position_length_vector.end() , compare ); + + std::vector< std::pair > result; + result.reserve( std::min( where_to_cut , position_length_vector.size() ) ); + + for ( size_t i = 0 ; i != std::min( where_to_cut , position_length_vector.size() ) ; ++i ) + { + result.push_back( this->intervals[ position_length_vector[i].first ] ); + if ( dbg )cerr << "Position : " << position_length_vector[i].first << " length : " << position_length_vector[i].second << endl; + } + + return result; +}//dominant_intervals + + +std::vector< size_t > Persistence_intervals::histograms_of_lengths( size_t number_of_bins ) +{ + bool dbg = false; + + if ( dbg )cerr << "this->intervals.size() : " << this->intervals.size() << endl; + //first find the length of the longest interval: + double lengthOfLongest = 0; + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + if ( (this->intervals[i].second - this->intervals[i].first) > lengthOfLongest ) + { + lengthOfLongest = this->intervals[i].second - this->intervals[i].first; + } + } + + if ( dbg ){cerr << "lengthOfLongest : " << lengthOfLongest << endl;} + + //this is a container we will use to store the resulting histogram + std::vector< size_t > result( number_of_bins + 1 , 0 ); + + //for every persistence interval in our collection. + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + //compute its length relative to the length of the dominant interval: + double relative_length_of_this_interval = (this->intervals[i].second - this->intervals[i].first)/lengthOfLongest; + + //given the relative length (between 0 and 1) compute to which bin should it contribute. + size_t position = (size_t)(relative_length_of_this_interval*number_of_bins); + + + ++result[position]; + + if ( dbg ) + { + cerr << "i : " << i << endl; + cerr << "Interval : [" << this->intervals[i].first << " , " << this->intervals[i].second << " ] \n"; + cerr << "relative_length_of_this_interval : " << relative_length_of_this_interval << endl; + cerr << "position : " << position << endl; + getchar(); + } + } + + + if ( dbg ){for ( size_t i = 0 ; i != result.size() ; ++i )cerr << result[i] << endl;} + return result; +} + + +std::vector< size_t > Persistence_intervals::cumulative_histograms_of_lengths( size_t number_of_bins ) +{ + std::vector< size_t > histogram = this->histograms_of_lengths( number_of_bins ); + std::vector< size_t > result( histogram.size() ); + + size_t sum = 0; + for ( size_t i = 0 ; i != histogram.size() ; ++i ) + { + sum += histogram[i]; + result[i] = sum; + } + return result; +} + + +std::vector< double > Persistence_intervals::characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins ) +{ + bool dbg = false; + + std::vector< double > result( number_of_bins ); + std::fill( result.begin() , result.end() , 0 ); + + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + if ( dbg ) + { + cerr << "Interval : " << this->intervals[i].first << " , " << this->intervals[i].second << endl; + } + + size_t beginIt = 0; + if ( this->intervals[i].first < x_min )beginIt = 0; + if ( this->intervals[i].first >= x_max )beginIt = result.size(); + if ( ( this->intervals[i].first > x_min ) && ( this->intervals[i].first < x_max ) ) + { + beginIt = number_of_bins*(this->intervals[i].first-x_min)/(x_max - x_min); + } + + size_t endIt; + if ( this->intervals[i].second < x_min )endIt = 0; + if ( this->intervals[i].second >= x_max )endIt = result.size(); + if ( ( this->intervals[i].second > x_min ) && ( this->intervals[i].second < x_max ) ) + { + endIt = number_of_bins*( this->intervals[i].second - x_min )/(x_max - x_min); + } + + if ( beginIt > endIt ){beginIt = endIt;} + + if ( dbg ) + { + cerr << "beginIt : " << beginIt << endl; + cerr << "endIt : " << endIt << endl; + } + + + for ( size_t pos = beginIt ; pos != endIt ; ++pos ) + { + result[pos] += ( (x_max - x_min)/(double)number_of_bins ) * ( this->intervals[i].second - this->intervals[i].first ); + } + //cerr << "x_max : " << x_max << " x_min : " << x_min << " , number_of_bins : " << number_of_bins << " this->intervals[i].second : " << this->intervals[i].second << " this->intervals[i].first : " << this->intervals[i].first << endl; + if ( dbg ) + { + cerr << "Result at this stage \n"; + for ( size_t aa = 0 ; aa != result.size() ; ++aa ) + { + cerr << result[aa] << " "; + } + cerr << endl; + //getchar(); + } + } + return result; +}//characteristic_function_of_diagram + + + +std::vector< double > Persistence_intervals::cumulative_characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins ) +{ + std::vector< double > intsOfBars = this->characteristic_function_of_diagram( x_min , x_max , number_of_bins ); + std::vector< double > result( intsOfBars.size() ); + double sum = 0; + for ( size_t i = 0 ; i != intsOfBars.size() ; ++i ) + { + sum += intsOfBars[i]; + result[i] = sum; + } + return result; +}//cumulative_characteristic_function_of_diagram + + +template +bool compare_first_element_of_pair( const std::pair< T , bool >& f, const std::pair< T , bool >& s ) +{ + return (f.first < s.first); +} + + +std::vector< std::pair< double , size_t > > Persistence_intervals::compute_persistent_betti_numbers() +{ + std::vector< std::pair< double , bool > > places_where_pbs_change( 2*this->intervals.size() ); + + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + places_where_pbs_change[2*i] = std::make_pair( this->intervals[i].first , true ); + places_where_pbs_change[2*i+1] = std::make_pair( this->intervals[i].second , false ); + } + + std::sort( places_where_pbs_change.begin() , places_where_pbs_change.end() , compare_first_element_of_pair ); + size_t pbn = 0; + std::vector< std::pair< double , size_t > > pbns( places_where_pbs_change.size() ); + for ( size_t i = 0 ; i != places_where_pbs_change.size() ; ++i ) + { + if ( places_where_pbs_change[i].second == true ) + { + ++pbn; + } + else + { + --pbn; + } + pbns[i] = std::make_pair( places_where_pbs_change[i].first , pbn ); + } + return pbns; +} + + + + + + +inline double compute_euclidean_distance( const std::pair< double,double > & f , const std::pair< double,double > & s ) +{ + return sqrt( (f.first-s.first)*(f.first-s.first) + (f.second-s.second)*(f.second-s.second) ); +} + + +std::vector< double > Persistence_intervals::k_n_n( size_t k , size_t where_to_cut ) +{ + bool dbg = false; + if ( dbg ) + { + cerr << "Here are the intervals : \n"; + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + cerr << "[ " << this->intervals[i].first << " , " << this->intervals[i].second << "] \n"; + } + getchar(); + } + + std::vector< double > result; + //compute all to all distance between point in the diagram. Also, consider points in the diagonal with the infinite multiplicity. + std::vector< std::vector< double > > distances( this->intervals.size() ); + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + std::vector aa(this->intervals.size()); + std::fill( aa.begin() , aa.end() , 0 ); + distances[i] = aa; + } + std::vector< double > distances_from_diagonal( this->intervals.size() ); + std::fill( distances_from_diagonal.begin() , distances_from_diagonal.end() , 0 ); + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + std::vector< double > distancesFromI; + for ( size_t j = i+1 ; j != this->intervals.size() ; ++j ) + { + distancesFromI.push_back( compute_euclidean_distance( this->intervals[i] , this->intervals[j] ) ); + } + //distances.push_back( distancesFromI ); + //also add a distance from this guy to daigonal: + double distanceToDiagonal = compute_euclidean_distance( this->intervals[i] , std::make_pair( 0.5*(this->intervals[i].first + this->intervals[i].second) , 0.5*(this->intervals[i].first + this->intervals[i].second) ) ); + distances_from_diagonal[i] = distanceToDiagonal; + + if ( dbg ) + { + cerr << "Here are the distances form the point : [" << this->intervals[i].first << " , " << this->intervals[i].second << "] in the diagram \n"; + for ( size_t aa = 0 ; aa != distancesFromI.size() ; ++aa ) + { + cerr << "To : " << i+aa << " : " << distancesFromI[aa] << " "; + } + cerr << endl; + getchar(); + } + + //filling in the distances matrix: + for ( size_t j = i+1 ; j != this->intervals.size() ; ++j ) + { + distances[i][j] = distancesFromI[j-i-1]; + distances[j][i] = distancesFromI[j-i-1]; + } + } + if ( dbg ) + { + cerr << "Here is the distance matrix : \n"; + for ( size_t i = 0 ; i != distances.size() ; ++i ) + { + for ( size_t j = 0 ; j != distances.size() ; ++j ) + { + cerr << distances[i][j] << " "; + } + cerr << endl; + } + cerr << endl << endl << "And here are the distances to the diagonal : " << endl; + for ( size_t i = 0 ; i != distances_from_diagonal. size() ; ++i ) + { + cerr << distances_from_diagonal[i] << " "; + } + cerr << endl << endl; + getchar(); + } + + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + std::vector< double > distancesFromI = distances[i]; + distancesFromI.push_back( distances_from_diagonal[i] ); + + //sort it: + std::sort( distancesFromI.begin() , distancesFromI.end() , std::greater() ); + + if ( k > distancesFromI.size() ) + { + if ( dbg ) + { + cerr << "There are not enough neighbors in your set. We set the result to plus infty \n"; + } + result.push_back( std::numeric_limits::max() ); + } + else + { + if ( distances_from_diagonal[i] > distancesFromI[k] ) + { + if ( dbg ) + { + cerr << "The k-th n.n. is on a diagonal. Therefore we set up a distance to diagonal \n"; + } + result.push_back( distances_from_diagonal[i] ); + } + else + { + result.push_back( distancesFromI[k] ); + } + } + } + std::sort( result.begin() , result.end() , std::greater() ); + result.resize( std::min( result.size() , where_to_cut ) ); + return result; -}//length_of_dominant_intervals - - - -bool compare( const std::pair< size_t , double >& first , const std::pair< size_t , double >& second ) -{ - return first.second > second.second; -} - - -std::vector< std::pair > Persistence_intervals::dominant_intervals( size_t where_to_cut ) -{ - bool dbg = false; - std::vector< std::pair< size_t , double > > position_length_vector( this->intervals.size() ); - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - position_length_vector[i] = std::make_pair( i , this->intervals[i].second - this->intervals[i].first ); - } - - std::sort( position_length_vector.begin() , position_length_vector.end() , compare ); - - std::vector< std::pair > result; - result.reserve( std::min( where_to_cut , position_length_vector.size() ) ); - - for ( size_t i = 0 ; i != std::min( where_to_cut , position_length_vector.size() ) ; ++i ) - { - result.push_back( this->intervals[ position_length_vector[i].first ] ); - if ( dbg )cerr << "Position : " << position_length_vector[i].first << " length : " << position_length_vector[i].second << endl; - } - - return result; -}//dominant_intervals - - -std::vector< size_t > Persistence_intervals::histograms_of_lengths( size_t number_of_bins ) -{ - bool dbg = false; - - if ( dbg )cerr << "this->intervals.size() : " << this->intervals.size() << endl; - //first find the length of the longest interval: - double lengthOfLongest = 0; - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - if ( (this->intervals[i].second - this->intervals[i].first) > lengthOfLongest ) - { - lengthOfLongest = this->intervals[i].second - this->intervals[i].first; - } - } - - if ( dbg ){cerr << "lengthOfLongest : " << lengthOfLongest << endl;} - - //this is a container we will use to store the resulting histogram - std::vector< size_t > result( number_of_bins + 1 , 0 ); - - //for every persistence interval in our collection. - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - //compute its length relative to the length of the dominant interval: - double relative_length_of_this_interval = (this->intervals[i].second - this->intervals[i].first)/lengthOfLongest; - - //given the relative length (between 0 and 1) compute to which bin should it contribute. - size_t position = (size_t)(relative_length_of_this_interval*number_of_bins); - - - ++result[position]; - - if ( dbg ) - { - cerr << "i : " << i << endl; - cerr << "Interval : [" << this->intervals[i].first << " , " << this->intervals[i].second << " ] \n"; - cerr << "relative_length_of_this_interval : " << relative_length_of_this_interval << endl; - cerr << "position : " << position << endl; - getchar(); - } - } - - - if ( dbg ){for ( size_t i = 0 ; i != result.size() ; ++i )cerr << result[i] << endl;} - return result; -} - - -std::vector< size_t > Persistence_intervals::cumulative_histograms_of_lengths( size_t number_of_bins ) -{ - std::vector< size_t > histogram = this->histograms_of_lengths( number_of_bins ); - std::vector< size_t > result( histogram.size() ); - - size_t sum = 0; - for ( size_t i = 0 ; i != histogram.size() ; ++i ) - { - sum += histogram[i]; - result[i] = sum; - } - return result; -} - - -std::vector< double > Persistence_intervals::characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins ) -{ - bool dbg = false; - - std::vector< double > result( number_of_bins ); - std::fill( result.begin() , result.end() , 0 ); - - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - if ( dbg ) - { - cerr << "Interval : " << this->intervals[i].first << " , " << this->intervals[i].second << endl; - } - - size_t beginIt = 0; - if ( this->intervals[i].first < x_min )beginIt = 0; - if ( this->intervals[i].first >= x_max )beginIt = result.size(); - if ( ( this->intervals[i].first > x_min ) && ( this->intervals[i].first < x_max ) ) - { - beginIt = number_of_bins*(this->intervals[i].first-x_min)/(x_max - x_min); - } - - size_t endIt; - if ( this->intervals[i].second < x_min )endIt = 0; - if ( this->intervals[i].second >= x_max )endIt = result.size(); - if ( ( this->intervals[i].second > x_min ) && ( this->intervals[i].second < x_max ) ) - { - endIt = number_of_bins*( this->intervals[i].second - x_min )/(x_max - x_min); - } - - if ( beginIt > endIt ){beginIt = endIt;} - - if ( dbg ) - { - cerr << "beginIt : " << beginIt << endl; - cerr << "endIt : " << endIt << endl; - } - - - for ( size_t pos = beginIt ; pos != endIt ; ++pos ) - { - result[pos] += ( (x_max - x_min)/(double)number_of_bins ) * ( this->intervals[i].second - this->intervals[i].first ); - } - //cerr << "x_max : " << x_max << " x_min : " << x_min << " , number_of_bins : " << number_of_bins << " this->intervals[i].second : " << this->intervals[i].second << " this->intervals[i].first : " << this->intervals[i].first << endl; - if ( dbg ) - { - cerr << "Result at this stage \n"; - for ( size_t aa = 0 ; aa != result.size() ; ++aa ) - { - cerr << result[aa] << " "; - } - cerr << endl; - //getchar(); - } - } - return result; -}//characteristic_function_of_diagram - - - -std::vector< double > Persistence_intervals::cumulative_characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins ) -{ - std::vector< double > intsOfBars = this->characteristic_function_of_diagram( x_min , x_max , number_of_bins ); - std::vector< double > result( intsOfBars.size() ); - double sum = 0; - for ( size_t i = 0 ; i != intsOfBars.size() ; ++i ) - { - sum += intsOfBars[i]; - result[i] = sum; - } - return result; -}//cumulative_characteristic_function_of_diagram - - -template -bool compare_first_element_of_pair( const std::pair< T , bool >& f, const std::pair< T , bool >& s ) -{ - return (f.first < s.first); -} - - -std::vector< std::pair< double , size_t > > Persistence_intervals::compute_persistent_betti_numbers() -{ - std::vector< std::pair< double , bool > > places_where_pbs_change( 2*this->intervals.size() ); - - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - places_where_pbs_change[2*i] = std::make_pair( this->intervals[i].first , true ); - places_where_pbs_change[2*i+1] = std::make_pair( this->intervals[i].second , false ); - } - - std::sort( places_where_pbs_change.begin() , places_where_pbs_change.end() , compare_first_element_of_pair ); - size_t pbn = 0; - std::vector< std::pair< double , size_t > > pbns( places_where_pbs_change.size() ); - for ( size_t i = 0 ; i != places_where_pbs_change.size() ; ++i ) - { - if ( places_where_pbs_change[i].second == true ) - { - ++pbn; - } - else - { - --pbn; - } - pbns[i] = std::make_pair( places_where_pbs_change[i].first , pbn ); - } - return pbns; -} - - - - - - -inline double compute_euclidean_distance( const std::pair< double,double > & f , const std::pair< double,double > & s ) -{ - return sqrt( (f.first-s.first)*(f.first-s.first) + (f.second-s.second)*(f.second-s.second) ); -} - - -std::vector< double > Persistence_intervals::k_n_n( size_t k , size_t where_to_cut ) -{ - bool dbg = false; - if ( dbg ) - { - cerr << "Here are the intervals : \n"; - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - cerr << "[ " << this->intervals[i].first << " , " << this->intervals[i].second << "] \n"; - } - getchar(); - } - - std::vector< double > result; - //compute all to all distance between point in the diagram. Also, consider points in the diagonal with the infinite multiplicity. - std::vector< std::vector< double > > distances( this->intervals.size() ); - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - std::vector aa(this->intervals.size()); - std::fill( aa.begin() , aa.end() , 0 ); - distances[i] = aa; - } - std::vector< double > distances_from_diagonal( this->intervals.size() ); - std::fill( distances_from_diagonal.begin() , distances_from_diagonal.end() , 0 ); - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - std::vector< double > distancesFromI; - for ( size_t j = i+1 ; j != this->intervals.size() ; ++j ) - { - distancesFromI.push_back( compute_euclidean_distance( this->intervals[i] , this->intervals[j] ) ); - } - //distances.push_back( distancesFromI ); - //also add a distance from this guy to daigonal: - double distanceToDiagonal = compute_euclidean_distance( this->intervals[i] , std::make_pair( 0.5*(this->intervals[i].first + this->intervals[i].second) , 0.5*(this->intervals[i].first + this->intervals[i].second) ) ); - distances_from_diagonal[i] = distanceToDiagonal; - - if ( dbg ) - { - cerr << "Here are the distances form the point : [" << this->intervals[i].first << " , " << this->intervals[i].second << "] in the diagram \n"; - for ( size_t aa = 0 ; aa != distancesFromI.size() ; ++aa ) - { - cerr << "To : " << i+aa << " : " << distancesFromI[aa] << " "; - } - cerr << endl; - getchar(); - } - - //filling in the distances matrix: - for ( size_t j = i+1 ; j != this->intervals.size() ; ++j ) - { - distances[i][j] = distancesFromI[j-i-1]; - distances[j][i] = distancesFromI[j-i-1]; - } - } - if ( dbg ) - { - cerr << "Here is the distance matrix : \n"; - for ( size_t i = 0 ; i != distances.size() ; ++i ) - { - for ( size_t j = 0 ; j != distances.size() ; ++j ) - { - cerr << distances[i][j] << " "; - } - cerr << endl; - } - cerr << endl << endl << "And here are the distances to the diagonal : " << endl; - for ( size_t i = 0 ; i != distances_from_diagonal. size() ; ++i ) - { - cerr << distances_from_diagonal[i] << " "; - } - cerr << endl << endl; - getchar(); - } - - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - std::vector< double > distancesFromI = distances[i]; - distancesFromI.push_back( distances_from_diagonal[i] ); - - //sort it: - std::sort( distancesFromI.begin() , distancesFromI.end() , std::greater() ); - - if ( k > distancesFromI.size() ) - { - if ( dbg ) - { - cerr << "There are not enough neighbors in your set. We set the result to plus infty \n"; - } - result.push_back( std::numeric_limits::max() ); - } - else - { - if ( distances_from_diagonal[i] > distancesFromI[k] ) - { - if ( dbg ) - { - cerr << "The k-th n.n. is on a diagonal. Therefore we set up a distance to diagonal \n"; - } - result.push_back( distances_from_diagonal[i] ); - } - else - { - result.push_back( distancesFromI[k] ); - } - } - } - std::sort( result.begin() , result.end() , std::greater() ); - result.resize( std::min( result.size() , where_to_cut ) ); - - return result; -} - - -std::pair Persistence_intervals::min_max() -{ - double min_ = INT_MAX; - double max_ = -INT_MAX; - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - if ( this->intervals[i].first < min_ )min_ = this->intervals[i].first; - if ( this->intervals[i].second > max_ )max_ = this->intervals[i].second; - } - return std::make_pair( min_ , max_ ); -} - -double Persistence_intervals::project_to_R( int number_of_function ) -{ - double result = 0; - - for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) - { - result += ( this->intervals[i].second - this->intervals[i].first )*( this->intervals[i].second - this->intervals[i].first ); - } - - return result; -} - - -}//namespace gudhi stat -}//namespace gudhi - -#endif +} + + +std::pair Persistence_intervals::min_max() +{ + double min_ = INT_MAX; + double max_ = -INT_MAX; + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + if ( this->intervals[i].first < min_ )min_ = this->intervals[i].first; + if ( this->intervals[i].second > max_ )max_ = this->intervals[i].second; + } + return std::make_pair( min_ , max_ ); +} + +double Persistence_intervals::project_to_R( int number_of_function ) +{ + double result = 0; + + for ( size_t i = 0 ; i != this->intervals.size() ; ++i ) + { + result += ( this->intervals[i].second - this->intervals[i].first )*( this->intervals[i].second - this->intervals[i].first ); + } + + return result; +} + + +}//namespace gudhi stat +}//namespace gudhi + +#endif diff --git a/src/Gudhi_stat/include/gudhi/concretizations/Persistence_landscapes.h b/src/Gudhi_stat/include/gudhi/concretizations/Persistence_landscapes.h index f728bfbe..403ca455 100644 --- a/src/Gudhi_stat/include/gudhi/concretizations/Persistence_landscapes.h +++ b/src/Gudhi_stat/include/gudhi/concretizations/Persistence_landscapes.h @@ -24,7 +24,7 @@ #ifndef Persistence_landscapes_H #define Persistence_landscapes_H - +//standard include #include #include #include @@ -35,12 +35,13 @@ #include - +//gudhi include #include #include #include #include #include +#include using namespace std; @@ -205,7 +206,7 @@ public: * 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); + Persistence_landscape(const char* filename , size_t dimension = 0); @@ -530,6 +531,10 @@ public: { return this->land; } + + + //a function used to create a gnuplot script for visualization of landscapes + void plot( const char* filename ,int from = -1, int to = -1 , double xRangeBegin = -1 , double xRangeEnd = -1 , double yRangeBegin = -1 , double yRangeEnd = -1 ); private: @@ -566,47 +571,18 @@ Persistence_landscape::Persistence_landscape(const Persistence_landscape& orygin -Persistence_landscape::Persistence_landscape(const char* filename) +Persistence_landscape::Persistence_landscape(const char* filename , size_t dimension) { bool dbg = false; if ( dbg ) { std::cerr << "Using constructor : Persistence_landscape(char* filename)" << std::endl; - } - - //this constructor reads persistence landscape form a file. This file have to be created by this software beforehead - std::ifstream in; - in.open( filename ); - - std::string line; - std::vector< std::pair > barcode; - - while (!in.eof()) - { - getline(in,line); - if ( !(line.length() == 0 || line[0] == '#') ) - { - std::stringstream lineSS; - lineSS << line; - double beginn, endd; - lineSS >> beginn; - lineSS >> endd; - if ( beginn > endd ) - { - double b = beginn; - beginn = endd; - endd = b; - } - barcode.push_back( std::make_pair( beginn , endd ) ); - if (dbg) - { - std::cerr << beginn << " , " << endd << std::endl; - } - } - } - in.close(); - + } + //standard file with barcode + //std::vector< std::pair< double , double > > barcode = read_standard_file( filename ); + //gudhi file with barcode + std::vector< std::pair< double , double > > barcode = read_gudhi_file( filename , dimension ); this->construct_persistence_landscape_from_barcode( barcode ); this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } @@ -1473,6 +1449,49 @@ double compute_inner_product( const Persistence_landscape& l1 , const Persistenc } +void Persistence_landscape::plot( const char* filename , int from, int to , double xRangeBegin , double xRangeEnd , double yRangeBegin , double yRangeEnd ) +{ + //this program create a gnuplot script file that allows to plot persistence diagram. + ofstream out; + + std::ostringstream nameSS; + nameSS << filename << "_GnuplotScript"; + std::string nameStr = nameSS.str(); + out.open( (char*)nameStr.c_str() ); + + if ( (xRangeBegin != -1) || (xRangeEnd != -1) || (yRangeBegin != -1) || (yRangeEnd != -1) ) + { + out << "set xrange [" << xRangeBegin << " : " << xRangeEnd << "]" << endl; + out << "set yrange [" << yRangeBegin << " : " << yRangeEnd << "]" << endl; + } + + if ( from == -1 ){from = 0;} + if ( to == -1 ){to = this->land.size();} + + out << "plot "; + for ( size_t lambda= std::min((size_t)from,this->land.size()) ; lambda != std::min((size_t)to,this->land.size()) ; ++lambda ) + { + out << " '-' using 1:2 title 'l" << lambda << "' with lp"; + if ( lambda+1 != std::min((size_t)to,this->land.size()) ) + { + out << ", \\"; + } + out << endl; + } + + for ( size_t lambda= std::min((size_t)from,this->land.size()) ; lambda != std::min((size_t)to,this->land.size()) ; ++lambda ) + { + for ( size_t i = 1 ; i != this->land[lambda].size()-1 ; ++i ) + { + out << this->land[lambda][i].first << " " << this->land[lambda][i].second << endl; + } + out << "EOF" << endl; + } + cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '" << nameStr << "' in gnuplot to visualize." << endl; +} + + + }//namespace gudhi stat }//namespace gudhi diff --git a/src/Gudhi_stat/include/gudhi/concretizations/Vector_distances_in_diagram.h b/src/Gudhi_stat/include/gudhi/concretizations/Vector_distances_in_diagram.h index bcabadac..ce111426 100644 --- a/src/Gudhi_stat/include/gudhi/concretizations/Vector_distances_in_diagram.h +++ b/src/Gudhi_stat/include/gudhi/concretizations/Vector_distances_in_diagram.h @@ -37,6 +37,7 @@ #include #include #include +#include using namespace std; namespace Gudhi @@ -203,27 +204,13 @@ Vector_distances_in_diagram& Vector_distances_in_diagram::operator =( cons template Vector_distances_in_diagram::Vector_distances_in_diagram( const char* filename , size_t where_to_cut ):Abs_Vectorized_topological_data(where_to_cut) -{ - std::vector< std::pair< double , double > > intervals; - ifstream in; - in.open( filename ); - - if ( !in.good() ) - { - std::cerr << "File : " << filename << " do not exist. The program will now terminate \n"; - throw("File with the persistence diagram do not exist, the program will now terminate.\n"); - } +{ + //standard file with barcode + std::vector< std::pair< double , double > > intervals = read_standard_file( filename ); + //gudhi file with barcode + //std::vector< std::pair< double , double > > intervals = read_gudhi_file( filename , dimension ); - while ( true ) - { - double first; - double second; - in >> first >> second; - if ( in.eof() )break; - intervals.push_back( std::make_pair( first,second ) ); - } this->intervals = intervals; - in.close(); this->compute_sorted_vector_of_distnaces_via_heap( where_to_cut ); set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } -- cgit v1.2.3 From 3bb99253e96d186bdfb3c42ef112086dcf3157c5 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Tue, 24 Jan 2017 16:22:09 +0000 Subject: Edit CMake and Doxy files git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2001 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: cea2ab8fcf5f06109432c74f3433fdbc0f90c5a9 --- CMakeLists.txt | 3 +++ biblio/how_to_cite_gudhi.bib | 9 +++++++++ src/CMakeLists.txt | 1 + src/Doxyfile | 3 ++- src/cmake/modules/GUDHI_user_version_target.txt | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index 1346f5d9..2d27bf8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,6 +126,7 @@ else() include_directories(src/Bottleneck_distance/include/) include_directories(src/Contraction/include/) include_directories(src/Hasse_complex/include/) + include_directories(src/Nerve_GIC/include/) include_directories(src/Persistent_cohomology/include/) include_directories(src/Rips_complex/include/) include_directories(src/Simplex_tree/include/) @@ -149,6 +150,8 @@ else() add_subdirectory(src/Witness_complex/example) add_subdirectory(src/Bitmap_cubical_complex/test) add_subdirectory(src/Bitmap_cubical_complex/example) + add_subdirectory(src/Nerve_GIC/example) + add_subdirectory(src/Nerve_GIC/test) add_subdirectory(src/Alpha_complex/example) add_subdirectory(src/Alpha_complex/test) add_subdirectory(src/Spatial_searching/example) diff --git a/biblio/how_to_cite_gudhi.bib b/biblio/how_to_cite_gudhi.bib index fde1d9b1..f87b53c4 100644 --- a/biblio/how_to_cite_gudhi.bib +++ b/biblio/how_to_cite_gudhi.bib @@ -112,4 +112,13 @@ , booktitle = "{GUDHI} User and Reference Manual" , url = "http://gudhi.gforge.inria.fr/doc/latest/group__bottleneck__distance.html" , year = 2016 +} + +@incollection{gudhi:NerveGIC +, author = "Mathieu Carri\`ere" +, title = "Nerve and GIC" +, publisher = "{GUDHI Editorial Board}" +, booktitle = "{GUDHI} User and Reference Manual" +, url = "http://gudhi.gforge.inria.fr/doc/latest/group__Nerve__GIC.html" +, year = 2017 } \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb349052..ebdcdcea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -117,6 +117,7 @@ else() add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) + add_subdirectory(example/Nerve_GIC) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Doxyfile b/src/Doxyfile index a41c6d6f..f06fbd23 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -851,7 +851,8 @@ IMAGE_PATH = doc/Skeleton_blocker/ \ doc/Subsampling/ \ doc/Spatial_searching/ \ doc/Tangential_complex/ \ - doc/Bottleneck_distance/ + doc/Bottleneck_distance/ \ + doc/Nerve_GIC/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/src/cmake/modules/GUDHI_user_version_target.txt b/src/cmake/modules/GUDHI_user_version_target.txt index 6332b065..71e35353 100644 --- a/src/cmake/modules/GUDHI_user_version_target.txt +++ b/src/cmake/modules/GUDHI_user_version_target.txt @@ -48,7 +48,7 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI) - set(GUDHI_MODULES "common;Alpha_complex;Bitmap_cubical_complex;Bottleneck_distance;Contraction;Hasse_complex;Persistent_cohomology;Rips_complex;Simplex_tree;Skeleton_blocker;Spatial_searching;Subsampling;Tangential_complex;Witness_complex") + set(GUDHI_MODULES "common;Alpha_complex;Bitmap_cubical_complex;Bottleneck_distance;Contraction;Hasse_complex;Nerve_GIC;Persistent_cohomology;Rips_complex;Simplex_tree;Skeleton_blocker;Spatial_searching;Subsampling;Tangential_complex;Witness_complex") foreach(GUDHI_MODULE ${GUDHI_MODULES}) # doc files -- cgit v1.2.3 From 8f4c961a93fe928d06c7776a9e8f5ecd00fab9ca Mon Sep 17 00:00:00 2001 From: pdlotko Date: Wed, 12 Apr 2017 13:07:58 +0000 Subject: a few more correction. First of all, bottleneck distance is added (although there is something strange in the results, FG has been pinged about this). Second of all, all the programs in utylites should now read general files (and dimension of persistence to be read is one of the parameteds of files). This still need to be tested and will be tested soon. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@2339 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: e60d14f07db223646597230d7f0bd78dd090bc0b --- src/CMakeLists.txt | 1 + src/Doxyfile | 3 +- src/Gudhi_stat/doc/average_landscape.png | Bin 0 -> 14917 bytes src/Gudhi_stat/include/gudhi/permutation_test.h | 2 + .../gudhi/persistence_representations/PSSK.h | 12 ++- .../Persistence_heat_maps.h | 16 ++- .../Persistence_intervals.h | 39 ++----- .../Persistence_intervals_with_distances.h | 76 ++++++++++++++ .../Persistence_landscape.h | 21 ++-- .../Persistence_landscape_on_grid.h | 82 +++++++++------ .../persistence_vectors.h | 20 ++-- src/Gudhi_stat/include/gudhi/topological_process.h | 5 +- .../test/persistence_lanscapes_on_grid_test.cpp | 35 ++++--- .../utilities/Multiplicative_bootstrap.cpp | 2 +- src/Gudhi_stat/utilities/permutation_test.cpp | 2 +- .../create_persistence_heat_maps.cpp | 20 ++-- ...aps_weighted_by_arctan_of_their_persistence.cpp | 18 +++- ...eat_maps_weighted_by_distance_from_diagonal.cpp | 14 ++- ..._weighted_by_squared_distance_from_diagonal.cpp | 18 +++- .../persistence_heat_maps/create_pssk.cpp | 17 ++- .../utilities/persistence_intervals/CMakeLists.txt | 15 ++- ...te_birth_death_range_in_persistence_diagram.cpp | 24 +++-- .../compute_bottleneck_distance.cpp | 115 +++++++++++++++++++++ .../compute_number_of_dominant_intervals.cpp | 15 ++- .../plot_histogram_of_intervals_lengths.cpp | 13 ++- .../plot_persistence_Betti_numbers.cpp | 100 ++++++++++++++++++ .../plot_persistence_Betti_numebrs.cpp | 90 ---------------- .../plot_persistence_intervals.cpp | 16 ++- .../persistence_landscapes/create_landscapes.cpp | 17 ++- .../create_landscapes_on_grid.cpp | 17 ++- .../create_persistence_vectors.cpp | 16 ++- 31 files changed, 593 insertions(+), 248 deletions(-) create mode 100644 src/Gudhi_stat/doc/average_landscape.png create mode 100644 src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals_with_distances.h create mode 100644 src/Gudhi_stat/utilities/persistence_intervals/compute_bottleneck_distance.cpp create mode 100644 src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp delete mode 100644 src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numebrs.cpp (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3779cb80..c94110a6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) add_subdirectory(example/Gudhi_stat) +add_subdirectory(example/Gudhi_stat/utilities) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Doxyfile b/src/Doxyfile index d2d0a447..f3782148 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -851,7 +851,8 @@ IMAGE_PATH = doc/Skeleton_blocker/ \ doc/Subsampling/ \ doc/Spatial_searching/ \ doc/Tangential_complex/ \ - doc/Bottleneck_distance/ + doc/Bottleneck_distance/ \ + doc/Gudhi_stat/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/src/Gudhi_stat/doc/average_landscape.png b/src/Gudhi_stat/doc/average_landscape.png new file mode 100644 index 00000000..ea59926b Binary files /dev/null and b/src/Gudhi_stat/doc/average_landscape.png differ diff --git a/src/Gudhi_stat/include/gudhi/permutation_test.h b/src/Gudhi_stat/include/gudhi/permutation_test.h index b4c1a8ba..69b0790b 100644 --- a/src/Gudhi_stat/include/gudhi/permutation_test.h +++ b/src/Gudhi_stat/include/gudhi/permutation_test.h @@ -37,6 +37,8 @@ namespace Gudhi namespace Gudhi_stat { +//TODO change the reading procedures so that they accept the dimension value (by default std::nnumeric_limits::max(). + template double permutation_test( const std::vector& data_1 , const std::vector& data_2 , size_t number_of_permutations , double exponent = 1 ) { diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/PSSK.h b/src/Gudhi_stat/include/gudhi/persistence_representations/PSSK.h index 7a299a86..d2fd3a86 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/PSSK.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/PSSK.h @@ -53,10 +53,18 @@ public: } - PSSK( const char* filename , std::vector< std::vector > filter = create_Gaussian_filter(5,1) , size_t number_of_pixels = 1000 , double min_ = -1 , double max_ = -1 ): + PSSK( const char* filename , std::vector< std::vector > filter = create_Gaussian_filter(5,1) , size_t number_of_pixels = 1000 , double min_ = -1 , double max_ = -1 , unsigned dimension = std::numeric_limits::max() ): Persistence_heat_maps() { - std::vector< std::pair< double , double > > intervals_ = read_standard_persistence_file( filename ); + std::vector< std::pair< double , double > > intervals_; + if ( dimension == std::numeric_limits::max() ) + { + intervals_ = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + intervals_ = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } this->construct( intervals_ , filter , number_of_pixels , min_ , max_ ); } diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_heat_maps.h b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_heat_maps.h index f82f3100..3cfd52f5 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_heat_maps.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_heat_maps.h @@ -230,14 +230,14 @@ public: **/ /** * Construction that takes at the input the following parameters: - * (1) A a name of a file with persistence intervals. The file shold be readable by the function read_standard_persistence_file. All other parameters are optional. They are: + * (1) A a name of a file with persistence intervals. The file shold be readable by the function read_persistence_intervals_in_one_dimension_from_file. All other parameters are optional. They are: * (2) a Gausian filter generated by create_Gaussian_filter filter (the default value of this vaiable is a Gaussian filter of a radius 5), * (3) a boolean value which determines if the area of image below diagonal should, or should not be erased (it will be erased by default). * (4) a number of pixels in each direction (set to 1000 by default). * (5) a min x and y value of points that are to be taken into account. By default it is set to std::numeric_limits::max(), in which case the program compute the values based on the data, * (6) a max x and y value of points that are to be taken into account. By default it is set to std::numeric_limits::max(), in which case the program compute the values based on the data. **/ - Persistence_heat_maps( const char* filename , std::vector< std::vector > filter = create_Gaussian_filter(5,1), bool erase_below_diagonal = false , size_t number_of_pixels = 1000 , double min_ = std::numeric_limits::max() , double max_ = std::numeric_limits::max() ); + Persistence_heat_maps( const char* filename , std::vector< std::vector > filter = create_Gaussian_filter(5,1), bool erase_below_diagonal = false , size_t number_of_pixels = 1000 , double min_ = std::numeric_limits::max() , double max_ = std::numeric_limits::max() , unsigned dimension = std::numeric_limits::max() ); /** @@ -695,9 +695,17 @@ Persistence_heat_maps::Persistence_heat_maps( const std::ve template Persistence_heat_maps::Persistence_heat_maps( const char* filename , std::vector< std::vector > filter, - bool erase_below_diagonal , size_t number_of_pixels , double min_ , double max_ ) + bool erase_below_diagonal , size_t number_of_pixels , double min_ , double max_ , unsigned dimension ) { - std::vector< std::pair< double , double > > intervals_ = read_standard_persistence_file( filename ); + std::vector< std::pair< double , double > > intervals_; + if ( dimension == std::numeric_limits::max() ) + { + intervals_ = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + intervals_ = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } this->construct( intervals_ , filter, erase_below_diagonal , number_of_pixels , min_ , max_ ); this->set_up_parameters_for_basic_classes(); } diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals.h b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals.h index 2c3e4803..2ff4d7f7 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals.h @@ -25,8 +25,6 @@ //gudhi include #include -//Bottleneck distance: -//#include //standard include #include @@ -51,8 +49,9 @@ public: /** * This is a constructor of a class Persistence_intervals from a text file. Each line of the input file is supposed to contain two numbers of a type doube (or convertable to double) * representing the birth and the death of the persistence interval. If the pairs are not sorted so that birth <= death, then the constructor will sort then that way. + * * The second parameter of a constructor is a dimension of intervals to be read from a file. If your file contains only birt-death pairs, use the default value. **/ - Persistence_intervals( const char* filename ); + Persistence_intervals( const char* filename , unsigned dimension = std::numeric_limits::max() ); /** * This is a constructor of a class Persistence_intervals from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elemnets of pairs @@ -247,26 +246,6 @@ public: return this->number_of_functions_for_vectorization; } - /** - *Computations of distance from the current persistnce diagram to the persistence diagram given as a parameter of this function. - *The last but one parameter, power, is here in case we would like to compute p=th Wasserstein distance. At the moment, this method only implement Bottleneck distance, - * which is infinity Wasserstein distance. Therefore any power which is not the default std::numeric_limits< double >::max() will be ignored and an - * exception will be thrown. - * The last parameter, tolerance, it is an additiv error of the approimation, set by default to zero. - **/ - double distance( const Persistence_intervals& second , double power = std::numeric_limits< double >::max() , double tolerance = 0) const - { - if ( power >= std::numeric_limits< double >::max() ) - { - //return Gudhi::persistence_diagram::bottleneck_distance(this->intervals, second.intervals, tolerance); - return 1; - } - else - { - std::cerr << "At the moment Gudhi do not support Wasserstein distances. We only support Bottleneck distance." << std::endl; - throw "At the moment Gudhi do not support Wasserstein distances. We only support Bottleneck distance."; - } - } //end of implementation of functions needed for concepts. //end of implementation of functions needed for concepts. @@ -303,7 +282,7 @@ protected: }; -Persistence_intervals::Persistence_intervals( const char* filename ) +Persistence_intervals::Persistence_intervals( const char* filename , unsigned dimension ) { //bool dbg = false; //ifstream in; @@ -336,10 +315,14 @@ Persistence_intervals::Persistence_intervals( const char* filename ) // } //} //in.close(); - //standard file with barcode - this->intervals = read_standard_persistence_file( filename ); - //gudhi file with barcode - //this->intervals = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); + if ( dimension == std::numeric_limits::max() ) + { + this->intervals = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + this->intervals = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); }//Persistence_intervals diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals_with_distances.h b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals_with_distances.h new file mode 100644 index 00000000..84a95e95 --- /dev/null +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_intervals_with_distances.h @@ -0,0 +1,76 @@ +/* This file is part of the Gudhi hiLibrary. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Pawel Dlotko + * + * Copyright (C) 2015 INRIA (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 Persistence_intervals_WITH_DISTANCES_H_ +#define Persistence_intervals_WITH_DISTANCES_H_ + + +#include +#include + +namespace Gudhi +{ +namespace Gudhi_stat +{ + +class Persistence_intervals_with_distances : public Persistence_intervals +{ +public: + /** + * This is a constructor of a class Persistence_intervals_with_distances from a text file. Each line of the input file is supposed to contain two numbers of a type doube (or convertable to double) + * representing the birth and the death of the persistence interval. If the pairs are not sorted so that birth <= death, then the constructor will sort then that way. + * The second parameter of a constructor is a dimension of intervals to be read from a file. If your file contains only birt-death pairs, use the default value. + **/ + Persistence_intervals_with_distances( const char* filename , unsigned dimension = std::numeric_limits::max() ):Persistence_intervals( filename , dimension ){} + + /** + * This is a constructor of a class Persistence_intervals_with_distances from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elemnets of pairs + * are smaller or equal the second elements of pairs. + **/ + Persistence_intervals_with_distances( const std::vector< std::pair< double,double > >& intervals ):Persistence_intervals( intervals ){} + + /** + *Computations of distance from the current persistnce diagram to the persistence diagram given as a parameter of this function. + *The last but one parameter, power, is here in case we would like to compute p=th Wasserstein distance. At the moment, this method only implement Bottleneck distance, + * which is infinity Wasserstein distance. Therefore any power which is not the default std::numeric_limits< double >::max() will be ignored and an + * exception will be thrown. + * The last parameter, tolerance, it is an additiv error of the approimation, set by default to zero. + **/ + double distance( const Persistence_intervals_with_distances& second , double power = std::numeric_limits< double >::max() , double tolerance = 0) const + { + if ( power >= std::numeric_limits< double >::max() ) + { + return Gudhi::persistence_diagram::bottleneck_distance(this->intervals, second.intervals, tolerance); + } + else + { + std::cerr << "At the moment Gudhi do not support Wasserstein distances. We only support Bottleneck distance." << std::endl; + throw "At the moment Gudhi do not support Wasserstein distances. We only support Bottleneck distance."; + } + } +}; + + +}//namespace gudhi stat +}//namespace gudhi + +#endif diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape.h b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape.h index 0d8fe5fe..681f5d8d 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape.h @@ -80,7 +80,7 @@ public: * 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 = 0); + Persistence_landscape(const char* filename , size_t dimension = std::numeric_limits::max() ); @@ -548,13 +548,18 @@ Persistence_landscape::Persistence_landscape(const char* filename , size_t dimen if ( dbg ) { std::cerr << "Using constructor : Persistence_landscape(char* filename)" << std::endl; - } - //standard file with barcode - //std::vector< std::pair< double , double > > barcode = read_standard_persistence_file( filename ); - //gudhi file with barcode - std::vector< std::pair< double , double > > barcode = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); - this->construct_persistence_landscape_from_barcode( barcode ); - this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); + } + std::vector< std::pair< double , double > > barcode; + if ( dimension == std::numeric_limits::max() ) + { + barcode = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + barcode = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } + this->construct_persistence_landscape_from_barcode( barcode ); + this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals(); } diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape_on_grid.h b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape_on_grid.h index 02a80435..1f4cb3ff 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape_on_grid.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/Persistence_landscape_on_grid.h @@ -33,6 +33,7 @@ #include #include #include +#include //gudhi include @@ -84,14 +85,14 @@ public: * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameters of this procedure are: ranges of grid, resoltion of a grid * number of landscape functions to be created and the dimension of intervals that are need to be read from a file (in case of Gudhi format files). **/ - Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned number_of_levels_of_landscape , size_t dimension_ = 0 ); + Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned number_of_levels_of_landscape , unsigned short dimension_ = 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. The additional parameters of this procedure are: ranges of grid, resoltion of a grid * and the dimension of intervals that are need to be read from a file (in case of Gudhi format files). **/ - Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , size_t dimension_ = 0 ); + Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned short dimension_ = std::numeric_limits::max() ); /** @@ -99,14 +100,15 @@ public: * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameter is the resoution of a grid and the number of landscape * functions to be created. The remaning parameters are calculated based on data. **/ - Persistence_landscape_on_grid(const char* filename , size_t number_of_points , unsigned number_of_levels_of_landscape ); + Persistence_landscape_on_grid(const char* filename , size_t number_of_points , unsigned number_of_levels_of_landscape , unsigned short dimension = 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. The additional parameter is the resoution of a grid. The remaning paraameters are - * calculated based on data. + * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameter is the resoution of a grid. The last parameter is the dimension + * of a persistence to read from the file. If your file contains only persistence pair in a single dimension, please set it up to std::numeric_limits::max(). + * The remaning parameters are calculated based on data. **/ - Persistence_landscape_on_grid(const char* filename , size_t number_of_points ); + Persistence_landscape_on_grid(const char* filename , size_t number_of_points , unsigned short dimension = std::numeric_limits::max() ); /** @@ -1256,33 +1258,45 @@ Persistence_landscape_on_grid::Persistence_landscape_on_grid( const std::vector< } -Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , size_t dimension ) +Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned short dimension ) { - //standard file with barcode - std::vector< std::pair< double , double > > p = read_standard_persistence_file( filename ); - //gudhi file with barcode - //std::vector< std::pair< double , double > > p = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); - - this->set_up_values_of_landscapes( p , grid_min_ , grid_max_ , number_of_points_ ); + std::vector< std::pair< double , double > > p; + if ( dimension == std::numeric_limits::max() ) + { + p = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + p = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } + this->set_up_values_of_landscapes( p , grid_min_ , grid_max_ , number_of_points_ ); } -Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_, unsigned number_of_levels_of_landscape, size_t dimension ) +Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_, unsigned number_of_levels_of_landscape, unsigned short dimension ) { - //standard file with barcode - std::vector< std::pair< double , double > > p = read_standard_persistence_file( filename ); - //gudhi file with barcode - //std::vector< std::pair< double , double > > p = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); - - this->set_up_values_of_landscapes( p , grid_min_ , grid_max_ , number_of_points_ , number_of_levels_of_landscape ); + std::vector< std::pair< double , double > > p; + if ( dimension == std::numeric_limits::max() ) + { + p = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + p = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } + this->set_up_values_of_landscapes( p , grid_min_ , grid_max_ , number_of_points_ , number_of_levels_of_landscape ); } -Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , size_t number_of_points_ ) +Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , size_t number_of_points_ , unsigned short dimension ) { - //standard file with barcode - std::vector< std::pair< double , double > > p = read_standard_persistence_file( filename ); - //gudhi file with barcode - //std::vector< std::pair< double , double > > p = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); - + std::vector< std::pair< double , double > > p; + if ( dimension == std::numeric_limits::max() ) + { + p = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + p = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } double grid_min_ = std::numeric_limits::max(); double grid_max_ = -std::numeric_limits::max(); for ( size_t i = 0 ; i != p.size() ; ++i ) @@ -1293,13 +1307,17 @@ Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filenam this->set_up_values_of_landscapes( p , grid_min_ , grid_max_ , number_of_points_ ); } -Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , size_t number_of_points_ , unsigned number_of_levels_of_landscape ) +Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename , size_t number_of_points_ , unsigned number_of_levels_of_landscape , unsigned short dimension ) { - //standard file with barcode - std::vector< std::pair< double , double > > p = read_standard_persistence_file( filename ); - //gudhi file with barcode - //std::vector< std::pair< double , double > > p = read_gudhi_persistence_file_in_one_dimension( filename , dimension ); - + std::vector< std::pair< double , double > > p; + if ( dimension == std::numeric_limits::max() ) + { + p = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + p = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } double grid_min_ = std::numeric_limits::max(); double grid_max_ = -std::numeric_limits::max(); for ( size_t i = 0 ; i != p.size() ; ++i ) diff --git a/src/Gudhi_stat/include/gudhi/persistence_representations/persistence_vectors.h b/src/Gudhi_stat/include/gudhi/persistence_representations/persistence_vectors.h index b1a3e4fd..aa1f23c2 100644 --- a/src/Gudhi_stat/include/gudhi/persistence_representations/persistence_vectors.h +++ b/src/Gudhi_stat/include/gudhi/persistence_representations/persistence_vectors.h @@ -105,7 +105,7 @@ public: /** * The constructor taking as an input a file with birth-death pairs. The second parameter is the desiered length of the output vectors. **/ - Vector_distances_in_diagram( const char* filename , size_t where_to_cut ); + Vector_distances_in_diagram( const char* filename , size_t where_to_cut , unsigned dimension = std::numeric_limits::max() ); /** @@ -432,13 +432,17 @@ Vector_distances_in_diagram::Vector_distances_in_diagram( const std::vector< } template -Vector_distances_in_diagram::Vector_distances_in_diagram( const char* filename , size_t where_to_cut ):where_to_cut(where_to_cut) -{ - //standard file with barcode - std::vector< std::pair< double , double > > intervals = read_standard_persistence_file( filename ); - //gudhi file with barcode - //std::vector< std::pair< double , double > > intervals = read_gudhi_persistence_file( filename , dimension ); - +Vector_distances_in_diagram::Vector_distances_in_diagram( const char* filename , size_t where_to_cut , unsigned dimension ):where_to_cut(where_to_cut) +{ + std::vector< std::pair< double , double > > intervals; + if ( dimension == std::numeric_limits::max() ) + { + intervals = read_persistence_intervals_in_one_dimension_from_file( filename ); + } + else + { + intervals = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); + } this->intervals = intervals; this->compute_sorted_vector_of_distances_via_heap( where_to_cut ); //this->compute_sorted_vector_of_distances_via_vector_sorting( where_to_cut ); diff --git a/src/Gudhi_stat/include/gudhi/topological_process.h b/src/Gudhi_stat/include/gudhi/topological_process.h index 17bea5ab..03edbb85 100644 --- a/src/Gudhi_stat/include/gudhi/topological_process.h +++ b/src/Gudhi_stat/include/gudhi/topological_process.h @@ -39,6 +39,9 @@ namespace Gudhi { namespace Gudhi_stat { + + +//TODO, change reading procedures so that they also accept the value of dimension. //over here we will need a few version of construct_representation_from_file procedure, since different representations may require different parameters. This is a procedure that in my //oppinion cannot be standarize, since construction of representation cannot. But, the remaining part of the code in my opinion is free from any details of representation. @@ -62,7 +65,7 @@ std::vector< std::vector< std::pair< double , double > > > read_persistence_pair for ( size_t i = 0 ; i != files.size() ; ++i ) { - std::vector< std::pair< double , double > > diag = read_standard_persistence_file( files[i].c_str() ); + std::vector< std::pair< double , double > > diag = read_persistence_intervals_in_one_dimension_from_file( files[i].c_str() ); result.push_back( diag ); if ( dbg ) { diff --git a/src/Gudhi_stat/test/persistence_lanscapes_on_grid_test.cpp b/src/Gudhi_stat/test/persistence_lanscapes_on_grid_test.cpp index ae771149..54fb2b84 100644 --- a/src/Gudhi_stat/test/persistence_lanscapes_on_grid_test.cpp +++ b/src/Gudhi_stat/test/persistence_lanscapes_on_grid_test.cpp @@ -44,7 +44,7 @@ double epsilon = 0.0000005; BOOST_AUTO_TEST_CASE(check_construction_of_landscape) { - Persistence_landscape_on_grid l( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid l( "data/file_with_diagram_1" , 100 , std::numeric_limits::max()); l.print_to_file( "landscape_from_file_with_diagram_1" ); Persistence_landscape_on_grid g; @@ -57,8 +57,8 @@ BOOST_AUTO_TEST_CASE(check_construction_of_landscape_using_only_ten_levels) { //TODO unsigned number = 10; - Persistence_landscape_on_grid l( "data/file_with_diagram_1" , 100 ,number ); - Persistence_landscape_on_grid g( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid l( "data/file_with_diagram_1" , 100 , number ); + Persistence_landscape_on_grid g( "data/file_with_diagram_1" , 100 , std::numeric_limits::max()); //cut all the elements of order > 10 in g. for ( size_t level = 0 ; level != number ; ++level ) @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(check_construction_of_landscape_using_only_ten_levels) BOOST_AUTO_TEST_CASE(check_computations_of_integrals) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100 , std::numeric_limits::max()); double integral = p.compute_integral_of_landscape(); //cerr << "integral : " << integral << endl;getchar(); BOOST_CHECK( fabs( integral - 27.343 ) <= 0.00005 ); @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals) BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100, std::numeric_limits::max() ); std::vector< double > integrals_fir_different_levels; //integrals_fir_different_levels.push_back(); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_for_each_level_separatelly) BOOST_AUTO_TEST_CASE(check_computations_of_integrals_of_powers_of_landscape) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100, std::numeric_limits::max() ); std::vector integrals_fir_different_powers; integrals_fir_different_powers.push_back( 0.241168); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(check_computations_of_integrals_of_powers_of_landscape) BOOST_AUTO_TEST_CASE(check_computations_of_values_on_different_points) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 100, std::numeric_limits::max() ); std::vector< double > results_level_0; results_level_0.push_back(0.00997867); @@ -184,8 +184,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_values_on_different_points) BOOST_AUTO_TEST_CASE(check_computations_sum_differences_and_multiplications) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" ,100 ); - Persistence_landscape_on_grid second("data/file_with_diagram_1" , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" ,100 , std::numeric_limits::max()); + Persistence_landscape_on_grid second("data/file_with_diagram_1" , 100, std::numeric_limits::max() ); Persistence_landscape_on_grid sum = p + second; Persistence_landscape_on_grid difference = p - second; @@ -210,8 +210,8 @@ BOOST_AUTO_TEST_CASE(check_computations_sum_differences_and_multiplications) BOOST_AUTO_TEST_CASE(check_computations_of_maxima_and_norms) { - Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 0 , 1 , 100 ); - Persistence_landscape_on_grid second("data/file_with_diagram_2" , 0 , 1 , 100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram_1" , 0. , 1. , 100 ); + Persistence_landscape_on_grid second("data/file_with_diagram_2" , 0. , 1. , 100 ); Persistence_landscape_on_grid sum = p + second; //cerr << p.compute_maximum() << endl; @@ -236,8 +236,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_maxima_and_norms) BOOST_AUTO_TEST_CASE(check_computations_of_averages) { - Persistence_landscape_on_grid p( "data/file_with_diagram", 0,1,100 ); - Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0,1,100 ); + Persistence_landscape_on_grid p( "data/file_with_diagram", 0.,1.,100 ); + Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0.,1.,100 ); Persistence_landscape_on_grid av; av.compute_average( {&p,&q} ); @@ -251,8 +251,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_averages) BOOST_AUTO_TEST_CASE(check_computations_of_distances) { - Persistence_landscape_on_grid p( "data/file_with_diagram", 0,1,10000 ); - Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0,1,10000 ); + Persistence_landscape_on_grid p( "data/file_with_diagram", 0.,1.,10000 ); + Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0.,1.,10000 ); BOOST_CHECK( fabs( p.distance( q )- 25.5779) <= 0.00005 ); BOOST_CHECK( fabs( p.distance( q , 2) - 2.04891) <= 0.00001 ); BOOST_CHECK( fabs( p.distance( q , std::numeric_limits::max() )-0.359 ) <= 0.00001 ); @@ -261,8 +261,8 @@ BOOST_AUTO_TEST_CASE(check_computations_of_distances) BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) { - Persistence_landscape_on_grid p( "data/file_with_diagram" , 0,1,10000); - Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0,1,10000 ); + Persistence_landscape_on_grid p( "data/file_with_diagram" , 0.,1.,10000); + Persistence_landscape_on_grid q( "data/file_with_diagram_1", 0.,1.,10000 ); //std::cerr << p.compute_scalar_product( q ) << std::endl; BOOST_CHECK( almost_equal( p.compute_scalar_product( q ) , 0.754367 ) ); } @@ -375,3 +375,4 @@ BOOST_AUTO_TEST_CASE(check_computations_of_scalar_product) //Persistence_landscape_on_grid q( aa, 0,1,10 ); cerr << p.compute_scalar_product( &q ) << endl; */ + diff --git a/src/Gudhi_stat/utilities/Multiplicative_bootstrap.cpp b/src/Gudhi_stat/utilities/Multiplicative_bootstrap.cpp index 42534752..7ee389f8 100644 --- a/src/Gudhi_stat/utilities/Multiplicative_bootstrap.cpp +++ b/src/Gudhi_stat/utilities/Multiplicative_bootstrap.cpp @@ -51,7 +51,7 @@ int main( int argc , char** argv ) std::vector< Persistence_landscape* > collection_of_landscapes( filenames.size() ); for ( size_t i = 0 ; i != filenames.size() ; ++i ) { - std::vector< std::pair< double , double > > diag = read_gudhi_persistence_file_in_one_dimension( filenames[i].c_str() , 1 );//read_standard_persistence_file( filenames[i].c_str() ); + std::vector< std::pair< double , double > > diag = read_persistence_intervals_in_one_dimension_from_file( filenames[i].c_str() ); collection_of_landscapes[i] = new Persistence_landscape( diag ); } diff --git a/src/Gudhi_stat/utilities/permutation_test.cpp b/src/Gudhi_stat/utilities/permutation_test.cpp index e431026f..62cd3f10 100644 --- a/src/Gudhi_stat/utilities/permutation_test.cpp +++ b/src/Gudhi_stat/utilities/permutation_test.cpp @@ -62,7 +62,7 @@ int main( int argc , char** argv ) std::vector< Persistence_landscape* > first_collection( first_group.size() ); for ( size_t i = 0 ; i != first_group.size() ; ++i ) { - std::vector< std::pair< double , double > > diag = read_standard_persistence_file( first_group[i].c_str() ); + std::vector< std::pair< double , double > > diag = read_persistence_intervals_in_one_dimension_from_file( first_group[i].c_str() ); Persistence_landscape* l = new Persistence_landscape( diag ); first_collection[i] = l; } diff --git a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp index 5d2100aa..d9c7aded 100644 --- a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp +++ b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp @@ -40,26 +40,32 @@ int main( int argc , char** argv ) std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; - std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; + std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; + std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; + std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; + std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; if ( argc < 5 ) { std::cout << "Wrong parameter list, the program will now terminate \n"; return 1; - } - + } size_t size_of_grid = (size_t)atoi( argv[1] ); double min_ = atof( argv[2] ); double max_ = atof( argv[3] ); size_t stdiv = atof( argv[4] ); + unsigned dimension = std::numeric_limits::max(); + int dim = atoi( argv[5] ); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } std::vector< const char* > filenames; - for ( int i = 5 ; i < argc ; ++i ) + for ( int i = 6 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } - - std::cout << "Creating persistence heat maps...\n"; std::vector< std::vector > filter = create_Gaussian_filter(stdiv,1); @@ -67,7 +73,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl; - Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ ); + Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ , dimension ); std::stringstream ss; ss << filenames[i] << ".mps"; diff --git a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_arctan_of_their_persistence.cpp b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_arctan_of_their_persistence.cpp index 8496e33e..7cb7eeb7 100644 --- a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_arctan_of_their_persistence.cpp +++ b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_arctan_of_their_persistence.cpp @@ -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. * @@ -40,8 +40,11 @@ int main( int argc , char** argv ) std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; + std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; + std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; - + if ( argc < 5 ) { std::cout << "Wrong parameter list, the program will now terminate \n"; @@ -53,8 +56,15 @@ int main( int argc , char** argv ) double max_ = atof( argv[3] ); size_t stdiv = atof( argv[4] ); + unsigned dimension = std::numeric_limits::max(); + int dim = atoi( argv[5] ); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + std::vector< const char* > filenames; - for ( int i = 5 ; i < argc ; ++i ) + for ( int i = 6 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -67,7 +77,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl; - Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ ); + Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ , dimension ); std::stringstream ss; ss << filenames[i] << ".mps"; diff --git a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_distance_from_diagonal.cpp b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_distance_from_diagonal.cpp index 83d4f3bc..3242e106 100644 --- a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_distance_from_diagonal.cpp +++ b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_distance_from_diagonal.cpp @@ -39,6 +39,9 @@ int main( int argc , char** argv ) std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; + std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; + std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; if ( argc < 5 ) @@ -52,8 +55,15 @@ int main( int argc , char** argv ) double max_ = atof( argv[3] ); size_t stdiv = atof( argv[4] ); + unsigned dimension = std::numeric_limits::max(); + int dim = atoi( argv[5] ); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + std::vector< const char* > filenames; - for ( int i = 5 ; i < argc ; ++i ) + for ( int i = 6 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -66,7 +76,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl; - Persistence_heat_maps l( filenames[i] , filter , size_of_grid , min_ , max_ ); + Persistence_heat_maps l( filenames[i] , filter , size_of_grid , min_ , max_ , dimension ); std::stringstream ss; ss << filenames[i] << ".mps"; diff --git a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_squared_distance_from_diagonal.cpp b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_squared_distance_from_diagonal.cpp index f62615f5..27846a99 100644 --- a/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_squared_distance_from_diagonal.cpp +++ b/src/Gudhi_stat/utilities/persistence_heat_maps/create_persistence_heat_maps_weighted_by_squared_distance_from_diagonal.cpp @@ -39,8 +39,11 @@ int main( int argc , char** argv ) std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; + std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; + std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; - + if ( argc < 5 ) { std::cout << "Wrong parameter list, the program will now terminate \n"; @@ -51,14 +54,19 @@ int main( int argc , char** argv ) double min_ = atof( argv[2] ); double max_ = atof( argv[3] ); size_t stdiv = atof( argv[4] ); + + unsigned dimension = std::numeric_limits::max(); + int dim = atoi( argv[5] ); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } std::vector< const char* > filenames; - for ( int i = 5 ; i < argc ; ++i ) + for ( int i = 6 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } - - std::cout << "Creating persistence heat maps...\n"; std::vector< std::vector > filter = create_Gaussian_filter(stdiv,1); @@ -66,7 +74,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl; - Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ ); + Persistence_heat_maps l( filenames[i] , filter, false , size_of_grid , min_ , max_ , dimension ); std::stringstream ss; ss << filenames[i] << ".mps"; diff --git a/src/Gudhi_stat/utilities/persistence_heat_maps/create_pssk.cpp b/src/Gudhi_stat/utilities/persistence_heat_maps/create_pssk.cpp index d38bb8b9..404a4be3 100644 --- a/src/Gudhi_stat/utilities/persistence_heat_maps/create_pssk.cpp +++ b/src/Gudhi_stat/utilities/persistence_heat_maps/create_pssk.cpp @@ -38,8 +38,12 @@ int main( int argc , char** argv ) std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; + std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; + std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; - + if ( argc < 5 ) { std::cout << "Wrong parameter list, the program will now terminate \n"; @@ -51,8 +55,15 @@ int main( int argc , char** argv ) double max_ = atof( argv[3] ); size_t stdiv = atof( argv[4] ); + unsigned dimension = std::numeric_limits::max(); + int dim = atoi( argv[5] ); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + std::vector< const char* > filenames; - for ( int i = 5 ; i < argc ; ++i ) + for ( int i = 6 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -63,7 +74,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { std::cout << "Creating a heat map based on a file : " << filenames[i] << std::endl; - PSSK l( filenames[i] , filter , size_of_grid , min_ , max_ ); + PSSK l( filenames[i] , filter , size_of_grid , min_ , max_ , dimension ); std::stringstream ss; ss << filenames[i] << ".pssk"; diff --git a/src/Gudhi_stat/utilities/persistence_intervals/CMakeLists.txt b/src/Gudhi_stat/utilities/persistence_intervals/CMakeLists.txt index 96cb1a5e..9420a8ea 100644 --- a/src/Gudhi_stat/utilities/persistence_intervals/CMakeLists.txt +++ b/src/Gudhi_stat/utilities/persistence_intervals/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 2.6) project(GUDHI_STAT) - - #persitence diagrams add_executable ( plot_persistence_intervals plot_persistence_intervals.cpp ) target_link_libraries( plot_persistence_intervals ${Boost_SYSTEM_LIBRARY}) @@ -16,7 +14,14 @@ target_link_libraries( compute_number_of_dominant_intervals ${Boost_SYSTEM_LIBRA add_executable ( plot_histogram_of_intervals_lengths plot_histogram_of_intervals_lengths.cpp ) target_link_libraries( plot_histogram_of_intervals_lengths ${Boost_SYSTEM_LIBRARY}) -add_executable ( plot_persistence_Betti_numebrs plot_persistence_Betti_numebrs.cpp ) -target_link_libraries( plot_persistence_Betti_numebrs ${Boost_SYSTEM_LIBRARY}) +add_executable ( plot_persistence_Betti_numbers plot_persistence_Betti_numbers.cpp ) +target_link_libraries( plot_persistence_Betti_numbers ${Boost_SYSTEM_LIBRARY}) + +if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) +add_executable ( compute_bottleneck_distance compute_bottleneck_distance.cpp ) +target_link_libraries( compute_bottleneck_distance ${Boost_SYSTEM_LIBRARY}) +if (TBB_FOUND) +target_link_libraries(compute_bottleneck_distance ${TBB_LIBRARIES}) +endif(TBB_FOUND) -#when we have bottleneck and wasserstein distance computations, add suitable programs here. +endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Gudhi_stat/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp b/src/Gudhi_stat/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp index 145040fe..426a9b7b 100644 --- a/src/Gudhi_stat/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp +++ b/src/Gudhi_stat/utilities/persistence_intervals/compute_birth_death_range_in_persistence_diagram.cpp @@ -37,18 +37,20 @@ using namespace Gudhi::Gudhi_stat; int main( int argc , char** argv ) { - //std::cout << "This program compute minimum birth and the maximum death time for a collection of persistence intervals \n"; - //if ( argc != 2 ) - //{ - // std::cout << "To run this program, please provide the name of a file with persistence diagram \n"; - // return 1; - //} - //Persistence_intervals p( argv[1] ); - //std::pair min_max_ = p.min_max(); - //std::cout << "Birth-death range : min: " << min_max_.first << ", max: " << min_max_.second << endl; + std::cout << "This program compute the range of birth and death times of persistence pairs in diagrams provided as an input. \n"; + std::cout << "The first parameter of the program is the dimension of persistence to be used. If your file contains "; + std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence pairs you want to use. If your input files consist only "; + std::cout << "of birth-death pairs, please set this first parameter to -1 \n"; + std::cout << "The remaining parameters of the program are the names of files with persistence diagrams. \n"; + int dim = atoi( argv[1] ); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } std::vector< const char* > filenames; - for ( int i = 1 ; i < argc ; ++i ) + for ( int i = 2 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -59,7 +61,7 @@ int main( int argc , char** argv ) for ( size_t file_no = 0 ; file_no != filenames.size() ; ++file_no ) { std::cout << "Creating diagram based on a file : " << filenames[file_no] << std::endl; - Persistence_intervals p( filenames[file_no] ); + Persistence_intervals p( filenames[file_no] , dimension ); std::pair min_max_ = p.min_max(); if ( min_max_.first < min_ )min_ = min_max_.first; if ( min_max_.second > max_ )max_ = min_max_.second; diff --git a/src/Gudhi_stat/utilities/persistence_intervals/compute_bottleneck_distance.cpp b/src/Gudhi_stat/utilities/persistence_intervals/compute_bottleneck_distance.cpp new file mode 100644 index 00000000..6f0ba635 --- /dev/null +++ b/src/Gudhi_stat/utilities/persistence_intervals/compute_bottleneck_distance.cpp @@ -0,0 +1,115 @@ +/* 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 (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 + + + +using namespace Gudhi; +using namespace Gudhi::Gudhi_stat; + +#include +#include + + +int main( int argc , char** argv ) +{ + std::cout << "This program compute the bottleneck distance of persistence diarams stored in a files. \n"; + std::cout << "The first parameter of the program is the dimension of persistence to be used to construct persistence landscapes. If your file contains "; + std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence pairs you want to use. If your input files consist only "; + std::cout << "of birth-death pairs, please set this first parameter to -1 \n"; + std::cout << "The remaining parameters of this programs are names of files with persistence diagrams.\n"; + + if ( argc < 3 ) + { + std::cout << "Wrong number of parameters, the program will now terminate \n"; + return 1; + } + + int dim = atoi(argv[1]); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + + + std::vector< const char* > filenames; + for ( int i = 2 ; i < argc ; ++i ) + { + filenames.push_back( argv[i] ); + } + + //reading the persistence intervals: + std::vector< Persistence_intervals_with_distances > persistence_intervals; + for ( size_t i = 0 ; i != filenames.size() ; ++i ) + { + Persistence_intervals_with_distances pers(filenames[i] , dimension ); + std::cerr << "perss : " << pers << std::endl; + getchar(); + persistence_intervals.push_back( pers ); + } + + //and now we will compute the scalar product of landscapes. + + //first we prepare an array: + std::vector< std::vector< double > > distance( filenames.size() ); + for ( size_t i = 0 ; i != filenames.size() ; ++i ) + { + std::vector< double > v( filenames.size() , 0 ); + distance[i] = v; + } + + //and now we can compute the distances: + for ( size_t i = 0 ; i != persistence_intervals.size() ; ++i ) + { + for ( size_t j = i+1 ; j != persistence_intervals.size() ; ++j ) + { + distance[i][j] = distance[j][i] = persistence_intervals[i].distance( persistence_intervals[j] ); + } + } + + //and now output the result to the screen and a file: + std::ofstream out; + out.open( "distance" ); + for ( size_t i = 0 ; i != distance.size() ; ++i ) + { + for ( size_t j = 0 ; j != distance.size() ; ++j ) + { + std::cout << distance[i][j] << " "; + out << distance[i][j] << " "; + } + std::cout << std::endl; + out << std::endl; + } + out.close(); + + return 0; +} + + + + + + + diff --git a/src/Gudhi_stat/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp b/src/Gudhi_stat/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp index eeda703a..0a7f7c2b 100644 --- a/src/Gudhi_stat/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp +++ b/src/Gudhi_stat/utilities/persistence_intervals/compute_number_of_dominant_intervals.cpp @@ -36,14 +36,19 @@ using namespace Gudhi::Gudhi_stat; int main( int argc , char** argv ) { std::cout << "This program compute the dominant intervals. A number of intervals to be displayed is a parameter of this program. \n"; - if ( argc != 3 ) + if ( argc != 4 ) { - std::cout << "To run this program, please provide the name of a file with persistence diagram and number of dominant intervals you would like to get \n"; + std::cout << "To run this program, please provide the name of a file with persistence diagram, dimension of intervals that should be taken into account (if your file contains only persistence pairs in a single dimension, set it up to -1) and number of dominant intervals you would like to get \n"; return 1; } - - Persistence_intervals p( argv[1] ); - std::vector< std::pair > dominant_intervals = p.dominant_intervals( atoi( argv[2] ) ); + int dim = atoi( argv[2] ); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + Persistence_intervals p( argv[1] , dimension ); + std::vector< std::pair > dominant_intervals = p.dominant_intervals( atoi( argv[3] ) ); std::cout << "Here are the dominant intervals : " << std::endl; for ( size_t i = 0 ; i != dominant_intervals.size() ; ++i ) { diff --git a/src/Gudhi_stat/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp b/src/Gudhi_stat/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp index db9c3f98..11876a0d 100644 --- a/src/Gudhi_stat/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp +++ b/src/Gudhi_stat/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp @@ -39,10 +39,21 @@ int main( int argc , char** argv ) if ( argc != 3 ) { std::cout << "To run this program, please provide the name of a file with persistence diagram and number of dominant intervals you would like to get \n"; + std::cout << "The second parameter of a program is the dimension of the persistence that is to be used. If your file contains only birth-death pairs, you can skip this parameter\n"; return 1; } + unsigned dimension = std::numeric_limits::max(); + int dim = -1; + if ( argc > 2 ) + { + dim = atoi( argv[2] ); + } + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } - Persistence_intervals p( argv[1] ); + Persistence_intervals p( argv[1] , dimension ); std::vector< std::pair > dominant_intervals = p.dominant_intervals( atoi( argv[2] ) ); std::vector< size_t > histogram = p.histogram_of_lengths( 10 ); diff --git a/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp b/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp new file mode 100644 index 00000000..09c6cc22 --- /dev/null +++ b/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp @@ -0,0 +1,100 @@ +/* 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 (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::Gudhi_stat; + + +int main( int argc , char** argv ) +{ + std::cout << "This program compute a plot of persistence Betti numbers. The input parameter is a file with persistence intervals. \n"; + std::cout << "The second optional parameter of a program is the dimension of the persistence that is to be used. If your file contains only birth-death pairs, you can skip this parameter\n"; + if ( argc < 2 ) + { + std::cout << "To run this program, please provide the name of a file with persistence diagram and number of dominant intervals you would like to get \n"; + return 1; + } + unsigned dimension = std::numeric_limits::max(); + int dim = -1; + if ( argc > 2 ) + { + dim = atoi( argv[2] ); + } + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + + + std::stringstream gnuplot_script; + gnuplot_script << argv[1] << "_Gnuplot_script"; + std::ofstream out; + out.open( gnuplot_script.str().c_str() ); + + Persistence_intervals p( argv[1] , dimension ); + std::vector< std::pair< double , size_t > > pbns = p.compute_persistent_betti_numbers(); + + //set up the ranges so that we see the image well. + double xRangeBegin = pbns[0].first; + double xRangeEnd = pbns[ pbns.size()-1 ].first; + double yRangeBegin = 0; + double yRangeEnd = 0; + for ( size_t i = 0 ; i != pbns.size() ; ++i ) + { + if ( pbns[i].second > yRangeEnd )yRangeEnd = pbns[i].second; + } + xRangeBegin -= (xRangeEnd -xRangeBegin)/100.0; + xRangeEnd += (xRangeEnd -xRangeBegin)/100.0; + yRangeEnd += yRangeEnd/100; + + + out << "set xrange [" << xRangeBegin << " : " << xRangeEnd << "]" << std::endl; + out << "set yrange [" << yRangeBegin << " : " << yRangeEnd << "]" << std::endl; + out << "plot '-' using 1:2 notitle with lp " << std::endl; + double previous_y = 0; + for ( size_t i = 0 ; i != pbns.size() ; ++i ) + { + out << pbns[i].first << " " << previous_y << std::endl; + out << pbns[i].first << " " << pbns[i].second << std::endl; + previous_y = pbns[i].second; + } + out << std::endl; + out.close(); + + //for ( size_t i = 0 ; i != pbns.size() ; ++i ) + //{ + // std::cout << pbns[i].first << " " << pbns[i].second << std::endl; + //} + + std::cout << "To vizualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; + + return 0; +} diff --git a/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numebrs.cpp b/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numebrs.cpp deleted file mode 100644 index cb89f6b9..00000000 --- a/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_Betti_numebrs.cpp +++ /dev/null @@ -1,90 +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 (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::Gudhi_stat; - - -int main( int argc , char** argv ) -{ - std::cout << "This program compute a plot of persistence Betti numbers. The input parameter is a file with persistence intervals. \n"; - if ( argc != 2 ) - { - std::cout << "To run this program, please provide the name of a file with persistence diagram and number of dominant intervals you would like to get \n"; - return 1; - } - - - - std::stringstream gnuplot_script; - gnuplot_script << argv[1] << "_Gnuplot_script"; - std::ofstream out; - out.open( gnuplot_script.str().c_str() ); - - Persistence_intervals p( argv[1] ); - std::vector< std::pair< double , size_t > > pbns = p.compute_persistent_betti_numbers(); - - //set up the ranges so that we see the image well. - double xRangeBegin = pbns[0].first; - double xRangeEnd = pbns[ pbns.size()-1 ].first; - double yRangeBegin = 0; - double yRangeEnd = 0; - for ( size_t i = 0 ; i != pbns.size() ; ++i ) - { - if ( pbns[i].second > yRangeEnd )yRangeEnd = pbns[i].second; - } - xRangeBegin -= (xRangeEnd -xRangeBegin)/100.0; - xRangeEnd += (xRangeEnd -xRangeBegin)/100.0; - yRangeEnd += yRangeEnd/100; - - - out << "set xrange [" << xRangeBegin << " : " << xRangeEnd << "]" << std::endl; - out << "set yrange [" << yRangeBegin << " : " << yRangeEnd << "]" << std::endl; - out << "plot '-' using 1:2 notitle with lp " << std::endl; - double previous_y = 0; - for ( size_t i = 0 ; i != pbns.size() ; ++i ) - { - out << pbns[i].first << " " << previous_y << std::endl; - out << pbns[i].first << " " << pbns[i].second << std::endl; - previous_y = pbns[i].second; - } - out << std::endl; - out.close(); - - //for ( size_t i = 0 ; i != pbns.size() ; ++i ) - //{ - // std::cout << pbns[i].first << " " << pbns[i].second << std::endl; - //} - - std::cout << "To vizualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; - - return 0; -} diff --git a/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_intervals.cpp b/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_intervals.cpp index bc466bd3..4315abb9 100644 --- a/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_intervals.cpp +++ b/src/Gudhi_stat/utilities/persistence_intervals/plot_persistence_intervals.cpp @@ -42,9 +42,23 @@ int main( int argc , char** argv ) if ( argc != 2 ) { std::cout << "To run this program, please provide the name of a file with persistence diagram \n"; + std::cout << "The second optional parameter of a program is the dimension of the persistence that is to be used. If your file contains only birth-death pairs, you can skip this parameter\n"; return 1; } - std::vector< std::pair< double , double > > intervals = read_gudhi_persistence_file_in_one_dimension( argv[1] , 2 ); + unsigned dimension = std::numeric_limits::max(); + int dim = -1; + if ( argc > 2 ) + { + dim = atoi( argv[2] ); + } + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + + + + std::vector< std::pair< double , double > > intervals = read_persistence_intervals_in_one_dimension_from_file( argv[1] , dimension ); Persistence_intervals b( intervals ); b.plot( argv[1] ); return 0; diff --git a/src/Gudhi_stat/utilities/persistence_landscapes/create_landscapes.cpp b/src/Gudhi_stat/utilities/persistence_landscapes/create_landscapes.cpp index 5485bf2a..f36e313a 100644 --- a/src/Gudhi_stat/utilities/persistence_landscapes/create_landscapes.cpp +++ b/src/Gudhi_stat/utilities/persistence_landscapes/create_landscapes.cpp @@ -32,9 +32,19 @@ using namespace Gudhi::Gudhi_stat; int main( int argc , char** argv ) { - std::cout << "This program creates persistence landscapes of diagrams provided as an input. Please call this program with the names of files with persistence diagrams \n"; + std::cout << "This program creates persistence landscapes of diagrams provided as an input. \n"; + std::cout << "The first parameter of the program is the dimension of persistence to be used to construct persistence landscapes. If your file contains "; + std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence pairs you want to use. If your input files consist only "; + std::cout << "of birth-death pairs, please set this first parameter to -1 \n"; + std::cout << "The remaining parameters of the program are the names of files with persistence diagrams. \n"; std::vector< const char* > filenames; - for ( int i = 1 ; i < argc ; ++i ) + int dim = atoi(argv[1]); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + for ( int i = 2 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -42,8 +52,7 @@ int main( int argc , char** argv ) std::cout << "Creating persistence landscapes...\n"; for ( size_t i = 0 ; i != filenames.size() ; ++i ) { - //std::vector< std::pair< double , double > > pers = read_standard_file( filename ); - Persistence_landscape l( filenames[i] , 1 ); + Persistence_landscape l( filenames[i] , dimension ); std::stringstream ss; ss << filenames[i] << ".land"; l.print_to_file( ss.str().c_str() ); diff --git a/src/Gudhi_stat/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp b/src/Gudhi_stat/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp index 4f36f02d..eb534bf1 100644 --- a/src/Gudhi_stat/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp +++ b/src/Gudhi_stat/utilities/persistence_landscapes_on_grid/create_landscapes_on_grid.cpp @@ -36,9 +36,12 @@ int main( int argc , char** argv ) std::cout << "This program creates persistence landscape on grid of diagrams provided as an input.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; + std::cout << "The fourth parameter of the program is the dimension of persistence to be used to construct persistence landscape on a grid. If your file contains "; + std::cout << "the information about dimension of birth-death pairs, please provide here the dimension of intervals you want to use. If your input files consist only "; + std::cout << "of birth-death pairs, please set the fourth parameter to -1 \n"; std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; - if ( argc < 4 ) + if ( argc < 5 ) { std::cout << "Wrong parameter list, the program will now terminate \n"; return 1; @@ -47,9 +50,15 @@ int main( int argc , char** argv ) size_t size_of_grid = (size_t)atoi( argv[1] ); double min_ = atof( argv[2] ); double max_ = atof( argv[3] ); + int dim = atoi( argv[4] ); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } std::vector< const char* > filenames; - for ( int i = 4 ; i < argc ; ++i ) + for ( int i = 5 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -61,12 +70,12 @@ int main( int argc , char** argv ) Persistence_landscape_on_grid l; if ( (min_ != -1) || (max_ != -1) ) { - l = Persistence_landscape_on_grid( filenames[i] , min_ , max_ , size_of_grid ); + l = Persistence_landscape_on_grid( filenames[i] , min_ , max_ , size_of_grid , dimension ); } else { //(min_ == -1) && (max_ == -1), in this case the program will find min_ and max_ based on the data. - l = Persistence_landscape_on_grid( filenames[i] , size_of_grid ); + l = Persistence_landscape_on_grid( filenames[i] , size_of_grid , dimension ); } std::stringstream ss; ss << filenames[i] << ".g_land"; diff --git a/src/Gudhi_stat/utilities/persistence_vectors/create_persistence_vectors.cpp b/src/Gudhi_stat/utilities/persistence_vectors/create_persistence_vectors.cpp index fc434ba8..40f5e81f 100644 --- a/src/Gudhi_stat/utilities/persistence_vectors/create_persistence_vectors.cpp +++ b/src/Gudhi_stat/utilities/persistence_vectors/create_persistence_vectors.cpp @@ -33,9 +33,19 @@ using namespace Gudhi::Gudhi_stat; int main( int argc , char** argv ) { - std::cout << "This program creates persistence vectors of diagrams provided as an input. Please call this program with the names of files with persistence diagrams \n"; + std::cout << "This program creates persistence vectors of diagrams provided as an input. The first parameter of this program is a dimension of persistence "; + std::cout << " that will be used in creation of the persistence vectors. If our input files contain persistence pairs of various dimension, as a second parameter of the "; + std::cout << " procedure please provide the dimension of persistence you want to use. If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; + std::cout << "The remaining parameters are the names of files with persistence diagrams. \n"; + int dim = atoi( argv[1] ); + unsigned dimension = std::numeric_limits::max(); + if ( (dim != -1) && (dim >= 0) ) + { + dimension = (unsigned)dim; + } + std::vector< const char* > filenames; - for ( int i = 1 ; i < argc ; ++i ) + for ( int i = 2 ; i < argc ; ++i ) { filenames.push_back( argv[i] ); } @@ -44,7 +54,7 @@ int main( int argc , char** argv ) { std::cerr << "Creatign persistence vectors based on a file : " << filenames[i] << std::endl; //std::vector< std::pair< double , double > > persistence_pairs = read_gudhi_persistence_file_in_one_dimension( filenames[i] , size_t dimension = 0 ) - Vector_distances_in_diagram< Euclidean_distance > l( filenames[i] , -1 ); + Vector_distances_in_diagram< Euclidean_distance > l( filenames[i] , dimension ); std::stringstream ss; ss << filenames[i] << ".vect"; l.print_to_file( ss.str().c_str() ); -- cgit v1.2.3 From be976b50b0d036b1cf9efc58f936182647b7cd69 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 21 Apr 2017 16:06:28 +0000 Subject: Fix user version bug git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@2374 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: ff7a428dbe3a5c7c2b45037f66329f1061cf7f7b --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c94110a6..d0e5d5d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,7 @@ add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) add_subdirectory(example/Gudhi_stat) -add_subdirectory(example/Gudhi_stat/utilities) +add_subdirectory(utilities/Gudhi_stat) # data points generator add_subdirectory(data/points/generator) -- cgit v1.2.3 From e129379cf8a173b70ab123be668f4c67edf6f2a1 Mon Sep 17 00:00:00 2001 From: pdlotko Date: Thu, 4 May 2017 11:56:16 +0000 Subject: Adding corrections to cmake files. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/gudhi_stat@2396 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 56eaad66d3c21f84e4965c13f2596739825fc861 --- src/CMakeLists.txt | 6 +++++- src/Gudhi_stat/test/CMakeLists.txt | 11 ----------- 2 files changed, 5 insertions(+), 12 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0e5d5d5..678303de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,7 +53,11 @@ add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) add_subdirectory(example/Gudhi_stat) -add_subdirectory(utilities/Gudhi_stat) +add_subdirectory(utilities/Gudhi_stat/persistence_heat_maps) +add_subdirectory(utilities/Gudhi_stat/persistence_intervals) +add_subdirectory(utilities/Gudhi_stat/persistence_landscapes) +add_subdirectory(utilities/Gudhi_stat/persistence_landscapes_on_grid) +add_subdirectory(utilities/Gudhi_stat/persistence_vectors) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Gudhi_stat/test/CMakeLists.txt b/src/Gudhi_stat/test/CMakeLists.txt index ba457d5d..ab2b1cc3 100644 --- a/src/Gudhi_stat/test/CMakeLists.txt +++ b/src/Gudhi_stat/test/CMakeLists.txt @@ -86,17 +86,6 @@ add_test(NAME read_persistence_from_file_test # XML format for Jenkins xUnit plugin --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/read_persistence_from_file_UT.xml --log_level=test_suite --report_level=no) -file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) -add_executable ( additional_tests additional_tests.cpp ) -target_link_libraries(additional_tests ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) - -# Unitary tests -add_test(NAME additional_tests - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/additional_tests - file(COPY data DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/additional_tests/data") - # XML format for Jenkins xUnit plugin - --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/additional_tests_UT.xml --log_level=test_suite --report_level=no) - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) -- cgit v1.2.3 From 6adf87fe0a609443962238200e877c60d90f6a2d Mon Sep 17 00:00:00 2001 From: mcarrier Date: Fri, 12 May 2017 15:37:55 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2413 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a0a65ae49ca0bb6e5ed614f44cabb060fa0e7490 --- CMakeLists.txt | 3 + data/points/COIL_database/asian_mug.off | 2 + data/points/COIL_database/lucky_cat_PCA1 | 72 +++++++++++++++ src/CMakeLists.txt | 1 + src/Nerve_GIC/example/CMakeLists.txt | 6 ++ src/Nerve_GIC/example/GIC.cpp | 15 ++-- src/Nerve_GIC/example/GICvoronoi.cpp | 59 ++++++++++++ src/Nerve_GIC/example/MapperDeltaCoord.cpp | 13 ++- src/Nerve_GIC/example/MapperDeltaFunc.cpp | 13 ++- src/Nerve_GIC/example/Nerve.cpp | 13 ++- src/Nerve_GIC/include/gudhi/GIC.h | 139 +++++++++++++++++++++-------- src/Nerve_GIC/test/CMakeLists.txt | 23 +++++ src/common/doc/main_page.h | 18 ++++ 13 files changed, 309 insertions(+), 68 deletions(-) create mode 100644 data/points/COIL_database/lucky_cat_PCA1 create mode 100644 src/Nerve_GIC/example/GICvoronoi.cpp create mode 100644 src/Nerve_GIC/test/CMakeLists.txt (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index aef771d0..f9029bb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ include_directories(src/Spatial_searching/include/) include_directories(src/Subsampling/include/) include_directories(src/Tangential_complex/include/) include_directories(src/Witness_complex/include/) +include_directories(src/Nerve_GIC/include/) add_subdirectory(src/common/example) add_subdirectory(src/common/test) @@ -83,6 +84,8 @@ add_subdirectory(src/Bottleneck_distance/test) add_subdirectory(src/Bottleneck_distance/benchmark) add_subdirectory(src/Rips_complex/example) add_subdirectory(src/Rips_complex/test) +add_subdirectory(src/Nerve_GIC/example) +add_subdirectory(src/Nerve_GIC/test) # data points generator add_subdirectory(data/points/generator) diff --git a/data/points/COIL_database/asian_mug.off b/data/points/COIL_database/asian_mug.off index 93d2ab00..f6a9a972 100644 --- a/data/points/COIL_database/asian_mug.off +++ b/data/points/COIL_database/asian_mug.off @@ -1,3 +1,5 @@ +OFF +72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.0352941 0.0588235 0.101961 0.133333 0.152941 0.180392 0.211765 0.227451 0.219608 0.215686 0.196078 0.160784 0.145098 0.101961 0.0666667 0.0392157 0.0117647 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.0745098 0.117647 0.219608 0.341176 0.439216 0.505882 0.552941 0.592157 0.6 0.611765 0.639216 0.639216 0.635294 0.647059 0.658824 0.654902 0.662745 0.647059 0.662745 0.690196 0.756863 0.72549 0.717647 0.713725 0.682353 0.662745 0.662745 0.647059 0.639216 0.627451 0.623529 0.588235 0.552941 0.482353 0.372549 0.266667 0.172549 0.101961 0.0392157 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.113725 0.258824 0.364706 0.466667 0.541176 0.564706 0.580392 0.588235 0.6 0.611765 0.611765 0.603922 0.592157 0.6 0.580392 0.584314 0.584314 0.576471 0.560784 0.560784 0.572549 0.560784 0.564706 0.552941 0.568627 0.698039 0.831373 0.854902 0.862745 0.8 0.72549 0.647059 0.647059 0.647059 0.631373 0.635294 0.65098 0.654902 0.65098 0.662745 0.65098 0.635294 0.647059 0.631373 0.623529 0.576471 0.509804 0.403922 0.27451 0.133333 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.211765 0.396078 0.490196 0.52549 0.556863 0.568627 0.564706 0.564706 0.568627 0.568627 0.541176 0.52549 0.486275 0.47451 0.454902 0.439216 0.415686 0.392157 0.372549 0.352941 0.360784 0.360784 0.337255 0.341176 0.34902 0.329412 0.321569 0.341176 0.329412 0.368627 0.482353 0.462745 0.352941 0.356863 0.364706 0.372549 0.380392 0.384314 0.403922 0.435294 0.443137 0.454902 0.494118 0.529412 0.623529 0.74902 0.894118 0.964706 0.835294 0.682353 0.666667 0.662745 0.647059 0.627451 0.603922 0.545098 0.447059 0.243137 0.0588235 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.14902 0.376471 0.478431 0.517647 0.533333 0.541176 0.541176 0.521569 0.521569 0.494118 0.470588 0.443137 0.4 0.368627 0.337255 0.301961 0.294118 0.282353 0.286275 0.282353 0.278431 0.262745 0.262745 0.278431 0.317647 0.294118 0.254902 0.270588 0.270588 0.278431 0.290196 0.329412 0.478431 0.545098 0.341176 0.309804 0.313725 0.298039 0.282353 0.286275 0.290196 0.290196 0.290196 0.294118 0.298039 0.294118 0.309804 0.313725 0.313725 0.321569 0.356863 0.368627 0.403922 0.443137 0.470588 0.529412 0.556863 0.584314 0.603922 0.619608 0.627451 0.607843 0.592157 0.552941 0.419608 0.184314 0.0627451 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.235294 0.415686 0.482353 0.505882 0.517647 0.517647 0.505882 0.470588 0.443137 0.396078 0.360784 0.317647 0.298039 0.27451 0.270588 0.262745 0.254902 0.243137 0.227451 0.227451 0.247059 0.25098 0.25098 0.235294 0.243137 0.243137 0.266667 0.305882 0.286275 0.243137 0.333333 0.329412 0.25098 0.282353 0.290196 0.972549 0.992157 0.356863 0.317647 0.345098 0.294118 0.262745 0.282353 0.266667 0.270588 0.270588 0.254902 0.25098 0.270588 0.270588 0.286275 0.290196 0.286275 0.301961 0.290196 0.301961 0.313725 0.32549 0.333333 0.34902 0.372549 0.411765 0.454902 0.521569 0.54902 0.580392 0.603922 0.592157 0.584314 0.54902 0.435294 0.227451 0.0313725 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.137255 0.388235 0.447059 0.470588 0.498039 0.482353 0.45098 0.435294 0.388235 0.329412 0.290196 0.262745 0.25098 0.239216 0.231373 0.231373 0.227451 0.239216 0.227451 0.235294 0.227451 0.215686 0.215686 0.231373 0.235294 0.239216 0.239216 0.239216 0.231373 0.25098 0.278431 0.266667 0.235294 0.247059 0.286275 0.243137 0.254902 0.282353 0.423529 0.576471 0.282353 0.27451 0.278431 0.266667 0.247059 0.25098 0.254902 0.243137 0.25098 0.243137 0.247059 0.243137 0.235294 0.266667 0.270588 0.278431 0.278431 0.282353 0.282353 0.301961 0.290196 0.290196 0.290196 0.294118 0.301961 0.313725 0.329412 0.34902 0.396078 0.45098 0.513725 0.552941 0.572549 0.584314 0.552941 0.517647 0.396078 0.121569 0.0156863 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.196078 0.435294 0.447059 0.443137 0.45098 0.435294 0.415686 0.341176 0.309804 0.258824 0.227451 0.211765 0.215686 0.219608 0.203922 0.207843 0.207843 0.219608 0.211765 0.219608 0.219608 0.223529 0.219608 0.188235 0.207843 0.215686 0.227451 0.235294 0.227451 0.231373 0.211765 0.235294 0.278431 0.270588 0.223529 0.231373 0.235294 0.231373 0.243137 0.290196 0.286275 0.294118 0.27451 0.247059 0.25098 0.254902 0.247059 0.243137 0.258824 0.247059 0.231373 0.235294 0.243137 0.243137 0.254902 0.25098 0.243137 0.25098 0.258824 0.266667 0.270588 0.270588 0.262745 0.266667 0.258824 0.262745 0.27451 0.254902 0.266667 0.25098 0.270588 0.27451 0.317647 0.368627 0.439216 0.494118 0.541176 0.552941 0.545098 0.541176 0.443137 0.172549 0.0235294 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.160784 0.403922 0.431373 0.415686 0.411765 0.4 0.352941 0.305882 0.247059 0.215686 0.192157 0.192157 0.192157 0.180392 0.192157 0.188235 0.2 0.196078 0.192157 0.196078 0.211765 0.215686 0.211765 0.207843 0.203922 0.192157 0.192157 0.211765 0.227451 0.231373 0.223529 0.219608 0.207843 0.219608 0.247059 0.262745 0.223529 0.219608 0.227451 0.219608 0.235294 0.258824 0.282353 0.282353 0.258824 0.235294 0.247059 0.247059 0.223529 0.235294 0.243137 0.235294 0.227451 0.223529 0.231373 0.247059 0.235294 0.231373 0.219608 0.239216 0.258824 0.258824 0.25098 0.243137 0.25098 0.270588 0.258824 0.25098 0.247059 0.243137 0.235294 0.247059 0.235294 0.239216 0.25098 0.258824 0.270588 0.317647 0.372549 0.447059 0.501961 0.521569 0.533333 0.513725 0.427451 0.188235 0.0196078 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.329412 0.407843 0.388235 0.368627 0.345098 0.298039 0.262745 0.231373 0.196078 0.180392 0.168627 0.14902 0.168627 0.176471 0.180392 0.176471 0.176471 0.188235 0.184314 0.2 0.196078 0.2 0.211765 0.2 0.219608 0.219608 0.184314 0.180392 0.203922 0.227451 0.227451 0.227451 0.215686 0.207843 0.203922 0.243137 0.266667 0.219608 0.211765 0.219608 0.235294 0.231373 0.258824 0.278431 0.258824 0.258824 0.243137 0.243137 0.239216 0.235294 0.231373 0.223529 0.239216 0.243137 0.227451 0.247059 0.235294 0.231373 0.219608 0.219608 0.227451 0.262745 0.25098 0.262745 0.258824 0.219608 0.262745 0.247059 0.235294 0.25098 0.231373 0.231373 0.223529 0.215686 0.223529 0.227451 0.239216 0.243137 0.239216 0.247059 0.278431 0.329412 0.419608 0.466667 0.498039 0.513725 0.490196 0.384314 0.0784314 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0823529 0.388235 0.376471 0.352941 0.321569 0.278431 0.215686 0.196078 0.188235 0.164706 0.160784 0.160784 0.14902 0.152941 0.164706 0.168627 0.184314 0.196078 0.180392 0.172549 0.184314 0.184314 0.188235 0.184314 0.188235 0.188235 0.203922 0.192157 0.176471 0.188235 0.203922 0.215686 0.219608 0.211765 0.215686 0.207843 0.215686 0.239216 0.239216 0.223529 0.219608 0.215686 0.219608 0.219608 0.235294 0.247059 0.247059 0.247059 0.243137 0.235294 0.231373 0.243137 0.231373 0.239216 0.219608 0.223529 0.219608 0.227451 0.227451 0.219608 0.219608 0.219608 0.231373 0.25098 0.239216 0.25098 0.25098 0.231373 0.243137 0.227451 0.235294 0.231373 0.243137 0.227451 0.231373 0.25098 0.262745 0.270588 0.247059 0.247059 0.231373 0.243137 0.270588 0.247059 0.262745 0.305882 0.4 0.45098 0.478431 0.490196 0.435294 0.188235 0.0156863 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.388235 0.360784 0.317647 0.282353 0.254902 0.196078 0.164706 0.141176 0.145098 0.141176 0.133333 0.141176 0.141176 0.137255 0.152941 0.156863 0.14902 0.145098 0.156863 0.168627 0.176471 0.2 0.215686 0.196078 0.172549 0.172549 0.180392 0.172549 0.176471 0.188235 0.172549 0.192157 0.2 0.192157 0.188235 0.196078 0.203922 0.207843 0.2 0.219608 0.211765 0.203922 0.207843 0.211765 0.219608 0.219608 0.219608 0.223529 0.219608 0.215686 0.219608 0.207843 0.215686 0.219608 0.215686 0.219608 0.215686 0.211765 0.211765 0.211765 0.215686 0.219608 0.219608 0.215686 0.215686 0.219608 0.223529 0.223529 0.215686 0.215686 0.223529 0.219608 0.207843 0.215686 0.215686 0.219608 0.215686 0.215686 0.235294 0.215686 0.219608 0.223529 0.227451 0.219608 0.227451 0.235294 0.270588 0.337255 0.423529 0.443137 0.443137 0.427451 0.192157 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.360784 0.352941 0.282353 0.258824 0.219608 0.156863 0.14902 0.137255 0.121569 0.12549 0.129412 0.121569 0.137255 0.129412 0.141176 0.141176 0.156863 0.145098 0.145098 0.145098 0.160784 0.168627 0.164706 0.164706 0.160784 0.172549 0.172549 0.164706 0.176471 0.180392 0.184314 0.176471 0.188235 0.180392 0.192157 0.192157 0.196078 0.188235 0.192157 0.188235 0.196078 0.203922 0.188235 0.215686 0.203922 0.207843 0.211765 0.207843 0.219608 0.207843 0.207843 0.215686 0.215686 0.207843 0.219608 0.207843 0.219608 0.219608 0.219608 0.219608 0.219608 0.215686 0.219608 0.211765 0.215686 0.203922 0.215686 0.207843 0.203922 0.219608 0.211765 0.207843 0.207843 0.211765 0.211765 0.188235 0.196078 0.211765 0.196078 0.227451 0.203922 0.215686 0.215686 0.2 0.207843 0.211765 0.215686 0.219608 0.231373 0.309804 0.380392 0.415686 0.435294 0.396078 0.152941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.262745 0.364706 0.286275 0.25098 0.207843 0.152941 0.12549 0.121569 0.121569 0.113725 0.117647 0.121569 0.117647 0.12549 0.12549 0.12549 0.133333 0.137255 0.152941 0.141176 0.137255 0.152941 0.141176 0.164706 0.156863 0.160784 0.156863 0.168627 0.168627 0.172549 0.172549 0.172549 0.176471 0.172549 0.172549 0.188235 0.2 0.180392 0.188235 0.196078 0.2 0.196078 0.203922 0.188235 0.203922 0.203922 0.2 0.196078 0.203922 0.203922 0.203922 0.207843 0.211765 0.203922 0.207843 0.203922 0.211765 0.219608 0.203922 0.219608 0.211765 0.219608 0.203922 0.219608 0.207843 0.203922 0.207843 0.211765 0.219608 0.211765 0.207843 0.219608 0.211765 0.207843 0.2 0.211765 0.203922 0.219608 0.2 0.2 0.223529 0.215686 0.2 0.192157 0.196078 0.203922 0.196078 0.196078 0.2 0.184314 0.219608 0.270588 0.360784 0.384314 0.403922 0.337255 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.372549 0.329412 0.25098 0.196078 0.137255 0.113725 0.109804 0.109804 0.113725 0.109804 0.117647 0.113725 0.12549 0.121569 0.12549 0.129412 0.141176 0.145098 0.145098 0.145098 0.137255 0.145098 0.14902 0.156863 0.152941 0.156863 0.156863 0.160784 0.160784 0.152941 0.176471 0.164706 0.172549 0.168627 0.184314 0.176471 0.180392 0.192157 0.188235 0.192157 0.196078 0.2 0.2 0.2 0.203922 0.207843 0.207843 0.207843 0.211765 0.211765 0.207843 0.203922 0.207843 0.215686 0.203922 0.207843 0.203922 0.207843 0.203922 0.207843 0.211765 0.203922 0.211765 0.203922 0.207843 0.203922 0.2 0.2 0.203922 0.2 0.196078 0.203922 0.211765 0.207843 0.219608 0.196078 0.203922 0.192157 0.203922 0.207843 0.215686 0.203922 0.2 0.192157 0.188235 0.196078 0.196078 0.192157 0.196078 0.184314 0.192157 0.203922 0.27451 0.356863 0.372549 0.380392 0.219608 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0823529 0.396078 0.309804 0.215686 0.14902 0.113725 0.105882 0.0980392 0.109804 0.109804 0.109804 0.109804 0.113725 0.121569 0.113725 0.12549 0.12549 0.133333 0.133333 0.133333 0.137255 0.145098 0.14902 0.141176 0.145098 0.156863 0.160784 0.156863 0.164706 0.168627 0.164706 0.168627 0.172549 0.164706 0.176471 0.176471 0.180392 0.188235 0.192157 0.176471 0.2 0.188235 0.2 0.207843 0.192157 0.2 0.2 0.203922 0.211765 0.203922 0.203922 0.211765 0.203922 0.2 0.203922 0.203922 0.211765 0.219608 0.219608 0.203922 0.207843 0.211765 0.207843 0.207843 0.219608 0.207843 0.203922 0.207843 0.211765 0.211765 0.203922 0.211765 0.2 0.207843 0.203922 0.196078 0.211765 0.203922 0.188235 0.211765 0.215686 0.192157 0.188235 0.192157 0.184314 0.184314 0.188235 0.196078 0.176471 0.180392 0.172549 0.176471 0.184314 0.196078 0.305882 0.333333 0.364706 0.305882 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.109804 0.411765 0.317647 0.2 0.121569 0.101961 0.0941176 0.101961 0.0941176 0.0980392 0.101961 0.109804 0.105882 0.109804 0.117647 0.12549 0.121569 0.137255 0.137255 0.133333 0.137255 0.141176 0.141176 0.137255 0.141176 0.160784 0.160784 0.160784 0.164706 0.160784 0.172549 0.176471 0.180392 0.164706 0.172549 0.184314 0.172549 0.180392 0.188235 0.192157 0.196078 0.184314 0.176471 0.196078 0.207843 0.2 0.203922 0.215686 0.207843 0.207843 0.196078 0.211765 0.211765 0.196078 0.207843 0.2 0.215686 0.203922 0.184314 0.203922 0.203922 0.203922 0.207843 0.203922 0.196078 0.207843 0.196078 0.207843 0.196078 0.215686 0.188235 0.203922 0.207843 0.207843 0.196078 0.196078 0.2 0.203922 0.196078 0.196078 0.2 0.180392 0.196078 0.196078 0.188235 0.192157 0.188235 0.184314 0.180392 0.176471 0.168627 0.164706 0.156863 0.176471 0.227451 0.329412 0.360784 0.329412 0.0666667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.101961 0.4 0.368627 0.215686 0.113725 0.105882 0.0862745 0.0862745 0.0823529 0.101961 0.0980392 0.0980392 0.109804 0.105882 0.113725 0.121569 0.117647 0.117647 0.133333 0.121569 0.129412 0.133333 0.145098 0.141176 0.137255 0.156863 0.152941 0.137255 0.152941 0.160784 0.164706 0.14902 0.164706 0.180392 0.168627 0.172549 0.176471 0.184314 0.180392 0.180392 0.176471 0.176471 0.176471 0.184314 0.188235 0.196078 0.2 0.203922 0.207843 0.188235 0.211765 0.192157 0.196078 0.196078 0.192157 0.2 0.203922 0.2 0.2 0.2 0.207843 0.211765 0.203922 0.196078 0.203922 0.2 0.207843 0.203922 0.2 0.196078 0.196078 0.196078 0.192157 0.184314 0.196078 0.196078 0.192157 0.2 0.180392 0.203922 0.188235 0.180392 0.184314 0.172549 0.172549 0.168627 0.176471 0.176471 0.168627 0.164706 0.164706 0.160784 0.152941 0.164706 0.215686 0.317647 0.368627 0.313725 0.0784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0705882 0.352941 0.447059 0.317647 0.117647 0.101961 0.0941176 0.0862745 0.0784314 0.0862745 0.0941176 0.0980392 0.0941176 0.101961 0.105882 0.0980392 0.101961 0.117647 0.105882 0.105882 0.109804 0.117647 0.12549 0.129412 0.133333 0.133333 0.12549 0.137255 0.133333 0.14902 0.137255 0.156863 0.156863 0.14902 0.14902 0.164706 0.164706 0.172549 0.160784 0.172549 0.172549 0.168627 0.172549 0.172549 0.164706 0.180392 0.188235 0.184314 0.188235 0.184314 0.188235 0.196078 0.184314 0.184314 0.180392 0.188235 0.188235 0.188235 0.192157 0.184314 0.184314 0.188235 0.184314 0.192157 0.180392 0.180392 0.188235 0.180392 0.184314 0.184314 0.192157 0.188235 0.188235 0.192157 0.180392 0.160784 0.176471 0.180392 0.168627 0.176471 0.176471 0.160784 0.176471 0.160784 0.172549 0.164706 0.160784 0.172549 0.160784 0.164706 0.156863 0.141176 0.14902 0.152941 0.223529 0.321569 0.360784 0.258824 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.278431 0.454902 0.470588 0.290196 0.105882 0.109804 0.109804 0.0823529 0.0784314 0.0862745 0.0980392 0.0901961 0.0941176 0.0941176 0.0941176 0.101961 0.109804 0.0941176 0.113725 0.117647 0.117647 0.121569 0.113725 0.121569 0.129412 0.12549 0.133333 0.137255 0.137255 0.133333 0.145098 0.14902 0.156863 0.141176 0.160784 0.145098 0.160784 0.160784 0.160784 0.168627 0.164706 0.164706 0.168627 0.176471 0.172549 0.176471 0.168627 0.184314 0.180392 0.172549 0.192157 0.184314 0.164706 0.192157 0.172549 0.176471 0.172549 0.188235 0.168627 0.176471 0.188235 0.188235 0.184314 0.196078 0.184314 0.184314 0.176471 0.188235 0.184314 0.172549 0.180392 0.176471 0.176471 0.184314 0.168627 0.180392 0.184314 0.168627 0.172549 0.180392 0.176471 0.160784 0.164706 0.172549 0.156863 0.156863 0.160784 0.168627 0.160784 0.160784 0.14902 0.14902 0.168627 0.309804 0.392157 0.333333 0.211765 0.054902 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.00392157 0.00392157 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.243137 0.380392 0.505882 0.505882 0.305882 0.117647 0.0980392 0.0980392 0.0823529 0.0941176 0.0941176 0.0901961 0.0745098 0.0901961 0.101961 0.0941176 0.101961 0.0980392 0.109804 0.105882 0.109804 0.113725 0.109804 0.117647 0.137255 0.129412 0.133333 0.129412 0.141176 0.141176 0.14902 0.14902 0.137255 0.137255 0.156863 0.156863 0.14902 0.168627 0.168627 0.160784 0.168627 0.168627 0.172549 0.176471 0.172549 0.184314 0.172549 0.168627 0.172549 0.184314 0.180392 0.180392 0.184314 0.176471 0.188235 0.184314 0.188235 0.180392 0.188235 0.188235 0.176471 0.184314 0.180392 0.192157 0.172549 0.188235 0.192157 0.188235 0.176471 0.180392 0.176471 0.188235 0.176471 0.180392 0.172549 0.180392 0.180392 0.172549 0.164706 0.160784 0.164706 0.160784 0.164706 0.164706 0.14902 0.14902 0.168627 0.156863 0.152941 0.152941 0.137255 0.168627 0.329412 0.411765 0.360784 0.258824 0.172549 0.0509804 0 0 0 0 0 0 0.0627451 0.168627 0.278431 0.329412 0.356863 0.360784 0.372549 0.368627 0.356863 0.329412 0.298039 0.188235 0.0784314 0 0 0 0 0 0 0 0 0 0 0.00784314 0.192157 0.305882 0.411765 0.517647 0.552941 0.435294 0.180392 0.109804 0.109804 0.0941176 0.0823529 0.0941176 0.0901961 0.0941176 0.0941176 0.105882 0.101961 0.101961 0.109804 0.109804 0.105882 0.117647 0.109804 0.109804 0.129412 0.121569 0.133333 0.129412 0.133333 0.133333 0.145098 0.137255 0.133333 0.145098 0.14902 0.152941 0.152941 0.156863 0.156863 0.156863 0.176471 0.164706 0.172549 0.168627 0.168627 0.172549 0.172549 0.176471 0.172549 0.188235 0.184314 0.184314 0.176471 0.180392 0.180392 0.176471 0.180392 0.180392 0.180392 0.180392 0.172549 0.184314 0.192157 0.180392 0.180392 0.168627 0.176471 0.180392 0.184314 0.176471 0.176471 0.184314 0.180392 0.176471 0.180392 0.180392 0.168627 0.172549 0.180392 0.168627 0.172549 0.152941 0.152941 0.156863 0.152941 0.141176 0.152941 0.152941 0.152941 0.137255 0.211765 0.380392 0.435294 0.380392 0.301961 0.290196 0.235294 0.0352941 0 0 0 0.0352941 0.207843 0.329412 0.376471 0.423529 0.443137 0.470588 0.478431 0.498039 0.494118 0.486275 0.486275 0.470588 0.443137 0.423529 0.364706 0.294118 0.14902 0.00784314 0 0 0 0 0 0 0 0.00392157 0.156863 0.270588 0.337255 0.435294 0.560784 0.619608 0.576471 0.407843 0.152941 0.113725 0.109804 0.0941176 0.0901961 0.105882 0.0980392 0.0941176 0.105882 0.101961 0.109804 0.101961 0.109804 0.105882 0.113725 0.113725 0.12549 0.117647 0.12549 0.12549 0.141176 0.141176 0.133333 0.137255 0.14902 0.141176 0.160784 0.152941 0.160784 0.164706 0.164706 0.152941 0.176471 0.168627 0.164706 0.152941 0.164706 0.188235 0.188235 0.184314 0.180392 0.184314 0.180392 0.188235 0.192157 0.192157 0.192157 0.188235 0.180392 0.196078 0.184314 0.176471 0.188235 0.196078 0.188235 0.188235 0.176471 0.184314 0.188235 0.180392 0.180392 0.176471 0.180392 0.176471 0.192157 0.180392 0.172549 0.180392 0.176471 0.164706 0.160784 0.160784 0.164706 0.160784 0.164706 0.168627 0.156863 0.156863 0.156863 0.156863 0.192157 0.356863 0.447059 0.447059 0.392157 0.329412 0.32549 0.294118 0.254902 0.0509804 0 0.0627451 0.219608 0.305882 0.392157 0.466667 0.494118 0.521569 0.537255 0.545098 0.556863 0.576471 0.568627 0.572549 0.572549 0.545098 0.541176 0.505882 0.482353 0.435294 0.368627 0.282353 0.0980392 0.0117647 0.00392157 0 0 0 0 0 0.12549 0.235294 0.305882 0.380392 0.439216 0.529412 0.596078 0.643137 0.607843 0.431373 0.207843 0.12549 0.109804 0.109804 0.101961 0.101961 0.105882 0.101961 0.101961 0.105882 0.105882 0.109804 0.109804 0.109804 0.121569 0.121569 0.129412 0.12549 0.133333 0.137255 0.133333 0.145098 0.145098 0.133333 0.160784 0.14902 0.156863 0.160784 0.160784 0.152941 0.172549 0.176471 0.172549 0.176471 0.180392 0.176471 0.184314 0.192157 0.180392 0.176471 0.168627 0.176471 0.184314 0.180392 0.184314 0.188235 0.180392 0.188235 0.176471 0.176471 0.188235 0.184314 0.176471 0.184314 0.188235 0.172549 0.188235 0.188235 0.184314 0.180392 0.188235 0.180392 0.180392 0.188235 0.176471 0.172549 0.168627 0.164706 0.168627 0.164706 0.160784 0.160784 0.152941 0.160784 0.156863 0.156863 0.243137 0.4 0.470588 0.478431 0.443137 0.380392 0.337255 0.329412 0.313725 0.286275 0.266667 0.207843 0.290196 0.329412 0.364706 0.423529 0.498039 0.54902 0.580392 0.588235 0.603922 0.627451 0.627451 0.627451 0.627451 0.627451 0.619608 0.607843 0.588235 0.576471 0.552941 0.509804 0.466667 0.415686 0.32549 0.168627 0.0196078 0 0 0 0 0 0.109804 0.207843 0.27451 0.329412 0.4 0.447059 0.498039 0.556863 0.619608 0.662745 0.662745 0.560784 0.368627 0.176471 0.121569 0.113725 0.109804 0.101961 0.105882 0.101961 0.109804 0.109804 0.117647 0.109804 0.121569 0.113725 0.121569 0.12549 0.133333 0.137255 0.129412 0.141176 0.14902 0.14902 0.152941 0.168627 0.156863 0.156863 0.168627 0.168627 0.160784 0.180392 0.168627 0.168627 0.176471 0.184314 0.172549 0.176471 0.180392 0.184314 0.192157 0.188235 0.184314 0.196078 0.192157 0.188235 0.184314 0.184314 0.184314 0.192157 0.184314 0.180392 0.188235 0.180392 0.168627 0.192157 0.184314 0.188235 0.176471 0.192157 0.184314 0.196078 0.176471 0.180392 0.180392 0.168627 0.164706 0.176471 0.168627 0.168627 0.168627 0.160784 0.164706 0.231373 0.380392 0.486275 0.513725 0.498039 0.447059 0.403922 0.356863 0.317647 0.305882 0.298039 0.305882 0.286275 0.27451 0.301961 0.392157 0.403922 0.427451 0.47451 0.541176 0.6 0.631373 0.65098 0.647059 0.662745 0.686275 0.886275 0.882353 0.858824 0.670588 0.666667 0.647059 0.619608 0.596078 0.572549 0.545098 0.482353 0.415686 0.337255 0.192157 0.0117647 0 0 0 0 0.0784314 0.192157 0.25098 0.305882 0.352941 0.403922 0.45098 0.478431 0.517647 0.572549 0.627451 0.670588 0.701961 0.694118 0.615686 0.431373 0.219608 0.156863 0.137255 0.121569 0.117647 0.121569 0.117647 0.109804 0.117647 0.12549 0.121569 0.129412 0.133333 0.145098 0.137255 0.145098 0.14902 0.14902 0.152941 0.152941 0.164706 0.156863 0.164706 0.156863 0.160784 0.168627 0.180392 0.172549 0.176471 0.184314 0.180392 0.192157 0.184314 0.176471 0.184314 0.188235 0.184314 0.192157 0.188235 0.196078 0.188235 0.192157 0.188235 0.184314 0.188235 0.180392 0.192157 0.196078 0.184314 0.188235 0.180392 0.180392 0.188235 0.188235 0.176471 0.176471 0.184314 0.192157 0.188235 0.188235 0.184314 0.184314 0.176471 0.192157 0.298039 0.45098 0.529412 0.54902 0.533333 0.501961 0.470588 0.415686 0.364706 0.321569 0.301961 0.290196 0.239216 0.219608 0.286275 0.290196 0.278431 0.380392 0.447059 0.45098 0.466667 0.505882 0.556863 0.635294 0.65098 0.658824 0.670588 0.658824 0.647059 0.670588 0.72549 0.701961 0.631373 0.65098 0.631373 0.627451 0.619608 0.596078 0.572549 0.541176 0.501961 0.427451 0.329412 0.164706 0.0117647 0 0 0 0.0588235 0.184314 0.231373 0.294118 0.337255 0.376471 0.411765 0.45098 0.47451 0.498039 0.541176 0.568627 0.607843 0.65098 0.682353 0.72549 0.733333 0.698039 0.592157 0.431373 0.286275 0.211765 0.14902 0.133333 0.12549 0.117647 0.133333 0.129412 0.137255 0.137255 0.141176 0.145098 0.152941 0.152941 0.152941 0.156863 0.164706 0.160784 0.164706 0.168627 0.168627 0.172549 0.164706 0.168627 0.176471 0.172549 0.184314 0.176471 0.176471 0.188235 0.180392 0.188235 0.180392 0.192157 0.184314 0.2 0.188235 0.192157 0.188235 0.196078 0.192157 0.192157 0.192157 0.180392 0.184314 0.184314 0.184314 0.196078 0.184314 0.176471 0.180392 0.184314 0.180392 0.184314 0.196078 0.25098 0.333333 0.45098 0.545098 0.572549 0.576471 0.545098 0.521569 0.494118 0.447059 0.411765 0.376471 0.341176 0.321569 0.294118 0.27451 0.247059 0.211765 0.184314 0.313725 0.309804 0.294118 0.431373 0.478431 0.482353 0.501961 0.537255 0.670588 0.619608 0.619608 0.596078 0.568627 0.533333 0.513725 0.498039 0.470588 0.470588 0.494118 0.509804 0.568627 0.596078 0.588235 0.588235 0.584314 0.572549 0.533333 0.494118 0.403922 0.290196 0.0941176 0.0117647 0 0 0.0156863 0.168627 0.227451 0.278431 0.329412 0.356863 0.396078 0.415686 0.443137 0.47451 0.494118 0.517647 0.537255 0.568627 0.596078 0.623529 0.670588 0.690196 0.705882 0.74902 0.74902 0.741176 0.701961 0.607843 0.501961 0.388235 0.278431 0.184314 0.145098 0.145098 0.141176 0.141176 0.156863 0.141176 0.160784 0.160784 0.164706 0.160784 0.172549 0.156863 0.168627 0.172549 0.180392 0.176471 0.176471 0.176471 0.180392 0.188235 0.184314 0.192157 0.176471 0.188235 0.184314 0.203922 0.184314 0.192157 0.188235 0.192157 0.184314 0.188235 0.184314 0.188235 0.184314 0.188235 0.196078 0.188235 0.184314 0.188235 0.2 0.25098 0.333333 0.411765 0.498039 0.572549 0.603922 0.607843 0.619608 0.580392 0.560784 0.52549 0.486275 0.470588 0.439216 0.415686 0.380392 0.364706 0.329412 0.305882 0.286275 0.266667 0.254902 0.227451 0.184314 0.152941 0.258824 0.309804 0.313725 0.572549 0.52549 0.494118 0.517647 0.545098 0.545098 0.533333 0.498039 0.415686 0.337255 0.231373 0.152941 0.109804 0.0784314 0.0941176 0.121569 0.152941 0.266667 0.392157 0.482353 0.552941 0.564706 0.564706 0.552941 0.517647 0.47451 0.372549 0.235294 0.027451 0 0 0.00392157 0.137255 0.219608 0.270588 0.313725 0.34902 0.372549 0.4 0.419608 0.45098 0.470588 0.498039 0.509804 0.529412 0.533333 0.54902 0.572549 0.592157 0.619608 0.65098 0.666667 0.713725 0.705882 0.737255 0.741176 0.784314 0.866667 0.886275 0.760784 0.705882 0.639216 0.564706 0.454902 0.364706 0.282353 0.231373 0.215686 0.188235 0.180392 0.180392 0.180392 0.184314 0.192157 0.184314 0.184314 0.188235 0.176471 0.192157 0.184314 0.207843 0.192157 0.196078 0.192157 0.2 0.184314 0.196078 0.196078 0.215686 0.192157 0.211765 0.239216 0.290196 0.34902 0.435294 0.513725 0.560784 0.611765 0.654902 0.662745 0.666667 0.65098 0.635294 0.619608 0.607843 0.584314 0.552941 0.521569 0.490196 0.458824 0.443137 0.411765 0.392157 0.376471 0.364706 0.345098 0.317647 0.301961 0.282353 0.262745 0.239216 0.25098 0.215686 0.172549 0.156863 0.258824 0.262745 0.360784 0.552941 0.513725 0.509804 0.54902 0.490196 0.423529 0.329412 0.196078 0.054902 0 0 0 0 0 0 0 0 0 0.0627451 0.247059 0.392157 0.486275 0.54902 0.545098 0.52549 0.482353 0.427451 0.305882 0.105882 0.00784314 0 0 0.101961 0.203922 0.254902 0.298039 0.329412 0.356863 0.384314 0.403922 0.423529 0.443137 0.454902 0.470588 0.494118 0.498039 0.521569 0.537255 0.552941 0.564706 0.576471 0.592157 0.603922 0.619608 0.643137 0.662745 0.678431 0.705882 0.72549 0.713725 0.72549 0.745098 0.796078 0.823529 0.815686 0.8 0.776471 0.792157 0.776471 0.760784 0.756863 0.74902 0.752941 0.752941 0.745098 0.737255 0.72549 0.721569 0.701961 0.67451 0.666667 0.662745 0.662745 0.682353 0.694118 0.686275 0.686275 0.717647 0.717647 0.72549 0.709804 0.72549 0.709804 0.698039 0.686275 0.678431 0.647059 0.639216 0.627451 0.592157 0.576471 0.54902 0.541176 0.517647 0.494118 0.482353 0.470588 0.447059 0.431373 0.411765 0.392157 0.380392 0.360784 0.337255 0.329412 0.317647 0.298039 0.27451 0.254902 0.239216 0.243137 0.239216 0.211765 0.156863 0.145098 0.243137 0.247059 0.372549 0.509804 0.498039 0.490196 0.447059 0.34902 0.192157 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0.133333 0.356863 0.482353 0.521569 0.521569 0.501961 0.45098 0.376471 0.2 0.0196078 0 0 0.0666667 0.184314 0.239216 0.278431 0.329412 0.356863 0.384314 0.4 0.419608 0.431373 0.443137 0.466667 0.47451 0.478431 0.501961 0.513725 0.52549 0.533333 0.552941 0.568627 0.580392 0.580392 0.580392 0.596078 0.596078 0.615686 0.619608 0.631373 0.643137 0.639216 0.654902 0.662745 0.670588 0.670588 0.666667 0.690196 0.709804 0.717647 0.72549 0.713725 0.709804 0.733333 0.717647 0.752941 0.780392 0.807843 0.976471 1 0.756863 0.756863 0.752941 0.721569 0.729412 0.709804 0.678431 0.686275 0.67451 0.658824 0.631373 0.623529 0.607843 0.584314 0.572549 0.560784 0.552941 0.541176 0.52549 0.517647 0.501961 0.486275 0.478431 0.470588 0.45098 0.435294 0.427451 0.407843 0.392157 0.384314 0.368627 0.345098 0.333333 0.329412 0.317647 0.286275 0.278431 0.254902 0.243137 0.223529 0.247059 0.227451 0.203922 0.156863 0.137255 0.227451 0.243137 0.384314 0.513725 0.466667 0.423529 0.294118 0.0941176 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12549 0.356863 0.47451 0.501961 0.505882 0.45098 0.388235 0.270588 0.0666667 0 0 0.027451 0.156863 0.219608 0.266667 0.313725 0.341176 0.376471 0.4 0.411765 0.423529 0.439216 0.454902 0.466667 0.458824 0.486275 0.494118 0.501961 0.513725 0.529412 0.537255 0.545098 0.552941 0.560784 0.560784 0.564706 0.588235 0.592157 0.584314 0.592157 0.603922 0.607843 0.615686 0.623529 0.635294 0.619608 0.623529 0.615686 0.623529 0.631373 0.615686 0.619608 0.619608 0.603922 0.615686 0.623529 0.607843 0.611765 0.615686 0.615686 0.607843 0.592157 0.588235 0.576471 0.615686 0.607843 0.580392 0.568627 0.560784 0.545098 0.545098 0.54902 0.529412 0.529412 0.521569 0.513725 0.498039 0.482353 0.458824 0.458824 0.443137 0.443137 0.45098 0.423529 0.431373 0.4 0.384314 0.376471 0.360784 0.341176 0.337255 0.321569 0.301961 0.286275 0.27451 0.262745 0.247059 0.235294 0.219608 0.247059 0.223529 0.196078 0.14902 0.133333 0.227451 0.254902 0.380392 0.423529 0.4 0.266667 0.0588235 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.188235 0.407843 0.498039 0.501961 0.466667 0.415686 0.321569 0.113725 0 0 0 0.137255 0.207843 0.247059 0.301961 0.329412 0.368627 0.388235 0.411765 0.423529 0.439216 0.45098 0.466667 0.454902 0.478431 0.486275 0.494118 0.494118 0.505882 0.509804 0.521569 0.517647 0.529412 0.54902 0.552941 0.552941 0.556863 0.564706 0.572549 0.572549 0.576471 0.584314 0.576471 0.592157 0.576471 0.584314 0.596078 0.584314 0.592157 0.584314 0.572549 0.584314 0.572549 0.580392 0.568627 0.588235 0.584314 0.584314 0.580392 0.576471 0.576471 0.560784 0.552941 0.54902 0.54902 0.54902 0.537255 0.52549 0.529412 0.513725 0.513725 0.498039 0.498039 0.470588 0.466667 0.466667 0.443137 0.431373 0.431373 0.419608 0.415686 0.419608 0.396078 0.380392 0.368627 0.356863 0.345098 0.333333 0.329412 0.317647 0.298039 0.298039 0.290196 0.266667 0.262745 0.239216 0.227451 0.227451 0.258824 0.227451 0.192157 0.145098 0.137255 0.215686 0.258824 0.360784 0.352941 0.25098 0.054902 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.309804 0.462745 0.486275 0.462745 0.427451 0.341176 0.164706 0 0 0 0.105882 0.188235 0.235294 0.290196 0.313725 0.345098 0.376471 0.396078 0.415686 0.431373 0.443137 0.462745 0.462745 0.478431 0.486275 0.490196 0.490196 0.494118 0.498039 0.498039 0.466667 0.490196 0.52549 0.52549 0.52549 0.533333 0.537255 0.552941 0.54902 0.560784 0.556863 0.552941 0.564706 0.556863 0.572549 0.564706 0.568627 0.572549 0.568627 0.564706 0.560784 0.568627 0.564706 0.584314 0.584314 0.615686 0.611765 0.572549 0.552941 0.552941 0.545098 0.537255 0.52549 0.52549 0.513725 0.509804 0.505882 0.498039 0.482353 0.47451 0.466667 0.478431 0.466667 0.458824 0.443137 0.435294 0.431373 0.415686 0.403922 0.4 0.384314 0.376471 0.364706 0.356863 0.345098 0.337255 0.32549 0.317647 0.298039 0.298039 0.282353 0.266667 0.262745 0.254902 0.235294 0.227451 0.219608 0.254902 0.215686 0.176471 0.133333 0.121569 0.196078 0.25098 0.317647 0.258824 0.0784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.207843 0.431373 0.490196 0.462745 0.407843 0.337255 0.180392 0 0 0 0.0784314 0.168627 0.235294 0.27451 0.309804 0.341176 0.368627 0.392157 0.407843 0.423529 0.439216 0.447059 0.458824 0.470588 0.478431 0.490196 0.494118 0.486275 0.498039 0.498039 0.494118 0.505882 0.529412 0.517647 0.533333 0.517647 0.529412 0.533333 0.541176 0.533333 0.529412 0.545098 0.54902 0.541176 0.54902 0.537255 0.552941 0.54902 0.537255 0.552941 0.537255 0.552941 0.556863 0.552941 0.568627 0.560784 0.560784 0.541176 0.537255 0.533333 0.52549 0.521569 0.505882 0.498039 0.490196 0.482353 0.478431 0.486275 0.466667 0.466667 0.454902 0.443137 0.431373 0.435294 0.435294 0.423529 0.403922 0.4 0.4 0.376471 0.372549 0.364706 0.345098 0.352941 0.329412 0.329412 0.32549 0.309804 0.294118 0.290196 0.286275 0.27451 0.254902 0.243137 0.223529 0.211765 0.227451 0.247059 0.215686 0.156863 0.12549 0.129412 0.176471 0.243137 0.231373 0.0784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0.407843 0.486275 0.447059 0.396078 0.317647 0.160784 0 0 0 0.027451 0.152941 0.211765 0.25098 0.298039 0.329412 0.356863 0.376471 0.403922 0.419608 0.431373 0.439216 0.45098 0.470588 0.466667 0.478431 0.494118 0.490196 0.498039 0.505882 0.505882 0.513725 0.509804 0.509804 0.513725 0.52549 0.521569 0.529412 0.533333 0.521569 0.533333 0.533333 0.529412 0.529412 0.541176 0.533333 0.529412 0.537255 0.533333 0.529412 0.533333 0.533333 0.529412 0.52549 0.52549 0.52549 0.509804 0.501961 0.513725 0.498039 0.501961 0.498039 0.490196 0.478431 0.482353 0.478431 0.458824 0.458824 0.454902 0.447059 0.443137 0.435294 0.427451 0.435294 0.415686 0.407843 0.4 0.392157 0.384314 0.380392 0.364706 0.356863 0.345098 0.341176 0.337255 0.329412 0.321569 0.301961 0.309804 0.282353 0.282353 0.278431 0.247059 0.235294 0.231373 0.219608 0.235294 0.231373 0.2 0.145098 0.113725 0.109804 0.14902 0.223529 0.113725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.172549 0.380392 0.47451 0.447059 0.388235 0.305882 0.156863 0 0 0 0 0.113725 0.192157 0.239216 0.27451 0.317647 0.337255 0.372549 0.388235 0.411765 0.419608 0.435294 0.45098 0.447059 0.47451 0.47451 0.482353 0.482353 0.490196 0.501961 0.498039 0.505882 0.513725 0.513725 0.517647 0.529412 0.521569 0.52549 0.529412 0.52549 0.533333 0.529412 0.529412 0.529412 0.52549 0.529412 0.529412 0.521569 0.521569 0.521569 0.529412 0.517647 0.517647 0.509804 0.513725 0.505882 0.509804 0.498039 0.501961 0.490196 0.490196 0.486275 0.486275 0.486275 0.47451 0.466667 0.462745 0.45098 0.447059 0.443137 0.443137 0.439216 0.427451 0.415686 0.415686 0.403922 0.407843 0.392157 0.372549 0.364706 0.360784 0.364706 0.333333 0.341176 0.333333 0.329412 0.321569 0.301961 0.294118 0.286275 0.27451 0.258824 0.243137 0.231373 0.219608 0.211765 0.239216 0.223529 0.192157 0.137255 0.109804 0.0862745 0.121569 0.109804 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.192157 0.372549 0.486275 0.45098 0.376471 0.298039 0.156863 0 0 0 0 0.0745098 0.168627 0.235294 0.270588 0.305882 0.329412 0.356863 0.368627 0.392157 0.419608 0.423529 0.439216 0.443137 0.45098 0.466667 0.470588 0.470588 0.490196 0.494118 0.486275 0.509804 0.505882 0.509804 0.521569 0.517647 0.52549 0.533333 0.529412 0.541176 0.537255 0.529412 0.529412 0.52549 0.529412 0.537255 0.529412 0.529412 0.533333 0.521569 0.517647 0.513725 0.509804 0.517647 0.509804 0.509804 0.513725 0.505882 0.498039 0.498039 0.501961 0.478431 0.470588 0.470588 0.470588 0.466667 0.458824 0.454902 0.443137 0.443137 0.447059 0.415686 0.427451 0.415686 0.411765 0.396078 0.396078 0.388235 0.384314 0.372549 0.364706 0.34902 0.352941 0.333333 0.329412 0.317647 0.305882 0.298039 0.290196 0.27451 0.266667 0.258824 0.231373 0.223529 0.211765 0.207843 0.266667 0.211765 0.180392 0.12549 0.0941176 0.0784314 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.247059 0.403922 0.494118 0.443137 0.352941 0.27451 0.121569 0 0 0 0 0.0352941 0.14902 0.207843 0.25098 0.286275 0.329412 0.337255 0.364706 0.388235 0.396078 0.427451 0.431373 0.423529 0.443137 0.466667 0.478431 0.466667 0.486275 0.494118 0.486275 0.505882 0.505882 0.509804 0.517647 0.521569 0.52549 0.52549 0.529412 0.521569 0.517647 0.517647 0.521569 0.521569 0.513725 0.533333 0.517647 0.529412 0.517647 0.501961 0.517647 0.513725 0.513725 0.505882 0.501961 0.501961 0.509804 0.501961 0.490196 0.482353 0.494118 0.486275 0.47451 0.47451 0.462745 0.462745 0.458824 0.443137 0.443137 0.439216 0.431373 0.431373 0.419608 0.419608 0.396078 0.396078 0.388235 0.376471 0.380392 0.364706 0.360784 0.34902 0.34902 0.329412 0.329412 0.313725 0.309804 0.298039 0.278431 0.27451 0.25098 0.25098 0.227451 0.215686 0.203922 0.176471 0.239216 0.203922 0.168627 0.113725 0.0862745 0.0431373 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.133333 0.301961 0.431373 0.509804 0.443137 0.345098 0.25098 0.0862745 0 0 0 0 0 0.113725 0.188235 0.231373 0.27451 0.305882 0.329412 0.352941 0.380392 0.388235 0.415686 0.415686 0.431373 0.439216 0.45098 0.458824 0.466667 0.478431 0.486275 0.47451 0.490196 0.486275 0.498039 0.498039 0.505882 0.509804 0.521569 0.501961 0.52549 0.517647 0.509804 0.513725 0.521569 0.501961 0.509804 0.513725 0.521569 0.501961 0.513725 0.52549 0.509804 0.501961 0.505882 0.498039 0.509804 0.490196 0.498039 0.494118 0.486275 0.478431 0.478431 0.470588 0.462745 0.458824 0.45098 0.45098 0.443137 0.447059 0.435294 0.431373 0.423529 0.411765 0.403922 0.4 0.388235 0.384314 0.368627 0.360784 0.356863 0.34902 0.341176 0.329412 0.329412 0.317647 0.305882 0.294118 0.286275 0.27451 0.262745 0.25098 0.235294 0.219608 0.211765 0.188235 0.196078 0.235294 0.2 0.156863 0.109804 0.0666667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.247059 0.372549 0.482353 0.505882 0.415686 0.305882 0.2 0.0392157 0 0 0 0 0 0.0745098 0.164706 0.215686 0.25098 0.294118 0.317647 0.341176 0.360784 0.392157 0.411765 0.392157 0.423529 0.439216 0.443137 0.458824 0.454902 0.47451 0.470588 0.482353 0.494118 0.486275 0.498039 0.501961 0.494118 0.521569 0.501961 0.505882 0.509804 0.509804 0.513725 0.501961 0.513725 0.513725 0.517647 0.505882 0.52549 0.501961 0.509804 0.513725 0.494118 0.501961 0.486275 0.494118 0.509804 0.486275 0.478431 0.478431 0.470588 0.482353 0.470588 0.466667 0.466667 0.45098 0.454902 0.443137 0.443137 0.443137 0.431373 0.439216 0.411765 0.411765 0.396078 0.4 0.392157 0.376471 0.368627 0.356863 0.352941 0.34902 0.32549 0.329412 0.321569 0.313725 0.298039 0.286275 0.27451 0.266667 0.258824 0.235294 0.231373 0.227451 0.211765 0.180392 0.192157 0.223529 0.188235 0.137255 0.0941176 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.211765 0.337255 0.443137 0.521569 0.498039 0.376471 0.266667 0.137255 0 0 0 0 0 0 0.0196078 0.137255 0.2 0.239216 0.278431 0.313725 0.329412 0.34902 0.364706 0.388235 0.392157 0.415686 0.431373 0.427451 0.443137 0.447059 0.454902 0.462745 0.470588 0.466667 0.478431 0.482353 0.490196 0.490196 0.498039 0.490196 0.501961 0.505882 0.501961 0.505882 0.513725 0.501961 0.513725 0.505882 0.509804 0.513725 0.498039 0.498039 0.501961 0.509804 0.501961 0.482353 0.494118 0.494118 0.478431 0.47451 0.478431 0.470588 0.466667 0.458824 0.466667 0.45098 0.443137 0.443137 0.439216 0.431373 0.419608 0.427451 0.415686 0.403922 0.396078 0.392157 0.392157 0.384314 0.368627 0.360784 0.345098 0.345098 0.345098 0.329412 0.321569 0.317647 0.301961 0.294118 0.27451 0.270588 0.258824 0.25098 0.239216 0.227451 0.211765 0.192157 0.172549 0.203922 0.215686 0.176471 0.121569 0.0784314 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.184314 0.32549 0.419608 0.513725 0.560784 0.454902 0.337255 0.223529 0.0666667 0 0 0 0 0 0 0 0.109804 0.172549 0.219608 0.262745 0.298039 0.32549 0.341176 0.360784 0.380392 0.384314 0.4 0.415686 0.427451 0.435294 0.443137 0.447059 0.454902 0.466667 0.466667 0.466667 0.482353 0.486275 0.490196 0.490196 0.498039 0.490196 0.501961 0.501961 0.509804 0.490196 0.490196 0.501961 0.509804 0.498039 0.498039 0.498039 0.494118 0.494118 0.486275 0.494118 0.490196 0.482353 0.478431 0.470588 0.482353 0.47451 0.462745 0.462745 0.443137 0.454902 0.45098 0.443137 0.439216 0.439216 0.431373 0.419608 0.419608 0.415686 0.407843 0.392157 0.388235 0.380392 0.368627 0.360784 0.356863 0.34902 0.341176 0.337255 0.317647 0.309804 0.305882 0.294118 0.290196 0.27451 0.266667 0.258824 0.235294 0.231373 0.215686 0.211765 0.188235 0.172549 0.211765 0.203922 0.168627 0.105882 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.188235 0.305882 0.411765 0.494118 0.564706 0.529412 0.396078 0.266667 0.160784 0.0156863 0 0 0 0 0 0 0 0.0627451 0.14902 0.196078 0.239216 0.27451 0.309804 0.333333 0.352941 0.368627 0.388235 0.4 0.415686 0.415686 0.435294 0.443137 0.443137 0.458824 0.458824 0.458824 0.466667 0.447059 0.47451 0.47451 0.482353 0.490196 0.482353 0.494118 0.494118 0.490196 0.494118 0.490196 0.482353 0.498039 0.490196 0.505882 0.494118 0.490196 0.490196 0.47451 0.486275 0.482353 0.47451 0.478431 0.486275 0.47451 0.458824 0.462745 0.458824 0.443137 0.443137 0.447059 0.443137 0.431373 0.443137 0.419608 0.415686 0.407843 0.392157 0.392157 0.392157 0.384314 0.384314 0.360784 0.360784 0.352941 0.345098 0.329412 0.32549 0.309804 0.305882 0.298039 0.290196 0.278431 0.266667 0.254902 0.25098 0.231373 0.219608 0.211765 0.192157 0.176471 0.160784 0.203922 0.192157 0.160784 0.101961 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.2 0.301961 0.392157 0.490196 0.560784 0.580392 0.470588 0.317647 0.211765 0.0745098 0.00392157 0 0 0 0 0 0 0 0.0156863 0.113725 0.184314 0.219608 0.266667 0.294118 0.317647 0.341176 0.356863 0.376471 0.376471 0.403922 0.411765 0.411765 0.427451 0.439216 0.443137 0.443137 0.454902 0.45098 0.454902 0.454902 0.466667 0.470588 0.47451 0.470588 0.482353 0.490196 0.47451 0.490196 0.47451 0.486275 0.482353 0.494118 0.47451 0.490196 0.486275 0.47451 0.478431 0.486275 0.47451 0.478431 0.470588 0.458824 0.458824 0.466667 0.45098 0.443137 0.439216 0.443137 0.443137 0.427451 0.423529 0.415686 0.407843 0.411765 0.380392 0.403922 0.4 0.384314 0.388235 0.364706 0.356863 0.341176 0.337255 0.337255 0.32549 0.321569 0.305882 0.298039 0.290196 0.278431 0.266667 0.25098 0.254902 0.235294 0.219608 0.215686 0.203922 0.180392 0.164706 0.152941 0.211765 0.176471 0.14902 0.0705882 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.129412 0.223529 0.305882 0.403922 0.486275 0.572549 0.596078 0.517647 0.368627 0.239216 0.117647 0.00784314 0 0 0 0 0 0 0 0 0 0.0862745 0.168627 0.207843 0.243137 0.286275 0.305882 0.32549 0.341176 0.356863 0.372549 0.388235 0.4 0.411765 0.415686 0.419608 0.443137 0.435294 0.454902 0.443137 0.454902 0.447059 0.458824 0.466667 0.466667 0.470588 0.482353 0.470588 0.470588 0.466667 0.470588 0.482353 0.490196 0.478431 0.478431 0.466667 0.478431 0.47451 0.466667 0.47451 0.458824 0.458824 0.466667 0.458824 0.458824 0.454902 0.447059 0.443137 0.431373 0.435294 0.427451 0.427451 0.423529 0.407843 0.411765 0.4 0.396078 0.388235 0.380392 0.376471 0.356863 0.356863 0.345098 0.337255 0.333333 0.329412 0.317647 0.305882 0.301961 0.294118 0.294118 0.27451 0.258824 0.239216 0.239216 0.235294 0.211765 0.2 0.2 0.164706 0.156863 0.164706 0.215686 0.184314 0.137255 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.0862745 0.196078 0.254902 0.341176 0.431373 0.513725 0.584314 0.611765 0.533333 0.380392 0.25098 0.145098 0.0196078 0 0 0 0 0 0 0 0 0 0 0.027451 0.12549 0.192157 0.219608 0.262745 0.298039 0.305882 0.329412 0.34902 0.368627 0.384314 0.392157 0.407843 0.419608 0.419608 0.431373 0.439216 0.435294 0.447059 0.447059 0.454902 0.462745 0.458824 0.458824 0.462745 0.470588 0.462745 0.466667 0.47451 0.466667 0.470588 0.47451 0.478431 0.466667 0.478431 0.462745 0.47451 0.466667 0.462745 0.462745 0.462745 0.458824 0.45098 0.443137 0.443137 0.447059 0.431373 0.443137 0.427451 0.427451 0.415686 0.411765 0.403922 0.403922 0.388235 0.388235 0.388235 0.368627 0.356863 0.356863 0.352941 0.337255 0.329412 0.329412 0.321569 0.305882 0.298039 0.298039 0.286275 0.270588 0.262745 0.258824 0.239216 0.227451 0.219608 0.203922 0.2 0.172549 0.164706 0.145098 0.156863 0.2 0.180392 0.12549 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.101961 0.180392 0.227451 0.290196 0.380392 0.454902 0.537255 0.596078 0.619608 0.545098 0.396078 0.25098 0.152941 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0.0980392 0.156863 0.2 0.243137 0.266667 0.286275 0.317647 0.333333 0.34902 0.356863 0.384314 0.388235 0.4 0.415686 0.427451 0.427451 0.419608 0.45098 0.447059 0.443137 0.45098 0.447059 0.45098 0.447059 0.458824 0.458824 0.466667 0.466667 0.458824 0.458824 0.470588 0.458824 0.458824 0.454902 0.454902 0.454902 0.447059 0.462745 0.462745 0.443137 0.447059 0.443137 0.439216 0.443137 0.419608 0.411765 0.419608 0.427451 0.419608 0.415686 0.403922 0.388235 0.396078 0.388235 0.388235 0.368627 0.364706 0.368627 0.34902 0.345098 0.333333 0.32549 0.313725 0.317647 0.294118 0.290196 0.286275 0.278431 0.254902 0.25098 0.243137 0.235294 0.219608 0.215686 0.188235 0.180392 0.168627 0.14902 0.133333 0.180392 0.196078 0.180392 0.0784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.141176 0.203922 0.227451 0.290196 0.356863 0.427451 0.501961 0.564706 0.635294 0.619608 0.52549 0.380392 0.247059 0.133333 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.133333 0.180392 0.223529 0.25098 0.278431 0.301961 0.329412 0.345098 0.360784 0.364706 0.384314 0.396078 0.411765 0.411765 0.419608 0.423529 0.439216 0.439216 0.439216 0.443137 0.443137 0.443137 0.443137 0.458824 0.45098 0.462745 0.447059 0.45098 0.462745 0.454902 0.462745 0.462745 0.462745 0.454902 0.45098 0.45098 0.443137 0.443137 0.447059 0.45098 0.443137 0.443137 0.431373 0.431373 0.431373 0.415686 0.415686 0.407843 0.4 0.376471 0.396078 0.380392 0.376471 0.368627 0.360784 0.352941 0.352941 0.345098 0.329412 0.329412 0.317647 0.309804 0.309804 0.290196 0.286275 0.278431 0.258824 0.25098 0.25098 0.231373 0.219608 0.219608 0.2 0.188235 0.172549 0.160784 0.141176 0.133333 0.2 0.196078 0.160784 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.109804 0.184314 0.219608 0.25098 0.294118 0.356863 0.407843 0.470588 0.545098 0.596078 0.643137 0.6 0.482353 0.345098 0.223529 0.117647 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.101961 0.160784 0.203922 0.231373 0.258824 0.294118 0.313725 0.329412 0.345098 0.360784 0.364706 0.372549 0.392157 0.407843 0.411765 0.411765 0.415686 0.431373 0.435294 0.439216 0.439216 0.439216 0.443137 0.443137 0.45098 0.443137 0.447059 0.447059 0.439216 0.458824 0.458824 0.462745 0.447059 0.443137 0.443137 0.447059 0.443137 0.443137 0.435294 0.443137 0.427451 0.435294 0.427451 0.419608 0.415686 0.411765 0.407843 0.403922 0.392157 0.396078 0.376471 0.388235 0.372549 0.364706 0.360784 0.345098 0.352941 0.337255 0.321569 0.313725 0.305882 0.301961 0.301961 0.286275 0.27451 0.266667 0.258824 0.239216 0.231373 0.219608 0.215686 0.2 0.192157 0.180392 0.164706 0.152941 0.137255 0.129412 0.203922 0.192157 0.133333 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.133333 0.184314 0.219608 0.247059 0.282353 0.32549 0.368627 0.411765 0.478431 0.52549 0.576471 0.854902 0.670588 0.54902 0.443137 0.309804 0.188235 0.0980392 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.137255 0.176471 0.223529 0.25098 0.270588 0.294118 0.321569 0.337255 0.345098 0.364706 0.368627 0.380392 0.396078 0.392157 0.396078 0.415686 0.411765 0.423529 0.411765 0.431373 0.435294 0.439216 0.435294 0.447059 0.439216 0.447059 0.435294 0.443137 0.439216 0.443137 0.439216 0.439216 0.439216 0.435294 0.435294 0.439216 0.435294 0.423529 0.435294 0.427451 0.415686 0.423529 0.407843 0.396078 0.403922 0.396078 0.4 0.388235 0.376471 0.376471 0.356863 0.356863 0.352941 0.356863 0.337255 0.337255 0.329412 0.313725 0.313725 0.286275 0.294118 0.286275 0.266667 0.262745 0.247059 0.247059 0.231373 0.223529 0.219608 0.2 0.188235 0.188235 0.168627 0.152941 0.145098 0.121569 0.133333 0.211765 0.176471 0.054902 0 0 0 0 0 0 0 0.0666667 0.14902 0.192157 0.215686 0.239216 0.262745 0.290196 0.329412 0.356863 0.403922 0.443137 0.482353 0.541176 0.588235 0.807843 0.647059 0.54902 0.454902 0.341176 0.223529 0.133333 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.105882 0.164706 0.196078 0.219608 0.266667 0.282353 0.305882 0.317647 0.337255 0.345098 0.364706 0.364706 0.384314 0.380392 0.4 0.407843 0.407843 0.415686 0.403922 0.423529 0.427451 0.431373 0.427451 0.431373 0.439216 0.439216 0.427451 0.431373 0.435294 0.443137 0.443137 0.423529 0.435294 0.427451 0.427451 0.427451 0.427451 0.423529 0.427451 0.419608 0.415686 0.403922 0.403922 0.403922 0.392157 0.392157 0.380392 0.376471 0.376471 0.360784 0.360784 0.356863 0.345098 0.333333 0.333333 0.32549 0.321569 0.309804 0.294118 0.294118 0.282353 0.27451 0.262745 0.254902 0.25098 0.235294 0.227451 0.219608 0.215686 0.203922 0.188235 0.180392 0.156863 0.137255 0.12549 0.117647 0.129412 0.219608 0.152941 0.0117647 0 0.00392157 0.0117647 0.0666667 0.129412 0.172549 0.2 0.235294 0.258824 0.290196 0.309804 0.345098 0.364706 0.396078 0.427451 0.466667 0.517647 0.568627 0.611765 0.654902 0.619608 0.537255 0.45098 0.341176 0.235294 0.145098 0.0705882 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.133333 0.172549 0.215686 0.239216 0.270588 0.282353 0.305882 0.321569 0.333333 0.345098 0.356863 0.368627 0.376471 0.388235 0.396078 0.392157 0.4 0.4 0.411765 0.419608 0.415686 0.423529 0.427451 0.427451 0.423529 0.431373 0.419608 0.427451 0.431373 0.431373 0.423529 0.427451 0.415686 0.419608 0.419608 0.411765 0.407843 0.403922 0.419608 0.4 0.396078 0.4 0.392157 0.384314 0.372549 0.372549 0.360784 0.372549 0.34902 0.352941 0.341176 0.329412 0.329412 0.321569 0.313725 0.313725 0.298039 0.298039 0.278431 0.278431 0.266667 0.254902 0.25098 0.235294 0.235294 0.219608 0.215686 0.2 0.192157 0.176471 0.164706 0.156863 0.133333 0.117647 0.101961 0.141176 0.203922 0.129412 0.0784314 0.0705882 0.0823529 0.109804 0.168627 0.219608 0.262745 0.298039 0.329412 0.364706 0.396078 0.423529 0.447059 0.486275 0.517647 0.54902 0.603922 0.619608 0.603922 0.552941 0.470588 0.388235 0.298039 0.219608 0.137255 0.0705882 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.101961 0.160784 0.203922 0.227451 0.254902 0.282353 0.301961 0.309804 0.329412 0.337255 0.34902 0.372549 0.364706 0.384314 0.376471 0.396078 0.403922 0.396078 0.407843 0.415686 0.407843 0.403922 0.415686 0.419608 0.415686 0.419608 0.423529 0.419608 0.427451 0.419608 0.427451 0.419608 0.4 0.411765 0.419608 0.407843 0.407843 0.411765 0.396078 0.403922 0.396078 0.384314 0.384314 0.372549 0.376471 0.360784 0.360784 0.356863 0.352941 0.337255 0.337255 0.329412 0.333333 0.317647 0.321569 0.313725 0.294118 0.282353 0.27451 0.27451 0.270588 0.239216 0.25098 0.231373 0.219608 0.215686 0.2 0.192157 0.180392 0.168627 0.152941 0.141176 0.117647 0.129412 0.101961 0.160784 0.196078 0.14902 0.129412 0.129412 0.164706 0.227451 0.290196 0.341176 0.364706 0.415686 0.45098 0.478431 0.501961 0.533333 0.552941 0.607843 0.611765 0.592157 0.533333 0.478431 0.411765 0.313725 0.235294 0.168627 0.105882 0.054902 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.121569 0.168627 0.207843 0.235294 0.254902 0.27451 0.294118 0.317647 0.321569 0.341176 0.356863 0.356863 0.372549 0.372549 0.384314 0.388235 0.396078 0.392157 0.415686 0.392157 0.403922 0.411765 0.415686 0.427451 0.415686 0.415686 0.407843 0.419608 0.415686 0.415686 0.407843 0.407843 0.403922 0.4 0.396078 0.407843 0.388235 0.392157 0.376471 0.388235 0.372549 0.388235 0.364706 0.364706 0.372549 0.352941 0.352941 0.352941 0.337255 0.329412 0.321569 0.313725 0.313725 0.317647 0.298039 0.286275 0.278431 0.27451 0.258824 0.25098 0.239216 0.231373 0.227451 0.207843 0.203922 0.196078 0.176471 0.172549 0.152941 0.141176 0.129412 0.109804 0.101961 0.0901961 0.180392 0.176471 0.2 0.215686 0.235294 0.301961 0.368627 0.419608 0.462745 0.490196 0.52549 0.556863 0.572549 0.603922 0.584314 0.552941 0.517647 0.454902 0.396078 0.317647 0.243137 0.180392 0.121569 0.0745098 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.105882 0.152941 0.184314 0.219608 0.247059 0.262745 0.282353 0.298039 0.321569 0.329412 0.337255 0.345098 0.34902 0.368627 0.368627 0.372549 0.380392 0.388235 0.392157 0.396078 0.392157 0.392157 0.407843 0.407843 0.407843 0.407843 0.4 0.407843 0.407843 0.403922 0.4 0.407843 0.4 0.403922 0.403922 0.396078 0.407843 0.384314 0.388235 0.388235 0.372549 0.372549 0.360784 0.360784 0.352941 0.34902 0.345098 0.329412 0.32549 0.321569 0.317647 0.313725 0.301961 0.294118 0.282353 0.282353 0.278431 0.258824 0.25098 0.25098 0.239216 0.223529 0.211765 0.203922 0.2 0.188235 0.176471 0.156863 0.14902 0.133333 0.121569 0.109804 0.101961 0.0901961 0.168627 0.180392 0.247059 0.301961 0.372549 0.435294 0.490196 0.541176 0.556863 0.545098 0.54902 0.541176 0.494118 0.45098 0.392157 0.345098 0.290196 0.219608 0.160784 0.117647 0.0745098 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.121569 0.164706 0.211765 0.227451 0.254902 0.262745 0.294118 0.290196 0.317647 0.337255 0.333333 0.345098 0.34902 0.34902 0.368627 0.364706 0.364706 0.388235 0.384314 0.396078 0.384314 0.392157 0.403922 0.396078 0.407843 0.4 0.4 0.415686 0.403922 0.396078 0.403922 0.380392 0.403922 0.384314 0.392157 0.384314 0.380392 0.372549 0.364706 0.364706 0.360784 0.360784 0.341176 0.356863 0.345098 0.341176 0.321569 0.32549 0.321569 0.309804 0.305882 0.290196 0.290196 0.27451 0.270588 0.270588 0.247059 0.239216 0.227451 0.219608 0.223529 0.207843 0.192157 0.188235 0.180392 0.176471 0.152941 0.137255 0.129412 0.113725 0.105882 0.0941176 0.0980392 0.145098 0.203922 0.34902 0.411765 0.454902 0.482353 0.482353 0.47451 0.458824 0.415686 0.368627 0.329412 0.278431 0.227451 0.184314 0.141176 0.105882 0.0666667 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0901961 0.141176 0.180392 0.219608 0.247059 0.247059 0.27451 0.286275 0.298039 0.317647 0.32549 0.329412 0.352941 0.345098 0.360784 0.356863 0.376471 0.376471 0.380392 0.384314 0.380392 0.388235 0.388235 0.392157 0.384314 0.388235 0.392157 0.388235 0.392157 0.384314 0.388235 0.384314 0.380392 0.376471 0.384314 0.380392 0.360784 0.376471 0.376471 0.360784 0.356863 0.345098 0.341176 0.337255 0.329412 0.32549 0.321569 0.317647 0.317647 0.301961 0.290196 0.290196 0.282353 0.266667 0.254902 0.258824 0.243137 0.239216 0.231373 0.227451 0.203922 0.203922 0.184314 0.180392 0.164706 0.156863 0.137255 0.129412 0.121569 0.105882 0.0941176 0.0823529 0.0941176 0.129412 0.207843 0.278431 0.329412 0.345098 0.333333 0.32549 0.27451 0.243137 0.207843 0.168627 0.117647 0.0980392 0.0745098 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.117647 0.160784 0.2 0.227451 0.235294 0.27451 0.278431 0.294118 0.317647 0.321569 0.329412 0.329412 0.337255 0.34902 0.352941 0.352941 0.364706 0.372549 0.372549 0.376471 0.384314 0.384314 0.380392 0.380392 0.384314 0.380392 0.376471 0.372549 0.384314 0.380392 0.372549 0.368627 0.372549 0.360784 0.364706 0.368627 0.352941 0.352941 0.34902 0.345098 0.329412 0.337255 0.329412 0.321569 0.309804 0.313725 0.305882 0.298039 0.294118 0.282353 0.270588 0.262745 0.254902 0.254902 0.243137 0.231373 0.223529 0.219608 0.215686 0.203922 0.192157 0.180392 0.172549 0.160784 0.141176 0.137255 0.117647 0.113725 0.0941176 0.0745098 0.0627451 0.0823529 0.129412 0.168627 0.192157 0.196078 0.176471 0.160784 0.133333 0.0980392 0.0823529 0.0470588 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.121569 0.172549 0.2 0.227451 0.243137 0.270588 0.282353 0.286275 0.305882 0.317647 0.337255 0.329412 0.341176 0.341176 0.352941 0.34902 0.356863 0.368627 0.341176 0.360784 0.372549 0.376471 0.376471 0.380392 0.364706 0.368627 0.372549 0.368627 0.372549 0.364706 0.356863 0.368627 0.364706 0.376471 0.360784 0.34902 0.345098 0.337255 0.329412 0.345098 0.329412 0.329412 0.321569 0.313725 0.309804 0.298039 0.290196 0.286275 0.278431 0.27451 0.254902 0.266667 0.247059 0.235294 0.239216 0.219608 0.219608 0.196078 0.192157 0.184314 0.168627 0.160784 0.14902 0.137255 0.12549 0.121569 0.109804 0.101961 0.0745098 0.0392157 0.0784314 0.101961 0.101961 0.0823529 0.0627451 0.054902 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.105882 0.152941 0.188235 0.215686 0.235294 0.254902 0.27451 0.282353 0.294118 0.305882 0.317647 0.329412 0.329412 0.305882 0.337255 0.34902 0.345098 0.356863 0.364706 0.364706 0.360784 0.360784 0.368627 0.364706 0.360784 0.364706 0.364706 0.356863 0.360784 0.360784 0.360784 0.360784 0.356863 0.356863 0.352941 0.341176 0.341176 0.337255 0.337255 0.317647 0.321569 0.313725 0.317647 0.305882 0.294118 0.294118 0.286275 0.282353 0.278431 0.258824 0.258824 0.247059 0.235294 0.223529 0.219608 0.211765 0.203922 0.196078 0.192157 0.172549 0.14902 0.152941 0.133333 0.12549 0.109804 0.105882 0.0901961 0.0745098 0.0352941 0.027451 0.0392157 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.121569 0.152941 0.196078 0.215686 0.235294 0.254902 0.270588 0.286275 0.294118 0.313725 0.321569 0.321569 0.329412 0.337255 0.341176 0.341176 0.352941 0.352941 0.345098 0.34902 0.360784 0.360784 0.352941 0.356863 0.356863 0.364706 0.360784 0.364706 0.352941 0.356863 0.34902 0.345098 0.345098 0.337255 0.341176 0.337255 0.329412 0.32549 0.321569 0.317647 0.309804 0.298039 0.294118 0.294118 0.278431 0.270588 0.258824 0.266667 0.254902 0.239216 0.231373 0.227451 0.223529 0.215686 0.207843 0.2 0.184314 0.176471 0.168627 0.14902 0.145098 0.129412 0.117647 0.109804 0.0980392 0.0862745 0.0509804 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.129412 0.168627 0.196078 0.219608 0.243137 0.262745 0.27451 0.278431 0.294118 0.309804 0.309804 0.321569 0.32549 0.333333 0.333333 0.352941 0.341176 0.341176 0.352941 0.34902 0.345098 0.352941 0.34902 0.356863 0.352941 0.352941 0.352941 0.345098 0.34902 0.345098 0.345098 0.341176 0.32549 0.329412 0.337255 0.317647 0.32549 0.321569 0.309804 0.301961 0.290196 0.294118 0.278431 0.27451 0.270588 0.266667 0.25098 0.243137 0.235294 0.227451 0.223529 0.223529 0.207843 0.196078 0.192157 0.172549 0.164706 0.152941 0.145098 0.141176 0.121569 0.113725 0.101961 0.0901961 0.0588235 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.0941176 0.145098 0.176471 0.203922 0.219608 0.247059 0.258824 0.262745 0.286275 0.294118 0.301961 0.305882 0.321569 0.329412 0.329412 0.329412 0.329412 0.337255 0.337255 0.345098 0.34902 0.341176 0.34902 0.34902 0.34902 0.341176 0.345098 0.333333 0.337255 0.341176 0.333333 0.329412 0.32549 0.333333 0.317647 0.313725 0.305882 0.301961 0.309804 0.286275 0.286275 0.286275 0.27451 0.262745 0.258824 0.25098 0.25098 0.231373 0.231373 0.219608 0.215686 0.203922 0.192157 0.188235 0.168627 0.168627 0.14902 0.141176 0.12549 0.12549 0.113725 0.109804 0.0901961 0.0627451 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.0941176 0.141176 0.172549 0.203922 0.227451 0.231373 0.262745 0.270588 0.282353 0.290196 0.294118 0.305882 0.309804 0.32549 0.321569 0.32549 0.333333 0.337255 0.329412 0.341176 0.341176 0.337255 0.337255 0.341176 0.341176 0.337255 0.329412 0.337255 0.329412 0.329412 0.329412 0.317647 0.321569 0.313725 0.305882 0.301961 0.301961 0.290196 0.282353 0.282353 0.270588 0.262745 0.258824 0.254902 0.247059 0.235294 0.235294 0.223529 0.219608 0.203922 0.2 0.192157 0.172549 0.168627 0.160784 0.152941 0.137255 0.12549 0.113725 0.109804 0.0941176 0.0666667 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.0901961 0.137255 0.164706 0.2 0.215686 0.243137 0.25098 0.270588 0.27451 0.286275 0.298039 0.305882 0.313725 0.317647 0.313725 0.321569 0.329412 0.32549 0.329412 0.333333 0.329412 0.329412 0.329412 0.329412 0.329412 0.313725 0.317647 0.321569 0.32549 0.309804 0.313725 0.309804 0.309804 0.290196 0.290196 0.301961 0.27451 0.286275 0.266667 0.266667 0.262745 0.258824 0.247059 0.243137 0.243137 0.223529 0.215686 0.203922 0.192157 0.184314 0.184314 0.164706 0.160784 0.14902 0.137255 0.129412 0.117647 0.105882 0.0901961 0.0705882 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.0901961 0.121569 0.164706 0.188235 0.215686 0.231373 0.254902 0.266667 0.278431 0.282353 0.294118 0.286275 0.301961 0.309804 0.309804 0.321569 0.321569 0.313725 0.32549 0.321569 0.317647 0.32549 0.321569 0.317647 0.321569 0.317647 0.313725 0.305882 0.32549 0.301961 0.298039 0.294118 0.294118 0.294118 0.270588 0.282353 0.266667 0.270588 0.247059 0.239216 0.231373 0.235294 0.227451 0.223529 0.211765 0.211765 0.192157 0.184314 0.188235 0.160784 0.160784 0.156863 0.137255 0.117647 0.12549 0.0901961 0.0862745 0.0705882 0.0313725 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.0941176 0.113725 0.141176 0.172549 0.2 0.215686 0.231373 0.243137 0.266667 0.270588 0.278431 0.294118 0.286275 0.305882 0.298039 0.301961 0.309804 0.301961 0.313725 0.321569 0.309804 0.313725 0.301961 0.305882 0.309804 0.305882 0.294118 0.301961 0.294118 0.298039 0.286275 0.282353 0.278431 0.270588 0.262745 0.258824 0.25098 0.243137 0.235294 0.231373 0.227451 0.219608 0.211765 0.203922 0.192157 0.180392 0.176471 0.168627 0.156863 0.141176 0.133333 0.121569 0.101961 0.101961 0.0784314 0.0627451 0.0392157 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.0705882 0.113725 0.121569 0.129412 0.160784 0.180392 0.211765 0.207843 0.227451 0.243137 0.25098 0.27451 0.278431 0.282353 0.294118 0.294118 0.301961 0.301961 0.298039 0.309804 0.301961 0.298039 0.305882 0.301961 0.301961 0.298039 0.298039 0.298039 0.290196 0.286275 0.278431 0.270588 0.266667 0.258824 0.25098 0.25098 0.239216 0.239216 0.231373 0.219608 0.219608 0.203922 0.196078 0.184314 0.188235 0.172549 0.156863 0.14902 0.145098 0.129412 0.109804 0.0980392 0.0862745 0.0745098 0.0705882 0.0509804 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0784314 0.0980392 0.141176 0.156863 0.152941 0.145098 0.168627 0.188235 0.207843 0.219608 0.231373 0.239216 0.258824 0.262745 0.266667 0.266667 0.278431 0.290196 0.286275 0.282353 0.27451 0.282353 0.282353 0.290196 0.278431 0.282353 0.27451 0.27451 0.262745 0.266667 0.262745 0.258824 0.239216 0.235294 0.231373 0.223529 0.219608 0.223529 0.207843 0.188235 0.188235 0.172549 0.168627 0.152941 0.14902 0.12549 0.117647 0.117647 0.0980392 0.0862745 0.0901961 0.0941176 0.0784314 0.0431373 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.105882 0.109804 0.141176 0.188235 0.207843 0.188235 0.176471 0.172549 0.192157 0.196078 0.207843 0.223529 0.223529 0.231373 0.235294 0.25098 0.254902 0.254902 0.254902 0.25098 0.258824 0.258824 0.243137 0.25098 0.247059 0.243137 0.247059 0.235294 0.231373 0.227451 0.219608 0.211765 0.211765 0.192157 0.188235 0.184314 0.176471 0.164706 0.160784 0.14902 0.137255 0.12549 0.113725 0.109804 0.113725 0.113725 0.113725 0.109804 0.0901961 0.0666667 0.0509804 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.113725 0.14902 0.145098 0.168627 0.211765 0.219608 0.219608 0.215686 0.211765 0.192157 0.180392 0.184314 0.2 0.2 0.211765 0.211765 0.215686 0.215686 0.215686 0.219608 0.215686 0.219608 0.211765 0.203922 0.207843 0.207843 0.188235 0.192157 0.184314 0.188235 0.176471 0.172549 0.152941 0.156863 0.145098 0.137255 0.129412 0.12549 0.137255 0.141176 0.145098 0.129412 0.113725 0.0980392 0.0901961 0.0784314 0.0627451 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.0588235 0.113725 0.156863 0.168627 0.172549 0.156863 0.192157 0.203922 0.219608 0.223529 0.235294 0.247059 0.235294 0.235294 0.227451 0.219608 0.211765 0.2 0.180392 0.192157 0.176471 0.184314 0.168627 0.180392 0.172549 0.176471 0.172549 0.168627 0.180392 0.176471 0.160784 0.172549 0.188235 0.188235 0.176471 0.160784 0.14902 0.133333 0.121569 0.12549 0.129412 0.109804 0.109804 0.0784314 0.0352941 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0431373 0.0470588 0.0509804 0.0901961 0.121569 0.160784 0.184314 0.196078 0.2 0.188235 0.192157 0.196078 0.192157 0.196078 0.207843 0.219608 0.227451 0.223529 0.235294 0.235294 0.231373 0.231373 0.219608 0.219608 0.215686 0.215686 0.207843 0.196078 0.192157 0.164706 0.164706 0.168627 0.152941 0.141176 0.137255 0.12549 0.117647 0.129412 0.12549 0.164706 0.164706 0.145098 0.0980392 0.0509804 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.137255 0.141176 0.0784314 0.0784314 0.0980392 0.109804 0.129412 0.152941 0.180392 0.192157 0.207843 0.207843 0.207843 0.203922 0.215686 0.2 0.2 0.192157 0.192157 0.188235 0.180392 0.180392 0.180392 0.172549 0.184314 0.168627 0.164706 0.168627 0.156863 0.160784 0.145098 0.14902 0.129412 0.105882 0.109804 0.137255 0.164706 0.172549 0.101961 0.0901961 0.0901961 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.145098 0.121569 0.0588235 0.0470588 0.0705882 0.0784314 0.0823529 0.0941176 0.101961 0.105882 0.109804 0.117647 0.133333 0.133333 0.152941 0.14902 0.156863 0.14902 0.156863 0.137255 0.137255 0.141176 0.133333 0.121569 0.117647 0.101961 0.0941176 0.0784314 0.0823529 0.0745098 0.0901961 0.105882 0.12549 0.12549 0.0901961 0.12549 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.0745098 0.0745098 0.0705882 0.0666667 0.0627451 0.0627451 0.0705882 0.0666667 0.0745098 0.0784314 0.0784314 0.0784314 0.0862745 0.0901961 0.0862745 0.0862745 0.0862745 0.0784314 0.0745098 0.0705882 0.0588235 0.0588235 0.0588235 0.0823529 0.105882 0.109804 0.113725 0.0980392 0.0784314 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.0313725 0.0352941 0.0627451 0.0901961 0.109804 0.109804 0.105882 0.0980392 0.109804 0.0980392 0.0941176 0.0941176 0.101961 0.0901961 0.0941176 0.0823529 0.0705882 0.0941176 0.105882 0.0431373 0.027451 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.027451 0.054902 0.0862745 0.133333 0.172549 0.2 0.239216 0.235294 0.254902 0.239216 0.235294 0.231373 0.196078 0.160784 0.121569 0.0823529 0.0509804 0.0156863 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.0627451 0.113725 0.192157 0.305882 0.415686 0.494118 0.54902 0.588235 0.6 0.611765 0.631373 0.643137 0.643137 0.639216 0.647059 0.654902 0.662745 0.654902 0.658824 0.678431 0.717647 0.776471 0.752941 0.745098 0.72549 0.701961 0.678431 0.658824 0.658824 0.658824 0.647059 0.619608 0.603922 0.564706 0.494118 0.376471 0.258824 0.168627 0.109804 0.0352941 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0705882 0.203922 0.321569 0.423529 0.521569 0.572549 0.592157 0.603922 0.603922 0.619608 0.619608 0.611765 0.611765 0.596078 0.607843 0.596078 0.588235 0.584314 0.580392 0.560784 0.564706 0.576471 0.564706 0.572549 0.556863 0.572549 0.698039 0.803922 0.831373 0.847059 0.796078 0.74902 0.65098 0.647059 0.643137 0.643137 0.647059 0.658824 0.666667 0.662745 0.654902 0.654902 0.643137 0.65098 0.635294 0.615686 0.576471 0.501961 0.388235 0.270588 0.113725 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.156863 0.360784 0.458824 0.517647 0.556863 0.580392 0.572549 0.584314 0.584314 0.568627 0.552941 0.552941 0.517647 0.498039 0.466667 0.45098 0.427451 0.392157 0.392157 0.372549 0.360784 0.368627 0.360784 0.345098 0.341176 0.34902 0.345098 0.337255 0.337255 0.333333 0.380392 0.47451 0.439216 0.356863 0.372549 0.372549 0.372549 0.388235 0.396078 0.423529 0.435294 0.454902 0.482353 0.513725 0.572549 0.639216 0.764706 0.929412 0.972549 0.807843 0.682353 0.670588 0.666667 0.647059 0.627451 0.588235 0.529412 0.415686 0.196078 0.0392157 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.0784314 0.309804 0.47451 0.505882 0.541176 0.552941 0.552941 0.537255 0.52549 0.501961 0.490196 0.458824 0.415686 0.392157 0.360784 0.333333 0.298039 0.286275 0.290196 0.290196 0.27451 0.266667 0.278431 0.270588 0.301961 0.305882 0.305882 0.254902 0.278431 0.278431 0.262745 0.298039 0.341176 0.647059 0.596078 0.34902 0.32549 0.317647 0.298039 0.286275 0.298039 0.294118 0.290196 0.298039 0.305882 0.298039 0.313725 0.305882 0.305882 0.321569 0.337255 0.368627 0.376471 0.403922 0.454902 0.494118 0.545098 0.576471 0.588235 0.615686 0.635294 0.639216 0.615686 0.603922 0.541176 0.376471 0.141176 0.027451 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.145098 0.341176 0.470588 0.501961 0.537255 0.52549 0.513725 0.490196 0.47451 0.427451 0.384314 0.34902 0.313725 0.290196 0.278431 0.262745 0.254902 0.254902 0.231373 0.243137 0.239216 0.258824 0.247059 0.258824 0.25098 0.247059 0.247059 0.270588 0.294118 0.27451 0.235294 0.447059 0.341176 0.254902 0.290196 0.309804 0.980392 1 0.423529 0.352941 0.356863 0.294118 0.266667 0.278431 0.262745 0.266667 0.270588 0.262745 0.266667 0.278431 0.27451 0.286275 0.294118 0.294118 0.309804 0.305882 0.305882 0.321569 0.321569 0.337255 0.360784 0.396078 0.435294 0.482353 0.541176 0.568627 0.592157 0.603922 0.603922 0.580392 0.552941 0.4 0.192157 0.0156863 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.298039 0.447059 0.470588 0.478431 0.498039 0.482353 0.454902 0.411765 0.360784 0.337255 0.282353 0.258824 0.25098 0.231373 0.239216 0.227451 0.235294 0.239216 0.243137 0.239216 0.223529 0.223529 0.227451 0.239216 0.243137 0.239216 0.231373 0.235294 0.235294 0.25098 0.282353 0.278431 0.247059 0.290196 0.258824 0.243137 0.262745 0.305882 0.462745 0.454902 0.298039 0.270588 0.278431 0.258824 0.25098 0.262745 0.247059 0.258824 0.247059 0.247059 0.243137 0.27451 0.266667 0.278431 0.270588 0.282353 0.294118 0.298039 0.298039 0.290196 0.278431 0.313725 0.298039 0.298039 0.309804 0.321569 0.341176 0.384314 0.4 0.466667 0.529412 0.572549 0.588235 0.584314 0.560784 0.509804 0.356863 0.0705882 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.329412 0.458824 0.45098 0.447059 0.462745 0.419608 0.396078 0.341176 0.294118 0.243137 0.215686 0.207843 0.211765 0.203922 0.215686 0.211765 0.211765 0.207843 0.219608 0.215686 0.215686 0.219608 0.215686 0.203922 0.2 0.211765 0.239216 0.231373 0.243137 0.223529 0.211765 0.227451 0.27451 0.262745 0.235294 0.231373 0.235294 0.239216 0.243137 0.266667 0.305882 0.278431 0.286275 0.247059 0.254902 0.254902 0.247059 0.254902 0.243137 0.247059 0.243137 0.247059 0.231373 0.258824 0.25098 0.254902 0.25098 0.247059 0.27451 0.262745 0.270588 0.262745 0.278431 0.286275 0.286275 0.266667 0.278431 0.27451 0.262745 0.27451 0.282353 0.305882 0.32549 0.380392 0.45098 0.509804 0.54902 0.568627 0.552941 0.529412 0.415686 0.137255 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.266667 0.431373 0.415686 0.411765 0.396078 0.392157 0.345098 0.278431 0.243137 0.215686 0.203922 0.2 0.188235 0.192157 0.196078 0.192157 0.2 0.188235 0.196078 0.203922 0.207843 0.215686 0.211765 0.211765 0.207843 0.192157 0.203922 0.219608 0.231373 0.235294 0.219608 0.215686 0.215686 0.223529 0.25098 0.266667 0.223529 0.223529 0.227451 0.227451 0.247059 0.270588 0.301961 0.294118 0.258824 0.239216 0.25098 0.25098 0.231373 0.243137 0.239216 0.231373 0.227451 0.239216 0.239216 0.254902 0.25098 0.247059 0.227451 0.243137 0.270588 0.270588 0.266667 0.262745 0.247059 0.266667 0.27451 0.243137 0.247059 0.25098 0.25098 0.247059 0.247059 0.254902 0.266667 0.270588 0.282353 0.317647 0.392157 0.458824 0.517647 0.533333 0.537255 0.517647 0.407843 0.152941 0.0117647 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.137255 0.388235 0.407843 0.384314 0.364706 0.321569 0.290196 0.243137 0.207843 0.196078 0.184314 0.172549 0.184314 0.180392 0.168627 0.188235 0.196078 0.192157 0.184314 0.188235 0.196078 0.192157 0.196078 0.203922 0.203922 0.207843 0.196078 0.196078 0.207843 0.196078 0.215686 0.235294 0.215686 0.223529 0.203922 0.2 0.247059 0.254902 0.219608 0.219608 0.227451 0.215686 0.231373 0.258824 0.278431 0.266667 0.254902 0.25098 0.254902 0.235294 0.247059 0.235294 0.247059 0.227451 0.219608 0.227451 0.235294 0.243137 0.243137 0.227451 0.239216 0.239216 0.258824 0.270588 0.266667 0.247059 0.227451 0.258824 0.254902 0.235294 0.258824 0.247059 0.223529 0.235294 0.231373 0.239216 0.227451 0.239216 0.25098 0.239216 0.262745 0.282353 0.352941 0.443137 0.490196 0.513725 0.509804 0.478431 0.32549 0.0392157 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.164706 0.396078 0.380392 0.34902 0.321569 0.270588 0.215686 0.2 0.172549 0.160784 0.145098 0.156863 0.152941 0.141176 0.172549 0.176471 0.172549 0.172549 0.172549 0.184314 0.184314 0.192157 0.2 0.188235 0.188235 0.203922 0.2 0.203922 0.184314 0.196078 0.2 0.223529 0.215686 0.215686 0.211765 0.2 0.203922 0.25098 0.247059 0.207843 0.219608 0.215686 0.211765 0.227451 0.243137 0.254902 0.25098 0.25098 0.239216 0.235294 0.243137 0.243137 0.231373 0.239216 0.219608 0.219608 0.235294 0.231373 0.227451 0.223529 0.235294 0.239216 0.235294 0.254902 0.254902 0.254902 0.239216 0.243137 0.235294 0.243137 0.239216 0.235294 0.227451 0.231373 0.243137 0.258824 0.270588 0.286275 0.25098 0.243137 0.262745 0.25098 0.266667 0.254902 0.278431 0.321569 0.427451 0.470588 0.490196 0.498039 0.435294 0.156863 0.0156863 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.231373 0.384314 0.341176 0.298039 0.282353 0.231373 0.180392 0.156863 0.141176 0.145098 0.141176 0.145098 0.14902 0.145098 0.156863 0.145098 0.168627 0.156863 0.156863 0.156863 0.168627 0.184314 0.2 0.215686 0.192157 0.192157 0.180392 0.184314 0.188235 0.188235 0.188235 0.180392 0.188235 0.196078 0.192157 0.192157 0.196078 0.207843 0.2 0.207843 0.203922 0.207843 0.2 0.219608 0.231373 0.223529 0.211765 0.223529 0.215686 0.227451 0.219608 0.215686 0.215686 0.203922 0.215686 0.215686 0.215686 0.215686 0.211765 0.223529 0.223529 0.219608 0.215686 0.219608 0.215686 0.219608 0.223529 0.215686 0.219608 0.227451 0.219608 0.219608 0.223529 0.223529 0.223529 0.219608 0.231373 0.215686 0.219608 0.239216 0.227451 0.215686 0.235294 0.231373 0.231373 0.243137 0.254902 0.290196 0.376471 0.435294 0.462745 0.470588 0.423529 0.152941 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.117647 0.380392 0.337255 0.27451 0.258824 0.2 0.145098 0.141176 0.137255 0.12549 0.129412 0.129412 0.137255 0.133333 0.133333 0.145098 0.145098 0.152941 0.145098 0.152941 0.160784 0.172549 0.164706 0.152941 0.164706 0.164706 0.168627 0.164706 0.172549 0.172549 0.184314 0.180392 0.188235 0.192157 0.192157 0.176471 0.2 0.203922 0.2 0.196078 0.192157 0.207843 0.207843 0.196078 0.2 0.2 0.203922 0.215686 0.211765 0.211765 0.196078 0.223529 0.211765 0.211765 0.223529 0.223529 0.219608 0.227451 0.215686 0.215686 0.211765 0.227451 0.219608 0.219608 0.219608 0.219608 0.211765 0.215686 0.223529 0.219608 0.223529 0.211765 0.215686 0.211765 0.203922 0.231373 0.207843 0.207843 0.219608 0.211765 0.215686 0.211765 0.203922 0.211765 0.196078 0.211765 0.215686 0.223529 0.227451 0.243137 0.333333 0.396078 0.431373 0.447059 0.4 0.129412 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.352941 0.345098 0.270588 0.25098 0.188235 0.133333 0.129412 0.121569 0.117647 0.12549 0.121569 0.121569 0.129412 0.141176 0.133333 0.137255 0.145098 0.145098 0.156863 0.152941 0.160784 0.164706 0.14902 0.160784 0.156863 0.176471 0.156863 0.180392 0.176471 0.164706 0.168627 0.180392 0.184314 0.180392 0.188235 0.180392 0.180392 0.192157 0.192157 0.203922 0.2 0.2 0.196078 0.196078 0.211765 0.196078 0.207843 0.203922 0.2 0.215686 0.207843 0.211765 0.211765 0.203922 0.203922 0.215686 0.196078 0.219608 0.211765 0.203922 0.219608 0.211765 0.211765 0.227451 0.203922 0.207843 0.219608 0.219608 0.215686 0.203922 0.215686 0.207843 0.203922 0.207843 0.2 0.223529 0.196078 0.207843 0.207843 0.211765 0.223529 0.196078 0.207843 0.211765 0.196078 0.196078 0.207843 0.203922 0.215686 0.211765 0.219608 0.301961 0.392157 0.407843 0.411765 0.34902 0.0509804 0 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0980392 0.396078 0.309804 0.243137 0.176471 0.133333 0.121569 0.101961 0.109804 0.117647 0.113725 0.113725 0.12549 0.133333 0.129412 0.129412 0.137255 0.133333 0.14902 0.141176 0.14902 0.14902 0.160784 0.14902 0.152941 0.160784 0.160784 0.168627 0.176471 0.176471 0.172549 0.172549 0.176471 0.180392 0.180392 0.196078 0.188235 0.188235 0.196078 0.196078 0.196078 0.188235 0.196078 0.2 0.2 0.203922 0.2 0.196078 0.219608 0.203922 0.211765 0.203922 0.215686 0.211765 0.203922 0.207843 0.203922 0.2 0.215686 0.207843 0.2 0.207843 0.207843 0.215686 0.211765 0.203922 0.207843 0.211765 0.203922 0.207843 0.2 0.215686 0.203922 0.207843 0.207843 0.196078 0.203922 0.207843 0.2 0.203922 0.211765 0.211765 0.203922 0.196078 0.2 0.196078 0.196078 0.196078 0.196078 0.203922 0.196078 0.188235 0.207843 0.286275 0.368627 0.392157 0.396078 0.219608 0.00392157 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.176471 0.396078 0.290196 0.203922 0.133333 0.113725 0.109804 0.0980392 0.113725 0.101961 0.105882 0.12549 0.12549 0.109804 0.12549 0.12549 0.133333 0.133333 0.14902 0.14902 0.152941 0.145098 0.152941 0.145098 0.156863 0.152941 0.156863 0.168627 0.164706 0.176471 0.168627 0.164706 0.184314 0.180392 0.180392 0.188235 0.192157 0.192157 0.188235 0.180392 0.196078 0.2 0.192157 0.203922 0.196078 0.203922 0.2 0.207843 0.211765 0.203922 0.211765 0.203922 0.2 0.2 0.207843 0.207843 0.203922 0.211765 0.207843 0.2 0.207843 0.223529 0.207843 0.207843 0.203922 0.215686 0.215686 0.203922 0.207843 0.207843 0.207843 0.2 0.196078 0.2 0.196078 0.2 0.203922 0.2 0.203922 0.2 0.192157 0.196078 0.192157 0.196078 0.196078 0.196078 0.196078 0.196078 0.196078 0.184314 0.184314 0.184314 0.180392 0.207843 0.313725 0.345098 0.380392 0.317647 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0.407843 0.301961 0.176471 0.117647 0.109804 0.0941176 0.101961 0.0941176 0.105882 0.101961 0.101961 0.121569 0.113725 0.117647 0.129412 0.133333 0.129412 0.14902 0.137255 0.137255 0.152941 0.145098 0.141176 0.156863 0.164706 0.156863 0.168627 0.172549 0.168627 0.176471 0.176471 0.172549 0.172549 0.192157 0.188235 0.184314 0.180392 0.196078 0.192157 0.2 0.192157 0.196078 0.196078 0.203922 0.211765 0.203922 0.207843 0.219608 0.215686 0.215686 0.207843 0.203922 0.207843 0.207843 0.2 0.211765 0.211765 0.203922 0.2 0.207843 0.2 0.2 0.207843 0.227451 0.215686 0.207843 0.207843 0.2 0.203922 0.207843 0.207843 0.2 0.196078 0.2 0.2 0.2 0.207843 0.196078 0.2 0.211765 0.2 0.196078 0.196078 0.196078 0.192157 0.188235 0.184314 0.188235 0.176471 0.172549 0.164706 0.172549 0.188235 0.258824 0.337255 0.368627 0.333333 0.0745098 0.00392157 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.176471 0.427451 0.356863 0.188235 0.105882 0.0980392 0.0980392 0.0745098 0.0941176 0.0980392 0.0980392 0.0941176 0.101961 0.0980392 0.117647 0.113725 0.113725 0.12549 0.137255 0.133333 0.121569 0.141176 0.145098 0.141176 0.14902 0.156863 0.156863 0.14902 0.160784 0.160784 0.164706 0.168627 0.176471 0.172549 0.164706 0.176471 0.192157 0.192157 0.176471 0.192157 0.192157 0.2 0.184314 0.2 0.192157 0.196078 0.196078 0.203922 0.203922 0.203922 0.2 0.203922 0.203922 0.211765 0.207843 0.2 0.2 0.203922 0.203922 0.203922 0.2 0.203922 0.2 0.2 0.211765 0.2 0.207843 0.196078 0.203922 0.196078 0.203922 0.196078 0.196078 0.192157 0.196078 0.203922 0.2 0.184314 0.2 0.196078 0.207843 0.184314 0.184314 0.180392 0.184314 0.192157 0.180392 0.172549 0.180392 0.164706 0.164706 0.160784 0.176471 0.164706 0.215686 0.32549 0.368627 0.333333 0.0745098 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.145098 0.4 0.45098 0.282353 0.109804 0.101961 0.101961 0.0862745 0.0941176 0.0980392 0.0941176 0.0901961 0.0941176 0.0941176 0.101961 0.0941176 0.109804 0.109804 0.113725 0.117647 0.129412 0.117647 0.12549 0.129412 0.129412 0.129412 0.129412 0.14902 0.145098 0.141176 0.152941 0.14902 0.168627 0.156863 0.168627 0.168627 0.156863 0.164706 0.180392 0.176471 0.180392 0.172549 0.180392 0.176471 0.184314 0.188235 0.188235 0.180392 0.196078 0.180392 0.188235 0.188235 0.184314 0.188235 0.192157 0.184314 0.188235 0.196078 0.196078 0.188235 0.196078 0.196078 0.192157 0.203922 0.192157 0.188235 0.196078 0.203922 0.188235 0.188235 0.184314 0.184314 0.188235 0.188235 0.192157 0.188235 0.188235 0.184314 0.168627 0.188235 0.176471 0.180392 0.180392 0.172549 0.176471 0.164706 0.164706 0.164706 0.172549 0.152941 0.168627 0.160784 0.160784 0.160784 0.215686 0.329412 0.384314 0.290196 0.0705882 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.113725 0.32549 0.470588 0.466667 0.262745 0.101961 0.101961 0.0980392 0.0823529 0.0980392 0.0901961 0.0862745 0.0980392 0.101961 0.0901961 0.105882 0.105882 0.101961 0.101961 0.121569 0.105882 0.109804 0.121569 0.12549 0.12549 0.129412 0.129412 0.129412 0.141176 0.133333 0.145098 0.152941 0.14902 0.156863 0.152941 0.14902 0.160784 0.168627 0.160784 0.160784 0.168627 0.172549 0.176471 0.180392 0.184314 0.180392 0.180392 0.180392 0.188235 0.192157 0.180392 0.188235 0.180392 0.192157 0.188235 0.172549 0.188235 0.184314 0.180392 0.2 0.184314 0.196078 0.180392 0.192157 0.196078 0.192157 0.196078 0.192157 0.192157 0.180392 0.196078 0.192157 0.188235 0.188235 0.184314 0.188235 0.188235 0.176471 0.176471 0.176471 0.172549 0.168627 0.172549 0.176471 0.176471 0.160784 0.156863 0.164706 0.152941 0.168627 0.156863 0.14902 0.156863 0.160784 0.278431 0.388235 0.372549 0.235294 0.0784314 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.254902 0.396078 0.521569 0.513725 0.305882 0.117647 0.109804 0.101961 0.0901961 0.0862745 0.101961 0.0901961 0.0823529 0.101961 0.0980392 0.101961 0.105882 0.105882 0.109804 0.105882 0.129412 0.12549 0.113725 0.129412 0.12549 0.129412 0.137255 0.137255 0.137255 0.152941 0.137255 0.145098 0.156863 0.156863 0.168627 0.152941 0.164706 0.168627 0.164706 0.172549 0.168627 0.172549 0.176471 0.172549 0.176471 0.184314 0.172549 0.180392 0.188235 0.188235 0.188235 0.188235 0.188235 0.184314 0.180392 0.196078 0.184314 0.196078 0.188235 0.196078 0.196078 0.192157 0.188235 0.196078 0.192157 0.184314 0.180392 0.196078 0.196078 0.188235 0.196078 0.180392 0.184314 0.180392 0.172549 0.176471 0.172549 0.184314 0.172549 0.168627 0.172549 0.172549 0.172549 0.160784 0.172549 0.172549 0.164706 0.152941 0.145098 0.145098 0.152941 0.160784 0.239216 0.380392 0.392157 0.305882 0.203922 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.227451 0.329412 0.431373 0.552941 0.572549 0.427451 0.180392 0.117647 0.105882 0.0862745 0.0862745 0.0862745 0.0941176 0.0980392 0.0901961 0.105882 0.101961 0.101961 0.105882 0.109804 0.105882 0.121569 0.117647 0.12549 0.12549 0.12549 0.133333 0.133333 0.141176 0.14902 0.14902 0.152941 0.152941 0.14902 0.156863 0.160784 0.160784 0.160784 0.168627 0.176471 0.164706 0.172549 0.176471 0.176471 0.176471 0.168627 0.176471 0.192157 0.180392 0.180392 0.188235 0.188235 0.192157 0.176471 0.188235 0.192157 0.184314 0.188235 0.188235 0.180392 0.192157 0.196078 0.196078 0.188235 0.180392 0.192157 0.192157 0.184314 0.184314 0.184314 0.188235 0.176471 0.176471 0.176471 0.184314 0.184314 0.172549 0.172549 0.176471 0.176471 0.168627 0.168627 0.160784 0.164706 0.156863 0.156863 0.152941 0.156863 0.14902 0.14902 0.164706 0.305882 0.415686 0.407843 0.321569 0.239216 0.176471 0.0431373 0 0 0 0 0 0 0 0 0 0 0.027451 0.0588235 0.0666667 0.054902 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.192157 0.286275 0.364706 0.454902 0.588235 0.619608 0.580392 0.388235 0.156863 0.117647 0.117647 0.0980392 0.0823529 0.0941176 0.0823529 0.109804 0.105882 0.101961 0.101961 0.0980392 0.117647 0.105882 0.117647 0.12549 0.121569 0.129412 0.133333 0.137255 0.141176 0.141176 0.141176 0.141176 0.137255 0.152941 0.156863 0.152941 0.172549 0.160784 0.168627 0.168627 0.168627 0.160784 0.168627 0.176471 0.188235 0.164706 0.180392 0.184314 0.184314 0.192157 0.184314 0.192157 0.192157 0.180392 0.188235 0.192157 0.203922 0.192157 0.188235 0.192157 0.192157 0.188235 0.196078 0.188235 0.176471 0.196078 0.196078 0.176471 0.192157 0.188235 0.188235 0.184314 0.180392 0.188235 0.180392 0.184314 0.164706 0.172549 0.176471 0.180392 0.176471 0.176471 0.164706 0.168627 0.160784 0.156863 0.152941 0.141176 0.145098 0.247059 0.407843 0.45098 0.415686 0.34902 0.290196 0.278431 0.160784 0.0117647 0 0 0 0 0 0.027451 0.196078 0.27451 0.32549 0.356863 0.380392 0.396078 0.388235 0.396078 0.376471 0.345098 0.313725 0.223529 0.0666667 0 0 0 0 0 0 0 0 0 0 0.0117647 0.156863 0.247059 0.329412 0.392157 0.454902 0.541176 0.607843 0.654902 0.615686 0.443137 0.203922 0.12549 0.117647 0.109804 0.101961 0.109804 0.101961 0.105882 0.109804 0.101961 0.101961 0.121569 0.105882 0.113725 0.12549 0.121569 0.129412 0.129412 0.137255 0.141176 0.137255 0.160784 0.145098 0.156863 0.160784 0.160784 0.164706 0.152941 0.160784 0.156863 0.168627 0.168627 0.164706 0.164706 0.184314 0.176471 0.184314 0.180392 0.192157 0.196078 0.188235 0.184314 0.188235 0.188235 0.188235 0.184314 0.180392 0.184314 0.192157 0.188235 0.192157 0.184314 0.184314 0.196078 0.188235 0.192157 0.180392 0.188235 0.196078 0.188235 0.184314 0.176471 0.192157 0.180392 0.184314 0.184314 0.160784 0.172549 0.176471 0.164706 0.164706 0.156863 0.172549 0.164706 0.172549 0.168627 0.176471 0.270588 0.431373 0.486275 0.470588 0.415686 0.368627 0.337255 0.313725 0.27451 0.160784 0.00784314 0 0 0.0117647 0.168627 0.333333 0.392157 0.427451 0.458824 0.486275 0.498039 0.498039 0.513725 0.501961 0.513725 0.490196 0.47451 0.454902 0.411765 0.372549 0.309804 0.121569 0.0117647 0 0 0 0 0 0 0 0 0.141176 0.227451 0.294118 0.356863 0.407843 0.470588 0.513725 0.572549 0.643137 0.666667 0.67451 0.584314 0.364706 0.196078 0.133333 0.121569 0.113725 0.105882 0.113725 0.105882 0.109804 0.121569 0.105882 0.113725 0.12549 0.12549 0.137255 0.137255 0.141176 0.14902 0.137255 0.160784 0.152941 0.14902 0.145098 0.152941 0.168627 0.156863 0.168627 0.176471 0.164706 0.168627 0.172549 0.172549 0.188235 0.184314 0.180392 0.192157 0.188235 0.180392 0.180392 0.192157 0.196078 0.180392 0.192157 0.192157 0.196078 0.196078 0.188235 0.196078 0.192157 0.196078 0.188235 0.180392 0.188235 0.192157 0.188235 0.196078 0.188235 0.188235 0.188235 0.176471 0.188235 0.188235 0.176471 0.176471 0.180392 0.176471 0.176471 0.172549 0.172549 0.172549 0.160784 0.156863 0.231373 0.364706 0.498039 0.517647 0.498039 0.45098 0.396078 0.360784 0.345098 0.32549 0.298039 0.27451 0.223529 0.141176 0.109804 0.196078 0.305882 0.392157 0.478431 0.517647 0.533333 0.560784 0.568627 0.580392 0.588235 0.596078 0.6 0.572549 0.580392 0.560784 0.54902 0.517647 0.482353 0.435294 0.376471 0.278431 0.0901961 0.00392157 0 0 0 0 0 0 0.117647 0.211765 0.270588 0.333333 0.384314 0.419608 0.462745 0.498039 0.517647 0.580392 0.631373 0.678431 0.713725 0.705882 0.611765 0.454902 0.243137 0.14902 0.133333 0.129412 0.109804 0.133333 0.12549 0.12549 0.12549 0.129412 0.129412 0.12549 0.137255 0.152941 0.145098 0.164706 0.152941 0.172549 0.156863 0.164706 0.156863 0.164706 0.176471 0.168627 0.168627 0.168627 0.176471 0.184314 0.176471 0.184314 0.184314 0.192157 0.188235 0.180392 0.188235 0.196078 0.184314 0.188235 0.192157 0.196078 0.192157 0.184314 0.188235 0.192157 0.2 0.196078 0.192157 0.196078 0.192157 0.176471 0.184314 0.180392 0.184314 0.180392 0.188235 0.184314 0.180392 0.184314 0.176471 0.184314 0.192157 0.172549 0.164706 0.180392 0.176471 0.27451 0.419608 0.509804 0.552941 0.537255 0.490196 0.45098 0.407843 0.364706 0.333333 0.337255 0.313725 0.305882 0.282353 0.286275 0.270588 0.337255 0.360784 0.384314 0.415686 0.494118 0.560784 0.588235 0.607843 0.623529 0.635294 0.635294 0.654902 0.654902 0.647059 0.635294 0.635294 0.619608 0.611765 0.592157 0.556863 0.513725 0.478431 0.407843 0.337255 0.172549 0.0156863 0 0 0 0 0 0.0901961 0.2 0.25098 0.305882 0.352941 0.388235 0.427451 0.462745 0.490196 0.517647 0.541176 0.584314 0.623529 0.666667 0.705882 0.741176 0.745098 0.713725 0.627451 0.458824 0.27451 0.196078 0.164706 0.145098 0.133333 0.129412 0.141176 0.129412 0.141176 0.145098 0.141176 0.152941 0.152941 0.156863 0.168627 0.164706 0.160784 0.176471 0.172549 0.172549 0.168627 0.180392 0.180392 0.176471 0.184314 0.176471 0.176471 0.176471 0.188235 0.184314 0.192157 0.184314 0.196078 0.180392 0.188235 0.184314 0.184314 0.188235 0.203922 0.188235 0.196078 0.184314 0.192157 0.196078 0.184314 0.196078 0.196078 0.192157 0.188235 0.184314 0.184314 0.192157 0.196078 0.188235 0.188235 0.203922 0.203922 0.282353 0.423529 0.529412 0.572549 0.580392 0.560784 0.537255 0.490196 0.447059 0.403922 0.376471 0.345098 0.317647 0.298039 0.262745 0.258824 0.313725 0.278431 0.294118 0.333333 0.423529 0.439216 0.439216 0.486275 0.552941 0.615686 0.635294 0.658824 0.654902 0.662745 0.678431 0.682353 0.678431 0.764706 0.764706 0.717647 0.666667 0.65098 0.631373 0.615686 0.576471 0.541176 0.486275 0.423529 0.333333 0.192157 0.0117647 0 0 0 0 0.054902 0.180392 0.247059 0.286275 0.333333 0.372549 0.396078 0.427451 0.462745 0.486275 0.509804 0.52549 0.517647 0.576471 0.6 0.639216 0.682353 0.709804 0.729412 0.760784 0.764706 0.756863 0.721569 0.631373 0.486275 0.360784 0.266667 0.188235 0.156863 0.14902 0.152941 0.160784 0.152941 0.156863 0.164706 0.156863 0.156863 0.172549 0.168627 0.168627 0.172549 0.180392 0.180392 0.180392 0.184314 0.180392 0.192157 0.188235 0.180392 0.192157 0.192157 0.184314 0.184314 0.184314 0.196078 0.192157 0.192157 0.192157 0.192157 0.2 0.192157 0.196078 0.188235 0.196078 0.196078 0.192157 0.184314 0.192157 0.188235 0.192157 0.231373 0.290196 0.345098 0.439216 0.537255 0.588235 0.611765 0.611765 0.588235 0.576471 0.537255 0.509804 0.470588 0.443137 0.411765 0.388235 0.356863 0.32549 0.305882 0.294118 0.262745 0.227451 0.211765 0.27451 0.290196 0.294118 0.392157 0.482353 0.470588 0.482353 0.533333 0.596078 0.768627 0.796078 0.72549 0.690196 0.690196 0.662745 0.647059 0.647059 0.635294 0.756863 0.862745 0.701961 0.658824 0.662745 0.647059 0.615686 0.580392 0.556863 0.498039 0.415686 0.32549 0.14902 0.0117647 0 0 0 0.0235294 0.164706 0.227451 0.278431 0.321569 0.356863 0.380392 0.403922 0.431373 0.458824 0.47451 0.482353 0.513725 0.537255 0.556863 0.572549 0.596078 0.615686 0.623529 0.658824 0.694118 0.713725 0.72549 0.760784 0.772549 0.780392 0.839216 0.890196 0.776471 0.686275 0.607843 0.545098 0.462745 0.364706 0.294118 0.219608 0.196078 0.180392 0.164706 0.176471 0.180392 0.180392 0.172549 0.176471 0.192157 0.188235 0.184314 0.192157 0.196078 0.196078 0.192157 0.192157 0.196078 0.196078 0.188235 0.192157 0.192157 0.192157 0.192157 0.196078 0.2 0.211765 0.247059 0.317647 0.376471 0.447059 0.505882 0.552941 0.611765 0.639216 0.654902 0.658824 0.65098 0.643137 0.615686 0.6 0.564706 0.521569 0.505882 0.466667 0.458824 0.419608 0.4 0.388235 0.364706 0.337255 0.313725 0.290196 0.282353 0.286275 0.235294 0.203922 0.196078 0.258824 0.321569 0.301961 0.447059 0.501961 0.490196 0.521569 0.552941 0.639216 0.729412 0.65098 0.603922 0.580392 0.54902 0.513725 0.490196 0.478431 0.478431 0.513725 0.545098 0.576471 0.631373 0.686275 0.6 0.596078 0.603922 0.568627 0.529412 0.486275 0.396078 0.282353 0.0705882 0.00784314 0 0 0 0.137255 0.215686 0.27451 0.313725 0.34902 0.368627 0.4 0.407843 0.435294 0.458824 0.462745 0.490196 0.509804 0.529412 0.545098 0.545098 0.564706 0.576471 0.596078 0.6 0.623529 0.643137 0.662745 0.658824 0.701961 0.709804 0.737255 0.741176 0.74902 0.756863 0.811765 0.811765 0.835294 0.815686 0.784314 0.788235 0.764706 0.752941 0.745098 0.729412 0.721569 0.690196 0.678431 0.643137 0.639216 0.623529 0.603922 0.603922 0.603922 0.596078 0.592157 0.607843 0.623529 0.631373 0.654902 0.666667 0.694118 0.694118 0.717647 0.698039 0.721569 0.717647 0.705882 0.705882 0.678431 0.670588 0.65098 0.631373 0.619608 0.6 0.568627 0.556863 0.541176 0.521569 0.498039 0.47451 0.447059 0.435294 0.415686 0.388235 0.376471 0.364706 0.341176 0.32549 0.313725 0.27451 0.262745 0.278431 0.254902 0.219608 0.192157 0.180392 0.254902 0.270588 0.345098 0.596078 0.623529 0.521569 0.52549 0.564706 0.568627 0.52549 0.501961 0.407843 0.317647 0.227451 0.152941 0.0901961 0.0588235 0.0784314 0.141176 0.192157 0.231373 0.4 0.509804 0.623529 0.592157 0.592157 0.584314 0.564706 0.513725 0.462745 0.352941 0.211765 0.0235294 0.00392157 0 0 0.0980392 0.2 0.247059 0.298039 0.341176 0.364706 0.392157 0.403922 0.427451 0.443137 0.439216 0.478431 0.490196 0.509804 0.509804 0.533333 0.537255 0.545098 0.560784 0.568627 0.596078 0.596078 0.6 0.596078 0.619608 0.619608 0.635294 0.639216 0.65098 0.654902 0.67451 0.686275 0.694118 0.698039 0.705882 0.705882 0.713725 0.733333 0.733333 0.745098 0.737255 0.752941 0.776471 0.8 0.831373 0.858824 0.996078 0.976471 0.8 0.784314 0.780392 0.74902 0.745098 0.756863 0.709804 0.717647 0.709804 0.694118 0.666667 0.654902 0.643137 0.631373 0.611765 0.603922 0.588235 0.572549 0.54902 0.541176 0.517647 0.509804 0.498039 0.494118 0.47451 0.462745 0.431373 0.419608 0.419608 0.396078 0.384314 0.368627 0.356863 0.337255 0.329412 0.305882 0.294118 0.270588 0.254902 0.266667 0.243137 0.215686 0.192157 0.176471 0.262745 0.286275 0.368627 0.517647 0.513725 0.509804 0.517647 0.490196 0.435294 0.345098 0.196078 0.0588235 0 0 0 0 0 0 0 0 0 0.0509804 0.211765 0.380392 0.505882 0.572549 0.580392 0.564706 0.537255 0.482353 0.419608 0.298039 0.101961 0.00784314 0 0 0.0666667 0.176471 0.243137 0.286275 0.321569 0.360784 0.392157 0.407843 0.411765 0.443137 0.443137 0.454902 0.47451 0.47451 0.486275 0.505882 0.509804 0.521569 0.537255 0.541176 0.54902 0.568627 0.580392 0.584314 0.588235 0.596078 0.603922 0.596078 0.603922 0.603922 0.631373 0.615686 0.635294 0.627451 0.643137 0.627451 0.654902 0.643137 0.647059 0.639216 0.631373 0.635294 0.639216 0.639216 0.647059 0.635294 0.639216 0.631373 0.639216 0.627451 0.619608 0.611765 0.607843 0.623529 0.619608 0.603922 0.588235 0.584314 0.568627 0.564706 0.560784 0.54902 0.533333 0.537255 0.521569 0.517647 0.501961 0.498039 0.482353 0.470588 0.45098 0.454902 0.447059 0.423529 0.411765 0.403922 0.384314 0.364706 0.360784 0.34902 0.32549 0.313725 0.301961 0.282353 0.27451 0.262745 0.239216 0.266667 0.239216 0.219608 0.180392 0.160784 0.235294 0.258824 0.376471 0.6 0.509804 0.494118 0.470588 0.372549 0.207843 0.054902 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.317647 0.462745 0.545098 0.560784 0.545098 0.517647 0.447059 0.376471 0.211765 0.0313725 0 0 0.0235294 0.160784 0.227451 0.266667 0.317647 0.34902 0.384314 0.4 0.423529 0.431373 0.462745 0.454902 0.462745 0.482353 0.498039 0.490196 0.498039 0.470588 0.501961 0.521569 0.52549 0.545098 0.545098 0.564706 0.572549 0.568627 0.572549 0.588235 0.592157 0.592157 0.596078 0.6 0.603922 0.6 0.603922 0.6 0.6 0.611765 0.596078 0.596078 0.596078 0.607843 0.592157 0.6 0.592157 0.596078 0.603922 0.6 0.596078 0.603922 0.6 0.576471 0.580392 0.576471 0.564706 0.560784 0.556863 0.537255 0.537255 0.537255 0.533333 0.509804 0.513725 0.490196 0.490196 0.478431 0.462745 0.454902 0.447059 0.439216 0.435294 0.427451 0.411765 0.392157 0.392157 0.392157 0.364706 0.352941 0.337255 0.32549 0.321569 0.301961 0.294118 0.282353 0.262745 0.247059 0.235294 0.254902 0.239216 0.211765 0.176471 0.164706 0.231373 0.266667 0.388235 0.47451 0.470588 0.439216 0.32549 0.137255 0.0117647 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.290196 0.470588 0.541176 0.537255 0.517647 0.470588 0.411765 0.294118 0.0823529 0 0 0.00392157 0.129412 0.2 0.254902 0.309804 0.341176 0.360784 0.388235 0.407843 0.427451 0.447059 0.454902 0.466667 0.478431 0.486275 0.494118 0.494118 0.494118 0.501961 0.505882 0.517647 0.52549 0.529412 0.537255 0.545098 0.552941 0.552941 0.560784 0.568627 0.560784 0.580392 0.568627 0.568627 0.580392 0.580392 0.580392 0.580392 0.572549 0.576471 0.584314 0.568627 0.580392 0.588235 0.584314 0.596078 0.596078 0.611765 0.623529 0.596078 0.572549 0.564706 0.552941 0.560784 0.545098 0.537255 0.52549 0.52549 0.52549 0.509804 0.505882 0.498039 0.486275 0.490196 0.470588 0.458824 0.454902 0.447059 0.443137 0.439216 0.423529 0.407843 0.403922 0.396078 0.380392 0.364706 0.356863 0.34902 0.337255 0.329412 0.313725 0.301961 0.301961 0.282353 0.266667 0.262745 0.247059 0.243137 0.262745 0.227451 0.2 0.172549 0.160784 0.215686 0.270588 0.384314 0.435294 0.407843 0.294118 0.109804 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.356863 0.498039 0.529412 0.505882 0.470588 0.411765 0.333333 0.133333 0 0 0 0.0980392 0.188235 0.235294 0.290196 0.317647 0.356863 0.372549 0.396078 0.411765 0.431373 0.45098 0.45098 0.470588 0.482353 0.490196 0.498039 0.501961 0.505882 0.509804 0.509804 0.517647 0.529412 0.533333 0.529412 0.545098 0.545098 0.537255 0.545098 0.541176 0.556863 0.552941 0.545098 0.556863 0.552941 0.556863 0.560784 0.560784 0.560784 0.564706 0.564706 0.568627 0.560784 0.560784 0.564706 0.576471 0.576471 0.572549 0.560784 0.552941 0.533333 0.529412 0.529412 0.513725 0.517647 0.498039 0.498039 0.501961 0.490196 0.482353 0.470588 0.462745 0.462745 0.447059 0.447059 0.443137 0.427451 0.419608 0.403922 0.4 0.396078 0.376471 0.376471 0.368627 0.356863 0.345098 0.337255 0.329412 0.32549 0.305882 0.301961 0.286275 0.27451 0.266667 0.25098 0.243137 0.254902 0.262745 0.231373 0.192157 0.164706 0.145098 0.207843 0.27451 0.368627 0.364706 0.266667 0.0980392 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.203922 0.447059 0.498039 0.498039 0.47451 0.411765 0.34902 0.156863 0 0 0 0.0509804 0.164706 0.231373 0.270588 0.317647 0.337255 0.380392 0.396078 0.403922 0.423529 0.439216 0.447059 0.462745 0.470588 0.47451 0.486275 0.498039 0.498039 0.501961 0.505882 0.529412 0.517647 0.517647 0.537255 0.537255 0.529412 0.533333 0.545098 0.541176 0.52549 0.545098 0.541176 0.541176 0.541176 0.541176 0.552941 0.541176 0.545098 0.541176 0.545098 0.537255 0.533333 0.529412 0.537255 0.529412 0.533333 0.52549 0.505882 0.513725 0.509804 0.505882 0.505882 0.513725 0.490196 0.498039 0.490196 0.478431 0.47451 0.47451 0.458824 0.45098 0.447059 0.443137 0.435294 0.419608 0.411765 0.411765 0.407843 0.396078 0.392157 0.380392 0.368627 0.360784 0.34902 0.341176 0.333333 0.333333 0.317647 0.298039 0.298039 0.282353 0.27451 0.258824 0.247059 0.231373 0.25098 0.247059 0.215686 0.176471 0.152941 0.133333 0.196078 0.262745 0.317647 0.270588 0.109804 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0784314 0.376471 0.490196 0.494118 0.470588 0.415686 0.333333 0.172549 0 0 0 0.00392157 0.145098 0.211765 0.254902 0.294118 0.321569 0.360784 0.376471 0.396078 0.415686 0.423529 0.443137 0.458824 0.462745 0.466667 0.482353 0.486275 0.501961 0.498039 0.509804 0.505882 0.517647 0.52549 0.517647 0.533333 0.537255 0.541176 0.545098 0.537255 0.537255 0.537255 0.533333 0.537255 0.541176 0.541176 0.552941 0.533333 0.521569 0.541176 0.537255 0.529412 0.517647 0.537255 0.517647 0.521569 0.517647 0.52549 0.509804 0.513725 0.486275 0.494118 0.498039 0.482353 0.482353 0.482353 0.466667 0.47451 0.470588 0.462745 0.45098 0.45098 0.439216 0.435294 0.415686 0.423529 0.407843 0.411765 0.392157 0.392157 0.392157 0.368627 0.364706 0.352941 0.352941 0.329412 0.329412 0.305882 0.329412 0.301961 0.290196 0.286275 0.270588 0.25098 0.243137 0.227451 0.262745 0.243137 0.215686 0.164706 0.141176 0.129412 0.172549 0.243137 0.231373 0.141176 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.290196 0.482353 0.498039 0.458824 0.403922 0.329412 0.188235 0 0 0 0 0.109804 0.192157 0.239216 0.282353 0.317647 0.341176 0.376471 0.392157 0.4 0.419608 0.439216 0.45098 0.462745 0.466667 0.490196 0.490196 0.486275 0.505882 0.509804 0.517647 0.513725 0.52549 0.529412 0.529412 0.529412 0.533333 0.533333 0.533333 0.533333 0.537255 0.533333 0.52549 0.537255 0.537255 0.52549 0.529412 0.529412 0.529412 0.533333 0.529412 0.517647 0.521569 0.52549 0.521569 0.513725 0.521569 0.501961 0.501961 0.498039 0.505882 0.486275 0.486275 0.486275 0.478431 0.47451 0.458824 0.462745 0.462745 0.443137 0.435294 0.439216 0.423529 0.423529 0.419608 0.407843 0.4 0.388235 0.380392 0.368627 0.372549 0.364706 0.345098 0.333333 0.329412 0.329412 0.317647 0.305882 0.301961 0.290196 0.266667 0.258824 0.25098 0.235294 0.231373 0.254902 0.231373 0.2 0.156863 0.137255 0.109804 0.152941 0.196078 0.14902 0.0352941 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.243137 0.462745 0.490196 0.435294 0.396078 0.317647 0.176471 0 0 0 0 0.0627451 0.164706 0.211765 0.266667 0.298039 0.333333 0.356863 0.384314 0.396078 0.407843 0.427451 0.423529 0.454902 0.454902 0.478431 0.478431 0.486275 0.494118 0.498039 0.498039 0.513725 0.517647 0.509804 0.513725 0.521569 0.533333 0.529412 0.513725 0.533333 0.52549 0.52549 0.529412 0.537255 0.517647 0.529412 0.533333 0.533333 0.529412 0.517647 0.513725 0.521569 0.521569 0.517647 0.521569 0.521569 0.501961 0.501961 0.505882 0.490196 0.501961 0.490196 0.486275 0.486275 0.470588 0.470588 0.462745 0.458824 0.458824 0.435294 0.443137 0.431373 0.423529 0.415686 0.407843 0.4 0.403922 0.388235 0.384314 0.376471 0.372549 0.360784 0.345098 0.345098 0.333333 0.321569 0.317647 0.298039 0.290196 0.278431 0.270588 0.254902 0.247059 0.231373 0.219608 0.258824 0.219608 0.196078 0.152941 0.12549 0.101961 0.117647 0.113725 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.227451 0.447059 0.494118 0.439216 0.384314 0.313725 0.172549 0 0 0 0 0.0196078 0.141176 0.2 0.247059 0.278431 0.317647 0.345098 0.376471 0.384314 0.4 0.407843 0.423529 0.447059 0.454902 0.454902 0.462745 0.482353 0.490196 0.490196 0.498039 0.513725 0.513725 0.513725 0.513725 0.509804 0.517647 0.521569 0.533333 0.533333 0.52549 0.517647 0.52549 0.52549 0.517647 0.529412 0.533333 0.521569 0.513725 0.513725 0.521569 0.517647 0.52549 0.521569 0.513725 0.517647 0.505882 0.498039 0.505882 0.501961 0.486275 0.482353 0.478431 0.478431 0.466667 0.458824 0.466667 0.454902 0.458824 0.439216 0.435294 0.435294 0.411765 0.419608 0.411765 0.392157 0.396078 0.384314 0.372549 0.372549 0.372549 0.352941 0.345098 0.329412 0.32549 0.313725 0.301961 0.286275 0.27451 0.270588 0.266667 0.243137 0.235294 0.203922 0.227451 0.258824 0.211765 0.188235 0.145098 0.113725 0.0941176 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.258824 0.447059 0.494118 0.423529 0.352941 0.278431 0.141176 0 0 0 0 0 0.0980392 0.188235 0.219608 0.262745 0.309804 0.329412 0.34902 0.372549 0.396078 0.411765 0.411765 0.435294 0.443137 0.454902 0.462745 0.466667 0.47451 0.486275 0.478431 0.501961 0.505882 0.501961 0.505882 0.505882 0.517647 0.521569 0.509804 0.517647 0.52549 0.509804 0.521569 0.513725 0.521569 0.529412 0.513725 0.517647 0.513725 0.513725 0.517647 0.517647 0.501961 0.501961 0.509804 0.498039 0.498039 0.498039 0.501961 0.482353 0.486275 0.486275 0.470588 0.458824 0.470588 0.466667 0.454902 0.447059 0.435294 0.427451 0.423529 0.427451 0.415686 0.407843 0.4 0.388235 0.384314 0.384314 0.368627 0.360784 0.352941 0.34902 0.337255 0.321569 0.317647 0.305882 0.298039 0.282353 0.266667 0.262745 0.25098 0.235294 0.227451 0.207843 0.231373 0.25098 0.211765 0.184314 0.133333 0.105882 0.0745098 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.313725 0.470588 0.501961 0.419608 0.337255 0.243137 0.105882 0 0 0 0 0 0.054902 0.160784 0.211765 0.25098 0.294118 0.313725 0.352941 0.364706 0.376471 0.407843 0.396078 0.419608 0.439216 0.439216 0.454902 0.462745 0.47451 0.47451 0.47451 0.486275 0.498039 0.498039 0.490196 0.509804 0.521569 0.509804 0.52549 0.509804 0.521569 0.513725 0.517647 0.517647 0.513725 0.505882 0.517647 0.505882 0.505882 0.509804 0.517647 0.505882 0.498039 0.494118 0.498039 0.498039 0.494118 0.482353 0.490196 0.478431 0.47451 0.47451 0.462745 0.466667 0.45098 0.45098 0.443137 0.443137 0.443137 0.431373 0.419608 0.427451 0.411765 0.396078 0.396078 0.384314 0.388235 0.368627 0.368627 0.34902 0.34902 0.337255 0.317647 0.313725 0.301961 0.290196 0.282353 0.282353 0.262745 0.254902 0.235294 0.231373 0.215686 0.2 0.239216 0.235294 0.196078 0.168627 0.117647 0.0941176 0.0392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0.396078 0.501961 0.486275 0.396078 0.309804 0.215686 0.0588235 0 0 0 0 0 0.0117647 0.137255 0.192157 0.243137 0.278431 0.309804 0.333333 0.360784 0.372549 0.388235 0.403922 0.411765 0.423529 0.431373 0.439216 0.443137 0.45098 0.466667 0.462745 0.478431 0.490196 0.498039 0.498039 0.498039 0.498039 0.501961 0.509804 0.509804 0.513725 0.505882 0.521569 0.509804 0.501961 0.505882 0.517647 0.501961 0.490196 0.513725 0.505882 0.490196 0.501961 0.494118 0.494118 0.498039 0.47451 0.478431 0.486275 0.470588 0.462745 0.462745 0.462745 0.462745 0.447059 0.45098 0.439216 0.431373 0.443137 0.423529 0.419608 0.419608 0.396078 0.403922 0.396078 0.380392 0.384314 0.364706 0.360784 0.34902 0.333333 0.341176 0.317647 0.313725 0.294118 0.294118 0.278431 0.266667 0.258824 0.239216 0.227451 0.223529 0.2 0.192157 0.239216 0.215686 0.196078 0.14902 0.101961 0.0823529 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.121569 0.321569 0.45098 0.537255 0.458824 0.364706 0.270588 0.168627 0.0156863 0 0 0 0 0 0 0.0901961 0.172549 0.207843 0.254902 0.298039 0.32549 0.341176 0.368627 0.376471 0.396078 0.407843 0.415686 0.423529 0.443137 0.443137 0.443137 0.466667 0.466667 0.470588 0.466667 0.47451 0.482353 0.494118 0.494118 0.494118 0.501961 0.490196 0.501961 0.501961 0.509804 0.505882 0.494118 0.509804 0.498039 0.509804 0.501961 0.505882 0.498039 0.494118 0.486275 0.505882 0.482353 0.490196 0.486275 0.47451 0.470588 0.470588 0.470588 0.466667 0.45098 0.454902 0.447059 0.439216 0.431373 0.427451 0.427451 0.411765 0.407843 0.4 0.392157 0.380392 0.384314 0.364706 0.368627 0.360784 0.34902 0.356863 0.333333 0.321569 0.309804 0.305882 0.294118 0.286275 0.27451 0.258824 0.25098 0.239216 0.231373 0.215686 0.2 0.192157 0.239216 0.203922 0.184314 0.141176 0.0980392 0.0470588 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0941176 0.27451 0.411765 0.52549 0.541176 0.443137 0.32549 0.235294 0.0941176 0 0 0 0 0 0 0 0.0431373 0.137255 0.196078 0.243137 0.27451 0.301961 0.329412 0.352941 0.372549 0.392157 0.4 0.407843 0.415686 0.423529 0.435294 0.443137 0.454902 0.439216 0.458824 0.47451 0.458824 0.466667 0.478431 0.478431 0.494118 0.490196 0.501961 0.486275 0.486275 0.494118 0.486275 0.498039 0.494118 0.490196 0.494118 0.498039 0.494118 0.498039 0.490196 0.490196 0.482353 0.494118 0.490196 0.47451 0.470588 0.478431 0.462745 0.466667 0.454902 0.454902 0.45098 0.439216 0.427451 0.435294 0.419608 0.411765 0.403922 0.407843 0.396078 0.384314 0.380392 0.368627 0.368627 0.368627 0.34902 0.337255 0.313725 0.317647 0.309804 0.305882 0.290196 0.278431 0.27451 0.266667 0.258824 0.239216 0.235294 0.223529 0.203922 0.184314 0.180392 0.235294 0.196078 0.180392 0.12549 0.0862745 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0941176 0.258824 0.392157 0.490196 0.572549 0.517647 0.392157 0.278431 0.188235 0.0431373 0 0 0 0 0 0 0 0 0.109804 0.172549 0.211765 0.25098 0.278431 0.309804 0.341176 0.360784 0.364706 0.392157 0.396078 0.407843 0.411765 0.427451 0.435294 0.443137 0.454902 0.458824 0.458824 0.462745 0.470588 0.466667 0.478431 0.482353 0.482353 0.482353 0.486275 0.494118 0.486275 0.482353 0.482353 0.486275 0.490196 0.490196 0.486275 0.478431 0.478431 0.478431 0.466667 0.478431 0.470588 0.454902 0.466667 0.466667 0.462745 0.45098 0.45098 0.45098 0.439216 0.427451 0.439216 0.431373 0.423529 0.407843 0.423529 0.396078 0.396078 0.380392 0.372549 0.372549 0.360784 0.34902 0.34902 0.345098 0.321569 0.32549 0.309804 0.305882 0.298039 0.27451 0.270588 0.262745 0.266667 0.239216 0.235294 0.227451 0.215686 0.188235 0.184314 0.184314 0.227451 0.196078 0.172549 0.117647 0.0705882 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.129412 0.262745 0.392157 0.47451 0.564706 0.576471 0.443137 0.321569 0.227451 0.101961 0.00392157 0 0 0 0 0 0 0 0 0.054902 0.152941 0.196078 0.231373 0.266667 0.301961 0.329412 0.356863 0.360784 0.384314 0.388235 0.396078 0.407843 0.419608 0.419608 0.435294 0.447059 0.454902 0.443137 0.458824 0.466667 0.462745 0.470588 0.466667 0.47451 0.478431 0.47451 0.47451 0.478431 0.47451 0.47451 0.494118 0.482353 0.478431 0.478431 0.482353 0.478431 0.47451 0.47451 0.47451 0.466667 0.47451 0.458824 0.45098 0.458824 0.447059 0.439216 0.443137 0.439216 0.439216 0.419608 0.423529 0.419608 0.415686 0.407843 0.396078 0.392157 0.384314 0.384314 0.368627 0.356863 0.356863 0.352941 0.333333 0.32549 0.329412 0.305882 0.313725 0.294118 0.282353 0.266667 0.262745 0.247059 0.235294 0.227451 0.207843 0.196078 0.188235 0.164706 0.180392 0.219608 0.192157 0.164706 0.105882 0.0392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.196078 0.294118 0.392157 0.494118 0.584314 0.603922 0.501961 0.368627 0.25098 0.145098 0.0235294 0 0 0 0 0 0 0 0 0 0.00392157 0.121569 0.172549 0.211765 0.243137 0.286275 0.305882 0.329412 0.356863 0.360784 0.384314 0.392157 0.396078 0.403922 0.423529 0.427451 0.439216 0.439216 0.447059 0.435294 0.45098 0.458824 0.462745 0.470588 0.470588 0.466667 0.47451 0.47451 0.470588 0.478431 0.47451 0.478431 0.470588 0.47451 0.47451 0.462745 0.47451 0.470588 0.454902 0.462745 0.462745 0.458824 0.435294 0.447059 0.439216 0.439216 0.447059 0.427451 0.427451 0.427451 0.423529 0.415686 0.403922 0.4 0.392157 0.392157 0.384314 0.384314 0.372549 0.364706 0.352941 0.352941 0.337255 0.32549 0.32549 0.313725 0.294118 0.282353 0.286275 0.262745 0.258824 0.247059 0.239216 0.227451 0.215686 0.203922 0.188235 0.180392 0.160784 0.196078 0.215686 0.184314 0.168627 0.0862745 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.156863 0.239216 0.32549 0.427451 0.517647 0.580392 0.611765 0.52549 0.396078 0.266667 0.176471 0.0431373 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.156863 0.196078 0.235294 0.262745 0.294118 0.309804 0.341176 0.352941 0.368627 0.372549 0.388235 0.407843 0.407843 0.411765 0.427451 0.427451 0.45098 0.443137 0.45098 0.454902 0.454902 0.458824 0.470588 0.458824 0.47451 0.470588 0.462745 0.458824 0.478431 0.462745 0.462745 0.458824 0.458824 0.470588 0.458824 0.466667 0.462745 0.45098 0.454902 0.454902 0.439216 0.439216 0.45098 0.443137 0.419608 0.431373 0.423529 0.419608 0.419608 0.407843 0.403922 0.4 0.388235 0.384314 0.376471 0.388235 0.364706 0.34902 0.356863 0.341176 0.333333 0.321569 0.317647 0.301961 0.298039 0.294118 0.278431 0.254902 0.25098 0.243137 0.235294 0.223529 0.207843 0.192157 0.180392 0.164706 0.164706 0.207843 0.207843 0.180392 0.164706 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.156863 0.215686 0.294118 0.380392 0.470588 0.541176 0.611765 0.627451 0.54902 0.411765 0.278431 0.168627 0.0705882 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.121569 0.176471 0.207843 0.247059 0.278431 0.305882 0.32549 0.337255 0.352941 0.372549 0.384314 0.388235 0.396078 0.407843 0.411765 0.423529 0.431373 0.431373 0.439216 0.443137 0.45098 0.458824 0.45098 0.462745 0.454902 0.45098 0.462745 0.466667 0.462745 0.470588 0.458824 0.454902 0.462745 0.45098 0.458824 0.462745 0.45098 0.439216 0.439216 0.439216 0.435294 0.431373 0.431373 0.419608 0.423529 0.403922 0.415686 0.419608 0.4 0.388235 0.396078 0.376471 0.380392 0.380392 0.360784 0.34902 0.345098 0.345098 0.329412 0.32549 0.309804 0.298039 0.301961 0.290196 0.286275 0.27451 0.262745 0.247059 0.247059 0.227451 0.227451 0.2 0.196078 0.188235 0.168627 0.152941 0.156863 0.196078 0.196078 0.184314 0.121569 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.0901961 0.184314 0.231373 0.290196 0.368627 0.443137 0.517647 0.592157 0.643137 0.623529 0.533333 0.396078 0.266667 0.168627 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.156863 0.192157 0.227451 0.258824 0.282353 0.305882 0.329412 0.34902 0.356863 0.364706 0.380392 0.388235 0.396078 0.403922 0.4 0.415686 0.423529 0.431373 0.431373 0.439216 0.447059 0.439216 0.45098 0.454902 0.454902 0.458824 0.454902 0.45098 0.466667 0.45098 0.439216 0.45098 0.439216 0.45098 0.439216 0.443137 0.443137 0.447059 0.435294 0.423529 0.435294 0.435294 0.419608 0.407843 0.396078 0.396078 0.4 0.384314 0.388235 0.388235 0.368627 0.372549 0.364706 0.34902 0.34902 0.341176 0.341176 0.32549 0.313725 0.305882 0.290196 0.298039 0.282353 0.270588 0.270588 0.247059 0.231373 0.231373 0.227451 0.215686 0.2 0.184314 0.176471 0.160784 0.152941 0.152941 0.2 0.196078 0.172549 0.0745098 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.101961 0.168627 0.215686 0.266667 0.317647 0.380392 0.454902 0.509804 0.584314 0.627451 0.654902 0.611765 0.505882 0.372549 0.239216 0.152941 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.12549 0.176471 0.207843 0.247059 0.27451 0.298039 0.321569 0.341176 0.352941 0.372549 0.368627 0.380392 0.388235 0.396078 0.403922 0.415686 0.411765 0.427451 0.431373 0.435294 0.443137 0.439216 0.443137 0.439216 0.427451 0.439216 0.443137 0.447059 0.439216 0.439216 0.454902 0.439216 0.435294 0.439216 0.447059 0.431373 0.423529 0.431373 0.443137 0.423529 0.427451 0.415686 0.4 0.407843 0.4 0.392157 0.396078 0.384314 0.380392 0.376471 0.360784 0.352941 0.352941 0.34902 0.356863 0.333333 0.321569 0.321569 0.298039 0.301961 0.294118 0.290196 0.27451 0.258824 0.247059 0.247059 0.235294 0.223529 0.215686 0.2 0.192157 0.180392 0.176471 0.164706 0.137255 0.14902 0.211765 0.196078 0.145098 0.00392157 0 0 0 0 0 0 0 0 0 0 0.00784314 0.0980392 0.164706 0.196078 0.235294 0.270588 0.309804 0.360784 0.403922 0.470588 0.533333 0.584314 0.639216 0.670588 0.631373 0.564706 0.431373 0.313725 0.2 0.121569 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0784314 0.14902 0.184314 0.211765 0.258824 0.27451 0.305882 0.317647 0.341176 0.352941 0.360784 0.372549 0.392157 0.396078 0.403922 0.396078 0.396078 0.423529 0.411765 0.407843 0.423529 0.423529 0.423529 0.427451 0.435294 0.435294 0.427451 0.435294 0.439216 0.435294 0.419608 0.427451 0.427451 0.423529 0.427451 0.423529 0.431373 0.423529 0.423529 0.415686 0.415686 0.403922 0.403922 0.403922 0.396078 0.388235 0.392157 0.376471 0.376471 0.368627 0.34902 0.356863 0.345098 0.337255 0.333333 0.329412 0.317647 0.313725 0.294118 0.294118 0.282353 0.270588 0.258824 0.254902 0.254902 0.227451 0.211765 0.219608 0.203922 0.196078 0.188235 0.180392 0.164706 0.14902 0.133333 0.152941 0.211765 0.192157 0.113725 0 0 0 0 0 0.0117647 0.0235294 0.0823529 0.14902 0.188235 0.203922 0.235294 0.258824 0.290196 0.313725 0.356863 0.4 0.439216 0.501961 0.537255 0.607843 0.658824 0.694118 0.647059 0.580392 0.470588 0.356863 0.243137 0.168627 0.0823529 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.121569 0.168627 0.2 0.235294 0.254902 0.286275 0.305882 0.321569 0.333333 0.360784 0.360784 0.372549 0.380392 0.384314 0.396078 0.403922 0.4 0.4 0.411765 0.423529 0.415686 0.415686 0.419608 0.419608 0.435294 0.427451 0.423529 0.427451 0.427451 0.427451 0.423529 0.427451 0.423529 0.431373 0.419608 0.419608 0.411765 0.415686 0.411765 0.403922 0.396078 0.396078 0.388235 0.388235 0.392157 0.372549 0.368627 0.364706 0.356863 0.341176 0.341176 0.333333 0.333333 0.337255 0.317647 0.305882 0.298039 0.298039 0.282353 0.27451 0.262745 0.258824 0.247059 0.235294 0.235294 0.207843 0.207843 0.2 0.184314 0.180392 0.160784 0.14902 0.141176 0.117647 0.156863 0.219608 0.176471 0.12549 0.0627451 0.0431373 0.0627451 0.109804 0.164706 0.196078 0.231373 0.231373 0.266667 0.305882 0.321569 0.34902 0.380392 0.407843 0.447059 0.494118 0.537255 0.580392 0.635294 0.85098 0.807843 0.65098 0.576471 0.47451 0.364706 0.254902 0.172549 0.105882 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.145098 0.188235 0.207843 0.247059 0.270588 0.294118 0.309804 0.317647 0.345098 0.352941 0.368627 0.356863 0.364706 0.396078 0.396078 0.4 0.396078 0.407843 0.415686 0.411765 0.419608 0.419608 0.415686 0.419608 0.415686 0.419608 0.419608 0.415686 0.415686 0.431373 0.407843 0.415686 0.411765 0.419608 0.407843 0.407843 0.415686 0.4 0.396078 0.392157 0.396078 0.388235 0.380392 0.364706 0.372549 0.364706 0.360784 0.352941 0.341176 0.341176 0.333333 0.321569 0.321569 0.309804 0.294118 0.286275 0.282353 0.270588 0.266667 0.262745 0.258824 0.243137 0.231373 0.223529 0.211765 0.2 0.184314 0.188235 0.168627 0.156863 0.14902 0.129412 0.121569 0.164706 0.215686 0.172549 0.156863 0.12549 0.133333 0.172549 0.219608 0.270588 0.301961 0.317647 0.356863 0.392157 0.419608 0.435294 0.47451 0.509804 0.54902 0.576471 0.607843 0.784314 0.847059 0.670588 0.596078 0.517647 0.415686 0.321569 0.231373 0.152941 0.101961 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.113725 0.164706 0.196078 0.227451 0.247059 0.27451 0.294118 0.309804 0.333333 0.337255 0.356863 0.356863 0.360784 0.376471 0.376471 0.384314 0.396078 0.4 0.392157 0.396078 0.4 0.415686 0.411765 0.407843 0.415686 0.411765 0.407843 0.411765 0.419608 0.415686 0.411765 0.407843 0.411765 0.4 0.403922 0.396078 0.392157 0.403922 0.392157 0.380392 0.384314 0.380392 0.376471 0.360784 0.360784 0.352941 0.345098 0.34902 0.329412 0.341176 0.317647 0.313725 0.309804 0.294118 0.290196 0.290196 0.270588 0.266667 0.258824 0.247059 0.247059 0.231373 0.215686 0.203922 0.196078 0.184314 0.176471 0.168627 0.152941 0.141176 0.137255 0.121569 0.105882 0.211765 0.247059 0.192157 0.239216 0.239216 0.27451 0.32549 0.368627 0.396078 0.419608 0.454902 0.482353 0.509804 0.541176 0.556863 0.6 0.631373 0.701961 0.721569 0.6 0.552941 0.482353 0.411765 0.32549 0.247059 0.176471 0.121569 0.0627451 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0823529 0.145098 0.184314 0.207843 0.235294 0.258824 0.282353 0.298039 0.301961 0.333333 0.337255 0.352941 0.360784 0.360784 0.376471 0.388235 0.380392 0.388235 0.396078 0.396078 0.4 0.396078 0.403922 0.407843 0.407843 0.411765 0.415686 0.4 0.415686 0.407843 0.4 0.411765 0.396078 0.4 0.4 0.4 0.4 0.388235 0.380392 0.384314 0.380392 0.364706 0.372549 0.360784 0.360784 0.34902 0.341176 0.337255 0.32549 0.321569 0.313725 0.309804 0.309804 0.290196 0.286275 0.278431 0.266667 0.262745 0.25098 0.239216 0.227451 0.227451 0.215686 0.203922 0.196078 0.180392 0.168627 0.156863 0.152941 0.133333 0.12549 0.109804 0.101961 0.192157 0.180392 0.254902 0.309804 0.368627 0.411765 0.462745 0.490196 0.52549 0.545098 0.556863 0.584314 0.615686 0.623529 0.627451 0.6 0.533333 0.494118 0.431373 0.368627 0.290196 0.223529 0.172549 0.121569 0.0666667 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.113725 0.160784 0.192157 0.223529 0.247059 0.254902 0.282353 0.301961 0.313725 0.333333 0.329412 0.352941 0.360784 0.360784 0.372549 0.384314 0.384314 0.380392 0.392157 0.392157 0.396078 0.396078 0.396078 0.396078 0.411765 0.396078 0.388235 0.4 0.396078 0.388235 0.396078 0.403922 0.384314 0.388235 0.384314 0.396078 0.384314 0.376471 0.360784 0.368627 0.368627 0.364706 0.34902 0.352941 0.337255 0.333333 0.32549 0.329412 0.329412 0.309804 0.298039 0.294118 0.282353 0.27451 0.262745 0.258824 0.25098 0.243137 0.235294 0.231373 0.211765 0.207843 0.196078 0.184314 0.176471 0.156863 0.152941 0.145098 0.121569 0.113725 0.0941176 0.113725 0.160784 0.196078 0.345098 0.470588 0.478431 0.517647 0.560784 0.580392 0.580392 0.560784 0.541176 0.52549 0.482353 0.454902 0.403922 0.352941 0.301961 0.239216 0.196078 0.14902 0.109804 0.0666667 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0705882 0.141176 0.172549 0.203922 0.231373 0.25098 0.262745 0.286275 0.305882 0.317647 0.321569 0.333333 0.345098 0.356863 0.360784 0.364706 0.368627 0.376471 0.376471 0.392157 0.392157 0.380392 0.380392 0.396078 0.396078 0.396078 0.392157 0.392157 0.380392 0.392157 0.380392 0.376471 0.392157 0.380392 0.368627 0.392157 0.368627 0.356863 0.352941 0.356863 0.352941 0.341176 0.34902 0.337255 0.333333 0.329412 0.317647 0.309804 0.305882 0.298039 0.286275 0.278431 0.266667 0.27451 0.258824 0.25098 0.243137 0.227451 0.215686 0.215686 0.207843 0.196078 0.184314 0.176471 0.168627 0.145098 0.141176 0.133333 0.109804 0.0901961 0.0941176 0.113725 0.137255 0.231373 0.341176 0.423529 0.466667 0.470588 0.466667 0.443137 0.403922 0.380392 0.337255 0.309804 0.258824 0.219608 0.188235 0.145098 0.105882 0.0745098 0.0392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.105882 0.14902 0.184314 0.215686 0.239216 0.266667 0.282353 0.294118 0.305882 0.32549 0.321569 0.337255 0.345098 0.352941 0.34902 0.364706 0.364706 0.368627 0.384314 0.376471 0.376471 0.380392 0.384314 0.392157 0.376471 0.388235 0.388235 0.384314 0.384314 0.364706 0.376471 0.380392 0.368627 0.372549 0.368627 0.352941 0.364706 0.352941 0.34902 0.34902 0.341176 0.333333 0.341176 0.32549 0.32549 0.309804 0.301961 0.294118 0.286275 0.282353 0.27451 0.262745 0.262745 0.25098 0.243137 0.235294 0.227451 0.215686 0.211765 0.196078 0.184314 0.172549 0.164706 0.160784 0.145098 0.133333 0.117647 0.105882 0.0941176 0.0705882 0.0901961 0.141176 0.223529 0.266667 0.298039 0.298039 0.282353 0.254902 0.223529 0.196078 0.168627 0.145098 0.117647 0.0901961 0.054902 0.0235294 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.12549 0.164706 0.196078 0.227451 0.247059 0.262745 0.278431 0.290196 0.305882 0.305882 0.329412 0.32549 0.341176 0.341176 0.356863 0.356863 0.368627 0.368627 0.360784 0.364706 0.372549 0.364706 0.372549 0.372549 0.384314 0.376471 0.380392 0.380392 0.372549 0.364706 0.364706 0.372549 0.352941 0.368627 0.360784 0.34902 0.352941 0.333333 0.341176 0.329412 0.333333 0.313725 0.309804 0.309804 0.298039 0.294118 0.286275 0.282353 0.27451 0.270588 0.254902 0.254902 0.243137 0.231373 0.207843 0.211765 0.207843 0.196078 0.192157 0.176471 0.164706 0.156863 0.14902 0.133333 0.12549 0.113725 0.0941176 0.0745098 0.0470588 0.0862745 0.12549 0.14902 0.141176 0.137255 0.12549 0.113725 0.0980392 0.0705882 0.0509804 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.141176 0.172549 0.196078 0.223529 0.25098 0.262745 0.278431 0.294118 0.301961 0.321569 0.321569 0.337255 0.341176 0.341176 0.352941 0.345098 0.364706 0.368627 0.356863 0.364706 0.364706 0.376471 0.368627 0.368627 0.368627 0.364706 0.372549 0.360784 0.360784 0.364706 0.352941 0.364706 0.352941 0.34902 0.341176 0.345098 0.32549 0.341176 0.32549 0.313725 0.313725 0.309804 0.294118 0.301961 0.282353 0.266667 0.262745 0.258824 0.262745 0.243137 0.243137 0.235294 0.215686 0.215686 0.196078 0.196078 0.192157 0.168627 0.176471 0.156863 0.14902 0.141176 0.121569 0.113725 0.0980392 0.0745098 0.0509804 0.0352941 0.0705882 0.0745098 0.0470588 0.0431373 0.027451 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.101961 0.145098 0.180392 0.211765 0.231373 0.25098 0.266667 0.282353 0.294118 0.298039 0.313725 0.32549 0.32549 0.341176 0.34902 0.345098 0.364706 0.356863 0.356863 0.368627 0.368627 0.356863 0.364706 0.364706 0.360784 0.352941 0.356863 0.356863 0.360784 0.360784 0.352941 0.34902 0.34902 0.333333 0.341176 0.337255 0.329412 0.321569 0.321569 0.317647 0.309804 0.290196 0.305882 0.286275 0.266667 0.278431 0.266667 0.25098 0.266667 0.243137 0.227451 0.223529 0.215686 0.207843 0.196078 0.188235 0.176471 0.172549 0.164706 0.14902 0.141176 0.12549 0.117647 0.105882 0.0862745 0.0627451 0.027451 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0431373 0.109804 0.152941 0.180392 0.219608 0.223529 0.247059 0.270588 0.286275 0.294118 0.305882 0.309804 0.32549 0.329412 0.333333 0.337255 0.345098 0.356863 0.341176 0.34902 0.34902 0.356863 0.356863 0.352941 0.356863 0.34902 0.360784 0.352941 0.352941 0.34902 0.345098 0.333333 0.345098 0.341176 0.32549 0.329412 0.321569 0.317647 0.313725 0.305882 0.298039 0.294118 0.294118 0.282353 0.270588 0.262745 0.25098 0.247059 0.239216 0.231373 0.227451 0.211765 0.211765 0.2 0.192157 0.180392 0.176471 0.160784 0.14902 0.141176 0.137255 0.117647 0.0980392 0.0941176 0.0705882 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.121569 0.164706 0.188235 0.215686 0.243137 0.258824 0.266667 0.270588 0.294118 0.298039 0.301961 0.321569 0.32549 0.337255 0.329412 0.345098 0.34902 0.341176 0.337255 0.352941 0.34902 0.34902 0.345098 0.34902 0.34902 0.341176 0.341176 0.352941 0.333333 0.329412 0.333333 0.333333 0.32549 0.32549 0.317647 0.317647 0.301961 0.301961 0.298039 0.290196 0.27451 0.270588 0.254902 0.25098 0.25098 0.235294 0.239216 0.219608 0.215686 0.211765 0.2 0.192157 0.188235 0.188235 0.164706 0.152941 0.141176 0.141176 0.129412 0.109804 0.101961 0.0705882 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.121569 0.156863 0.192157 0.219608 0.239216 0.254902 0.266667 0.282353 0.298039 0.298039 0.313725 0.317647 0.317647 0.329412 0.321569 0.32549 0.341176 0.333333 0.337255 0.337255 0.337255 0.337255 0.337255 0.337255 0.341176 0.32549 0.329412 0.345098 0.333333 0.321569 0.321569 0.317647 0.317647 0.305882 0.301961 0.298039 0.286275 0.282353 0.278431 0.27451 0.262745 0.262745 0.25098 0.239216 0.235294 0.223529 0.215686 0.203922 0.188235 0.188235 0.188235 0.180392 0.160784 0.152941 0.14902 0.141176 0.12549 0.113725 0.0862745 0.0705882 0.0470588 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.0588235 0.0980392 0.141176 0.176471 0.2 0.235294 0.247059 0.262745 0.27451 0.278431 0.290196 0.305882 0.301961 0.317647 0.321569 0.317647 0.333333 0.32549 0.329412 0.333333 0.333333 0.32549 0.337255 0.321569 0.317647 0.32549 0.329412 0.313725 0.313725 0.321569 0.313725 0.309804 0.301961 0.298039 0.294118 0.286275 0.278431 0.266667 0.266667 0.254902 0.25098 0.243137 0.239216 0.227451 0.223529 0.219608 0.203922 0.207843 0.192157 0.188235 0.176471 0.176471 0.152941 0.14902 0.133333 0.121569 0.109804 0.0862745 0.0705882 0.0352941 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.0901961 0.0980392 0.12549 0.168627 0.211765 0.211765 0.231373 0.262745 0.258824 0.27451 0.282353 0.290196 0.301961 0.309804 0.313725 0.309804 0.321569 0.32549 0.317647 0.321569 0.32549 0.317647 0.313725 0.321569 0.32549 0.317647 0.317647 0.298039 0.309804 0.298039 0.294118 0.301961 0.286275 0.27451 0.282353 0.270588 0.262745 0.254902 0.247059 0.239216 0.231373 0.231373 0.223529 0.219608 0.203922 0.2 0.188235 0.188235 0.172549 0.164706 0.14902 0.137255 0.129412 0.12549 0.0980392 0.0901961 0.0666667 0.027451 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.0901961 0.129412 0.109804 0.145098 0.172549 0.196078 0.211765 0.235294 0.247059 0.262745 0.270588 0.290196 0.298039 0.298039 0.298039 0.309804 0.301961 0.313725 0.305882 0.305882 0.329412 0.305882 0.317647 0.301961 0.301961 0.305882 0.298039 0.317647 0.294118 0.270588 0.286275 0.286275 0.270588 0.262745 0.262745 0.247059 0.247059 0.247059 0.235294 0.223529 0.231373 0.2 0.203922 0.2 0.180392 0.188235 0.164706 0.156863 0.145098 0.129412 0.117647 0.109804 0.0901961 0.0784314 0.054902 0.0588235 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.0862745 0.117647 0.156863 0.164706 0.145098 0.164706 0.188235 0.2 0.219608 0.227451 0.243137 0.247059 0.262745 0.278431 0.286275 0.290196 0.290196 0.286275 0.298039 0.294118 0.301961 0.294118 0.298039 0.286275 0.298039 0.286275 0.282353 0.270588 0.27451 0.270588 0.258824 0.258824 0.254902 0.239216 0.239216 0.235294 0.231373 0.219608 0.207843 0.2 0.196078 0.188235 0.172549 0.168627 0.152941 0.145098 0.129412 0.121569 0.113725 0.0941176 0.0862745 0.0823529 0.0745098 0.0509804 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.0901961 0.113725 0.141176 0.176471 0.196078 0.196078 0.184314 0.172549 0.188235 0.211765 0.207843 0.219608 0.243137 0.243137 0.25098 0.247059 0.262745 0.262745 0.258824 0.266667 0.278431 0.258824 0.262745 0.270588 0.258824 0.266667 0.25098 0.247059 0.239216 0.235294 0.239216 0.223529 0.219608 0.203922 0.207843 0.2 0.184314 0.192157 0.180392 0.176471 0.152941 0.164706 0.137255 0.133333 0.117647 0.101961 0.105882 0.113725 0.0980392 0.0823529 0.0627451 0.054902 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.113725 0.129412 0.152941 0.172549 0.2 0.215686 0.223529 0.211765 0.196078 0.196078 0.192157 0.2 0.196078 0.215686 0.219608 0.219608 0.227451 0.227451 0.223529 0.235294 0.231373 0.235294 0.223529 0.223529 0.223529 0.219608 0.203922 0.203922 0.196078 0.2 0.2 0.188235 0.180392 0.172549 0.168627 0.160784 0.145098 0.141176 0.129412 0.129412 0.12549 0.133333 0.141176 0.12549 0.121569 0.101961 0.0862745 0.0666667 0.0392157 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.0392157 0.109804 0.152941 0.172549 0.164706 0.176471 0.192157 0.207843 0.227451 0.243137 0.243137 0.243137 0.235294 0.219608 0.219608 0.207843 0.207843 0.196078 0.196078 0.196078 0.192157 0.188235 0.196078 0.172549 0.180392 0.172549 0.164706 0.172549 0.168627 0.168627 0.164706 0.168627 0.172549 0.164706 0.168627 0.176471 0.168627 0.160784 0.164706 0.137255 0.121569 0.109804 0.0980392 0.0901961 0.0823529 0.0509804 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.0588235 0.0470588 0.0862745 0.121569 0.168627 0.188235 0.196078 0.188235 0.196078 0.184314 0.196078 0.207843 0.219608 0.219608 0.239216 0.243137 0.243137 0.239216 0.247059 0.235294 0.239216 0.231373 0.235294 0.231373 0.219608 0.219608 0.207843 0.203922 0.196078 0.203922 0.184314 0.180392 0.164706 0.152941 0.145098 0.129412 0.137255 0.137255 0.14902 0.145098 0.113725 0.0862745 0.0509804 0.0313725 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0352941 0.168627 0.133333 0.0588235 0.0745098 0.0901961 0.105882 0.137255 0.164706 0.188235 0.207843 0.211765 0.207843 0.203922 0.207843 0.188235 0.196078 0.192157 0.192157 0.184314 0.188235 0.180392 0.192157 0.176471 0.172549 0.164706 0.164706 0.156863 0.164706 0.164706 0.14902 0.156863 0.145098 0.156863 0.141176 0.141176 0.160784 0.188235 0.180392 0.156863 0.113725 0.0666667 0.0588235 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.0588235 0.0627451 0.0588235 0.0470588 0.0588235 0.0666667 0.0862745 0.0941176 0.105882 0.117647 0.129412 0.14902 0.168627 0.176471 0.188235 0.192157 0.184314 0.180392 0.196078 0.180392 0.176471 0.172549 0.172549 0.164706 0.152941 0.137255 0.137255 0.121569 0.109804 0.0941176 0.0980392 0.145098 0.176471 0.196078 0.156863 0.133333 0.0980392 0.0980392 0.0431373 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.0392157 0.105882 0.0862745 0.0470588 0.054902 0.0666667 0.0705882 0.0784314 0.0862745 0.0862745 0.0941176 0.0941176 0.0980392 0.0941176 0.0980392 0.0901961 0.0980392 0.101961 0.0941176 0.0823529 0.0901961 0.0745098 0.0784314 0.0666667 0.0980392 0.129412 0.141176 0.117647 0.14902 0.129412 0.0588235 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.0784314 0.117647 0.105882 0.0980392 0.0862745 0.0745098 0.0627451 0.0509804 0.0509804 0.0588235 0.0509804 0.0627451 0.0588235 0.0431373 0.0666667 0.0627451 0.109804 0.141176 0.160784 0.14902 0.129412 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.0588235 0.101961 0.156863 0.2 0.235294 0.27451 0.301961 0.313725 0.317647 0.32549 0.313725 0.301961 0.270588 0.235294 0.188235 0.133333 0.0901961 0.0470588 0.027451 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.0784314 0.141176 0.243137 0.368627 0.47451 0.537255 0.576471 0.596078 0.623529 0.627451 0.639216 0.647059 0.654902 0.643137 0.662745 0.662745 0.666667 0.666667 0.654902 0.678431 0.713725 0.784314 0.772549 0.776471 0.772549 0.752941 0.694118 0.690196 0.682353 0.670588 0.658824 0.643137 0.627451 0.596078 0.545098 0.45098 0.321569 0.215686 0.137255 0.0666667 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.129412 0.262745 0.368627 0.494118 0.556863 0.584314 0.603922 0.611765 0.603922 0.619608 0.615686 0.607843 0.607843 0.611765 0.592157 0.588235 0.584314 0.572549 0.568627 0.560784 0.556863 0.54902 0.556863 0.556863 0.545098 0.560784 0.619608 0.807843 0.823529 0.819608 0.803922 0.764706 0.662745 0.662745 0.658824 0.65098 0.654902 0.662745 0.666667 0.67451 0.678431 0.678431 0.654902 0.65098 0.647059 0.631373 0.603922 0.533333 0.423529 0.309804 0.160784 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.231373 0.403922 0.494118 0.545098 0.564706 0.576471 0.584314 0.572549 0.560784 0.560784 0.560784 0.533333 0.509804 0.494118 0.458824 0.431373 0.423529 0.411765 0.388235 0.360784 0.345098 0.352941 0.356863 0.333333 0.329412 0.341176 0.32549 0.333333 0.341176 0.341176 0.372549 0.458824 0.454902 0.368627 0.368627 0.372549 0.380392 0.372549 0.4 0.423529 0.443137 0.454902 0.478431 0.513725 0.560784 0.631373 0.709804 0.882353 1 0.905882 0.717647 0.678431 0.690196 0.658824 0.643137 0.615686 0.552941 0.45098 0.243137 0.054902 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.117647 0.372549 0.490196 0.521569 0.54902 0.560784 0.54902 0.537255 0.533333 0.501961 0.486275 0.45098 0.415686 0.384314 0.368627 0.32549 0.294118 0.270588 0.270588 0.282353 0.282353 0.282353 0.278431 0.282353 0.282353 0.313725 0.301961 0.270588 0.278431 0.298039 0.270588 0.278431 0.329412 0.498039 0.647059 0.341176 0.329412 0.32549 0.294118 0.290196 0.294118 0.305882 0.290196 0.294118 0.298039 0.290196 0.294118 0.313725 0.32549 0.317647 0.345098 0.360784 0.384314 0.407843 0.447059 0.490196 0.52549 0.560784 0.592157 0.607843 0.631373 0.639216 0.627451 0.607843 0.564706 0.423529 0.180392 0.0666667 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.164706 0.372549 0.490196 0.501961 0.517647 0.529412 0.513725 0.490196 0.466667 0.423529 0.388235 0.34902 0.317647 0.298039 0.278431 0.262745 0.266667 0.258824 0.25098 0.227451 0.223529 0.247059 0.254902 0.258824 0.258824 0.262745 0.25098 0.266667 0.298039 0.294118 0.258824 0.290196 0.52549 0.258824 0.266667 0.321569 0.894118 0.988235 0.607843 0.341176 0.356863 0.313725 0.266667 0.27451 0.278431 0.258824 0.266667 0.266667 0.262745 0.278431 0.27451 0.286275 0.290196 0.305882 0.298039 0.309804 0.313725 0.32549 0.329412 0.333333 0.345098 0.380392 0.431373 0.462745 0.521569 0.568627 0.6 0.615686 0.611765 0.611765 0.576471 0.447059 0.25098 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.313725 0.45098 0.470588 0.478431 0.501961 0.490196 0.45098 0.423529 0.364706 0.321569 0.290196 0.254902 0.243137 0.231373 0.243137 0.231373 0.235294 0.239216 0.235294 0.235294 0.223529 0.219608 0.219608 0.231373 0.239216 0.239216 0.25098 0.235294 0.243137 0.247059 0.278431 0.298039 0.247059 0.243137 0.266667 0.25098 0.262745 0.337255 0.427451 0.521569 0.321569 0.278431 0.278431 0.278431 0.262745 0.258824 0.262745 0.243137 0.254902 0.254902 0.25098 0.270588 0.27451 0.27451 0.278431 0.27451 0.286275 0.282353 0.286275 0.294118 0.294118 0.286275 0.305882 0.298039 0.305882 0.317647 0.333333 0.372549 0.415686 0.454902 0.521569 0.560784 0.588235 0.603922 0.580392 0.556863 0.435294 0.172549 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.341176 0.447059 0.458824 0.439216 0.45098 0.435294 0.388235 0.337255 0.278431 0.239216 0.227451 0.219608 0.219608 0.211765 0.207843 0.207843 0.203922 0.223529 0.211765 0.223529 0.219608 0.223529 0.219608 0.203922 0.2 0.227451 0.235294 0.243137 0.231373 0.235294 0.223529 0.235294 0.270588 0.27451 0.235294 0.231373 0.247059 0.223529 0.258824 0.278431 0.317647 0.294118 0.282353 0.266667 0.25098 0.254902 0.266667 0.258824 0.254902 0.258824 0.243137 0.243137 0.239216 0.254902 0.258824 0.258824 0.262745 0.247059 0.247059 0.266667 0.266667 0.266667 0.286275 0.278431 0.282353 0.270588 0.278431 0.286275 0.27451 0.278431 0.282353 0.290196 0.317647 0.364706 0.423529 0.501961 0.545098 0.572549 0.564706 0.541176 0.498039 0.227451 0.0352941 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.27451 0.431373 0.423529 0.407843 0.4 0.380392 0.333333 0.27451 0.235294 0.211765 0.188235 0.196078 0.188235 0.188235 0.2 0.180392 0.196078 0.2 0.203922 0.2 0.2 0.211765 0.215686 0.215686 0.207843 0.196078 0.184314 0.2 0.231373 0.231373 0.235294 0.223529 0.219608 0.2 0.243137 0.270588 0.243137 0.239216 0.235294 0.235294 0.227451 0.262745 0.286275 0.286275 0.262745 0.25098 0.25098 0.258824 0.239216 0.247059 0.254902 0.25098 0.239216 0.243137 0.235294 0.243137 0.25098 0.247059 0.243137 0.223529 0.266667 0.270588 0.254902 0.266667 0.25098 0.266667 0.282353 0.25098 0.258824 0.27451 0.247059 0.25098 0.247059 0.270588 0.254902 0.27451 0.290196 0.317647 0.368627 0.45098 0.513725 0.541176 0.552941 0.533333 0.47451 0.207843 0.0196078 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.117647 0.388235 0.411765 0.380392 0.364706 0.341176 0.294118 0.247059 0.219608 0.2 0.180392 0.180392 0.172549 0.188235 0.164706 0.176471 0.192157 0.192157 0.2 0.196078 0.180392 0.2 0.2 0.215686 0.207843 0.215686 0.211765 0.188235 0.188235 0.203922 0.219608 0.235294 0.207843 0.207843 0.219608 0.219608 0.243137 0.258824 0.235294 0.223529 0.231373 0.231373 0.247059 0.25098 0.282353 0.266667 0.258824 0.247059 0.243137 0.25098 0.243137 0.243137 0.243137 0.235294 0.231373 0.235294 0.239216 0.235294 0.239216 0.231373 0.235294 0.223529 0.266667 0.266667 0.258824 0.25098 0.243137 0.266667 0.278431 0.247059 0.247059 0.243137 0.239216 0.243137 0.243137 0.235294 0.25098 0.243137 0.258824 0.25098 0.258824 0.278431 0.337255 0.427451 0.486275 0.517647 0.517647 0.505882 0.403922 0.105882 0.00392157 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.176471 0.407843 0.384314 0.345098 0.321569 0.278431 0.215686 0.188235 0.164706 0.160784 0.145098 0.156863 0.156863 0.14902 0.152941 0.172549 0.172549 0.168627 0.164706 0.180392 0.196078 0.188235 0.184314 0.192157 0.184314 0.188235 0.196078 0.196078 0.188235 0.188235 0.203922 0.215686 0.211765 0.207843 0.207843 0.211765 0.207843 0.227451 0.25098 0.223529 0.211765 0.219608 0.231373 0.231373 0.239216 0.254902 0.262745 0.262745 0.254902 0.235294 0.235294 0.243137 0.243137 0.247059 0.223529 0.235294 0.227451 0.231373 0.239216 0.215686 0.219608 0.231373 0.235294 0.25098 0.262745 0.243137 0.243137 0.247059 0.227451 0.243137 0.227451 0.239216 0.239216 0.243137 0.239216 0.266667 0.278431 0.266667 0.270588 0.25098 0.243137 0.243137 0.27451 0.254902 0.278431 0.317647 0.415686 0.470588 0.501961 0.498039 0.466667 0.215686 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14902 0.392157 0.360784 0.309804 0.286275 0.25098 0.176471 0.160784 0.145098 0.133333 0.145098 0.133333 0.137255 0.141176 0.145098 0.145098 0.160784 0.145098 0.156863 0.156863 0.160784 0.184314 0.192157 0.196078 0.192157 0.172549 0.176471 0.176471 0.180392 0.192157 0.188235 0.188235 0.184314 0.196078 0.192157 0.196078 0.203922 0.196078 0.2 0.203922 0.203922 0.203922 0.203922 0.215686 0.227451 0.215686 0.223529 0.223529 0.231373 0.231373 0.223529 0.227451 0.223529 0.215686 0.223529 0.223529 0.211765 0.227451 0.227451 0.227451 0.215686 0.223529 0.223529 0.219608 0.223529 0.231373 0.227451 0.223529 0.227451 0.219608 0.227451 0.219608 0.223529 0.207843 0.223529 0.227451 0.207843 0.227451 0.223529 0.231373 0.235294 0.223529 0.227451 0.231373 0.227451 0.239216 0.266667 0.282353 0.337255 0.419608 0.470588 0.482353 0.458824 0.286275 0.0392157 0.0156863 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.392157 0.345098 0.286275 0.262745 0.211765 0.152941 0.137255 0.145098 0.133333 0.12549 0.129412 0.137255 0.12549 0.145098 0.141176 0.14902 0.14902 0.14902 0.152941 0.145098 0.145098 0.156863 0.156863 0.176471 0.160784 0.164706 0.172549 0.164706 0.184314 0.176471 0.180392 0.180392 0.180392 0.188235 0.192157 0.180392 0.196078 0.2 0.192157 0.188235 0.192157 0.2 0.203922 0.2 0.2 0.2 0.211765 0.207843 0.207843 0.207843 0.219608 0.215686 0.207843 0.211765 0.223529 0.219608 0.211765 0.223529 0.215686 0.219608 0.223529 0.219608 0.219608 0.219608 0.215686 0.207843 0.211765 0.215686 0.211765 0.231373 0.219608 0.211765 0.215686 0.223529 0.223529 0.207843 0.215686 0.215686 0.215686 0.219608 0.223529 0.207843 0.219608 0.211765 0.211765 0.211765 0.227451 0.231373 0.247059 0.309804 0.388235 0.439216 0.470588 0.45098 0.278431 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.294118 0.368627 0.278431 0.262745 0.196078 0.141176 0.12549 0.129412 0.12549 0.12549 0.121569 0.129412 0.133333 0.141176 0.141176 0.133333 0.137255 0.141176 0.152941 0.156863 0.152941 0.152941 0.156863 0.160784 0.164706 0.172549 0.168627 0.172549 0.168627 0.180392 0.180392 0.176471 0.184314 0.180392 0.176471 0.2 0.180392 0.192157 0.180392 0.192157 0.192157 0.192157 0.2 0.219608 0.2 0.215686 0.211765 0.211765 0.223529 0.211765 0.219608 0.207843 0.207843 0.235294 0.211765 0.196078 0.211765 0.211765 0.223529 0.203922 0.207843 0.223529 0.215686 0.2 0.219608 0.219608 0.231373 0.219608 0.219608 0.231373 0.211765 0.215686 0.207843 0.219608 0.211765 0.215686 0.211765 0.211765 0.203922 0.207843 0.207843 0.211765 0.219608 0.203922 0.207843 0.196078 0.2 0.211765 0.223529 0.207843 0.207843 0.262745 0.384314 0.411765 0.427451 0.411765 0.219608 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.376471 0.329412 0.247059 0.203922 0.141176 0.117647 0.109804 0.113725 0.113725 0.117647 0.117647 0.121569 0.129412 0.133333 0.133333 0.137255 0.137255 0.14902 0.14902 0.152941 0.14902 0.152941 0.156863 0.156863 0.160784 0.168627 0.156863 0.156863 0.176471 0.172549 0.172549 0.172549 0.176471 0.184314 0.172549 0.192157 0.176471 0.192157 0.192157 0.196078 0.188235 0.2 0.192157 0.2 0.211765 0.2 0.211765 0.207843 0.211765 0.211765 0.219608 0.207843 0.211765 0.211765 0.203922 0.223529 0.215686 0.211765 0.211765 0.211765 0.207843 0.219608 0.211765 0.223529 0.215686 0.211765 0.207843 0.211765 0.223529 0.211765 0.211765 0.215686 0.207843 0.215686 0.215686 0.215686 0.2 0.219608 0.211765 0.203922 0.215686 0.2 0.196078 0.196078 0.2 0.2 0.192157 0.211765 0.2 0.207843 0.203922 0.2 0.258824 0.360784 0.380392 0.415686 0.34902 0.0666667 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.105882 0.407843 0.313725 0.215686 0.145098 0.113725 0.101961 0.105882 0.0980392 0.105882 0.0980392 0.117647 0.117647 0.12549 0.129412 0.12549 0.12549 0.145098 0.141176 0.145098 0.152941 0.152941 0.152941 0.141176 0.152941 0.156863 0.164706 0.160784 0.160784 0.164706 0.172549 0.172549 0.176471 0.184314 0.184314 0.184314 0.192157 0.176471 0.184314 0.2 0.184314 0.196078 0.192157 0.207843 0.2 0.207843 0.207843 0.211765 0.207843 0.219608 0.219608 0.215686 0.219608 0.211765 0.211765 0.211765 0.215686 0.219608 0.211765 0.196078 0.203922 0.215686 0.219608 0.207843 0.215686 0.215686 0.207843 0.215686 0.227451 0.219608 0.211765 0.215686 0.215686 0.196078 0.211765 0.211765 0.211765 0.207843 0.2 0.211765 0.207843 0.203922 0.207843 0.2 0.196078 0.188235 0.192157 0.2 0.196078 0.2 0.188235 0.180392 0.188235 0.2 0.270588 0.360784 0.376471 0.380392 0.160784 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.407843 0.345098 0.215686 0.121569 0.101961 0.105882 0.101961 0.0941176 0.0980392 0.0980392 0.109804 0.113725 0.113725 0.117647 0.12549 0.117647 0.133333 0.141176 0.137255 0.137255 0.141176 0.137255 0.152941 0.152941 0.156863 0.14902 0.160784 0.160784 0.156863 0.168627 0.172549 0.180392 0.180392 0.172549 0.180392 0.184314 0.184314 0.188235 0.184314 0.188235 0.184314 0.207843 0.196078 0.188235 0.196078 0.215686 0.2 0.211765 0.203922 0.207843 0.227451 0.211765 0.211765 0.215686 0.207843 0.207843 0.207843 0.207843 0.203922 0.215686 0.211765 0.223529 0.211765 0.211765 0.219608 0.207843 0.215686 0.211765 0.196078 0.2 0.196078 0.211765 0.211765 0.207843 0.211765 0.207843 0.196078 0.203922 0.203922 0.211765 0.207843 0.188235 0.203922 0.184314 0.203922 0.188235 0.180392 0.188235 0.180392 0.176471 0.176471 0.184314 0.176471 0.203922 0.321569 0.356863 0.388235 0.239216 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.117647 0.415686 0.403922 0.223529 0.109804 0.105882 0.0980392 0.0784314 0.0901961 0.0941176 0.0862745 0.0862745 0.109804 0.101961 0.105882 0.113725 0.121569 0.113725 0.129412 0.121569 0.145098 0.12549 0.14902 0.141176 0.145098 0.156863 0.152941 0.160784 0.164706 0.156863 0.160784 0.160784 0.164706 0.172549 0.164706 0.176471 0.176471 0.184314 0.180392 0.184314 0.196078 0.188235 0.196078 0.192157 0.196078 0.203922 0.196078 0.211765 0.196078 0.211765 0.203922 0.207843 0.196078 0.207843 0.211765 0.207843 0.2 0.215686 0.203922 0.211765 0.211765 0.223529 0.219608 0.215686 0.211765 0.203922 0.203922 0.203922 0.2 0.211765 0.207843 0.207843 0.223529 0.2 0.211765 0.2 0.192157 0.203922 0.180392 0.196078 0.2 0.184314 0.2 0.180392 0.188235 0.192157 0.180392 0.168627 0.176471 0.180392 0.172549 0.168627 0.172549 0.172549 0.184314 0.298039 0.352941 0.380392 0.231373 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.341176 0.482353 0.364706 0.160784 0.0980392 0.0901961 0.0901961 0.0862745 0.0941176 0.0941176 0.0901961 0.0980392 0.0901961 0.0980392 0.0980392 0.0941176 0.0901961 0.113725 0.109804 0.117647 0.129412 0.133333 0.117647 0.133333 0.141176 0.133333 0.137255 0.14902 0.152941 0.152941 0.152941 0.156863 0.160784 0.156863 0.168627 0.164706 0.168627 0.160784 0.172549 0.176471 0.176471 0.184314 0.180392 0.188235 0.180392 0.184314 0.180392 0.184314 0.196078 0.188235 0.184314 0.203922 0.192157 0.196078 0.192157 0.196078 0.2 0.2 0.192157 0.188235 0.2 0.196078 0.192157 0.196078 0.192157 0.203922 0.207843 0.2 0.192157 0.192157 0.188235 0.184314 0.188235 0.2 0.188235 0.184314 0.192157 0.192157 0.180392 0.188235 0.172549 0.176471 0.184314 0.168627 0.172549 0.172549 0.164706 0.176471 0.164706 0.164706 0.168627 0.152941 0.156863 0.164706 0.278431 0.34902 0.368627 0.219608 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.282353 0.454902 0.501961 0.356863 0.121569 0.0980392 0.0941176 0.0784314 0.0862745 0.0941176 0.0862745 0.0941176 0.101961 0.0862745 0.0941176 0.0941176 0.101961 0.0941176 0.109804 0.117647 0.113725 0.117647 0.133333 0.129412 0.137255 0.133333 0.137255 0.137255 0.137255 0.133333 0.141176 0.133333 0.164706 0.152941 0.152941 0.152941 0.160784 0.164706 0.160784 0.156863 0.164706 0.168627 0.176471 0.172549 0.172549 0.180392 0.176471 0.180392 0.192157 0.176471 0.196078 0.176471 0.188235 0.180392 0.192157 0.196078 0.188235 0.180392 0.196078 0.184314 0.192157 0.2 0.188235 0.188235 0.192157 0.196078 0.184314 0.172549 0.188235 0.192157 0.180392 0.188235 0.172549 0.188235 0.184314 0.180392 0.192157 0.172549 0.180392 0.180392 0.180392 0.172549 0.168627 0.180392 0.172549 0.168627 0.168627 0.172549 0.164706 0.164706 0.156863 0.164706 0.156863 0.188235 0.321569 0.407843 0.337255 0.168627 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0431373 0.231373 0.372549 0.498039 0.556863 0.392157 0.14902 0.105882 0.101961 0.0941176 0.0784314 0.0901961 0.0941176 0.0705882 0.0901961 0.0823529 0.0901961 0.0980392 0.101961 0.101961 0.113725 0.105882 0.113725 0.129412 0.117647 0.12549 0.129412 0.152941 0.141176 0.133333 0.14902 0.14902 0.14902 0.164706 0.156863 0.152941 0.160784 0.14902 0.168627 0.156863 0.172549 0.164706 0.156863 0.180392 0.176471 0.180392 0.176471 0.168627 0.172549 0.184314 0.188235 0.188235 0.180392 0.196078 0.188235 0.184314 0.196078 0.192157 0.192157 0.188235 0.184314 0.188235 0.192157 0.188235 0.192157 0.180392 0.180392 0.184314 0.180392 0.188235 0.176471 0.188235 0.184314 0.188235 0.176471 0.176471 0.168627 0.176471 0.176471 0.180392 0.180392 0.168627 0.180392 0.164706 0.164706 0.164706 0.168627 0.168627 0.156863 0.160784 0.160784 0.14902 0.14902 0.160784 0.298039 0.4 0.392157 0.270588 0.145098 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.196078 0.298039 0.407843 0.521569 0.596078 0.513725 0.262745 0.121569 0.109804 0.0980392 0.0862745 0.0901961 0.0862745 0.0901961 0.101961 0.0901961 0.105882 0.101961 0.101961 0.105882 0.113725 0.117647 0.117647 0.117647 0.12549 0.12549 0.133333 0.137255 0.133333 0.14902 0.152941 0.145098 0.156863 0.160784 0.160784 0.164706 0.14902 0.168627 0.160784 0.172549 0.164706 0.180392 0.176471 0.164706 0.164706 0.188235 0.188235 0.180392 0.172549 0.188235 0.188235 0.192157 0.188235 0.188235 0.192157 0.192157 0.184314 0.180392 0.184314 0.184314 0.172549 0.188235 0.184314 0.192157 0.184314 0.192157 0.180392 0.188235 0.184314 0.180392 0.184314 0.184314 0.192157 0.192157 0.188235 0.176471 0.184314 0.172549 0.172549 0.168627 0.176471 0.184314 0.160784 0.164706 0.160784 0.160784 0.156863 0.156863 0.14902 0.14902 0.152941 0.14902 0.290196 0.403922 0.4 0.321569 0.227451 0.129412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.160784 0.270588 0.345098 0.439216 0.552941 0.619608 0.615686 0.498039 0.247059 0.117647 0.117647 0.105882 0.0941176 0.0901961 0.0901961 0.0980392 0.105882 0.101961 0.101961 0.109804 0.109804 0.121569 0.121569 0.12549 0.133333 0.129412 0.129412 0.137255 0.137255 0.141176 0.145098 0.145098 0.145098 0.145098 0.152941 0.160784 0.152941 0.156863 0.172549 0.152941 0.168627 0.172549 0.160784 0.164706 0.176471 0.180392 0.160784 0.180392 0.188235 0.176471 0.184314 0.184314 0.184314 0.192157 0.176471 0.184314 0.192157 0.188235 0.188235 0.180392 0.192157 0.188235 0.188235 0.188235 0.180392 0.184314 0.192157 0.176471 0.192157 0.196078 0.192157 0.184314 0.192157 0.188235 0.176471 0.180392 0.172549 0.180392 0.172549 0.160784 0.160784 0.168627 0.176471 0.164706 0.172549 0.152941 0.141176 0.164706 0.145098 0.141176 0.215686 0.396078 0.454902 0.411765 0.345098 0.278431 0.196078 0.101961 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12549 0.235294 0.298039 0.380392 0.435294 0.509804 0.596078 0.654902 0.654902 0.556863 0.305882 0.156863 0.12549 0.117647 0.101961 0.0901961 0.0980392 0.101961 0.0980392 0.105882 0.0980392 0.109804 0.113725 0.121569 0.12549 0.12549 0.113725 0.133333 0.141176 0.133333 0.141176 0.145098 0.145098 0.156863 0.145098 0.164706 0.164706 0.168627 0.168627 0.168627 0.160784 0.168627 0.176471 0.180392 0.172549 0.168627 0.184314 0.188235 0.184314 0.184314 0.188235 0.188235 0.192157 0.203922 0.196078 0.188235 0.176471 0.188235 0.192157 0.196078 0.192157 0.184314 0.2 0.207843 0.192157 0.196078 0.188235 0.184314 0.188235 0.192157 0.184314 0.176471 0.184314 0.192157 0.180392 0.164706 0.180392 0.188235 0.164706 0.172549 0.168627 0.164706 0.172549 0.164706 0.168627 0.152941 0.14902 0.152941 0.2 0.388235 0.470588 0.470588 0.435294 0.384314 0.301961 0.25098 0.184314 0.0666667 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0980392 0.203922 0.282353 0.34902 0.403922 0.45098 0.498039 0.552941 0.615686 0.666667 0.701961 0.654902 0.482353 0.258824 0.168627 0.129412 0.113725 0.113725 0.109804 0.109804 0.109804 0.113725 0.117647 0.117647 0.12549 0.117647 0.141176 0.121569 0.137255 0.137255 0.141176 0.145098 0.152941 0.156863 0.152941 0.156863 0.160784 0.164706 0.164706 0.160784 0.168627 0.168627 0.176471 0.180392 0.168627 0.180392 0.184314 0.192157 0.180392 0.180392 0.203922 0.188235 0.188235 0.192157 0.176471 0.180392 0.196078 0.184314 0.196078 0.184314 0.192157 0.2 0.192157 0.192157 0.184314 0.180392 0.180392 0.184314 0.192157 0.184314 0.188235 0.188235 0.184314 0.180392 0.184314 0.180392 0.184314 0.168627 0.172549 0.172549 0.168627 0.172549 0.168627 0.160784 0.152941 0.188235 0.278431 0.435294 0.498039 0.498039 0.470588 0.415686 0.372549 0.341176 0.313725 0.270588 0.168627 0.0352941 0 0 0 0 0.00784314 0.0627451 0.184314 0.301961 0.337255 0.372549 0.388235 0.392157 0.407843 0.396078 0.372549 0.345098 0.301961 0.168627 0.0392157 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.192157 0.254902 0.305882 0.368627 0.419608 0.454902 0.486275 0.521569 0.564706 0.615686 0.662745 0.709804 0.72549 0.682353 0.541176 0.376471 0.207843 0.137255 0.129412 0.12549 0.117647 0.12549 0.117647 0.121569 0.129412 0.129412 0.133333 0.137255 0.14902 0.145098 0.14902 0.14902 0.156863 0.156863 0.160784 0.156863 0.164706 0.164706 0.172549 0.168627 0.172549 0.168627 0.172549 0.172549 0.172549 0.176471 0.176471 0.188235 0.184314 0.180392 0.2 0.192157 0.180392 0.188235 0.192157 0.192157 0.184314 0.188235 0.192157 0.184314 0.2 0.184314 0.196078 0.196078 0.2 0.196078 0.188235 0.180392 0.188235 0.176471 0.180392 0.176471 0.184314 0.184314 0.180392 0.176471 0.176471 0.176471 0.172549 0.172549 0.160784 0.188235 0.305882 0.435294 0.521569 0.541176 0.509804 0.47451 0.431373 0.384314 0.352941 0.352941 0.333333 0.301961 0.270588 0.188235 0.0705882 0 0 0.054902 0.207843 0.356863 0.407843 0.447059 0.478431 0.494118 0.505882 0.509804 0.513725 0.513725 0.509804 0.498039 0.482353 0.45098 0.411765 0.368627 0.286275 0.109804 0 0 0 0 0 0 0 0 0 0.0509804 0.184314 0.247059 0.305882 0.345098 0.396078 0.427451 0.462745 0.490196 0.501961 0.529412 0.584314 0.607843 0.662745 0.690196 0.729412 0.745098 0.733333 0.690196 0.580392 0.376471 0.207843 0.152941 0.152941 0.145098 0.137255 0.117647 0.137255 0.137255 0.14902 0.137255 0.141176 0.156863 0.145098 0.160784 0.156863 0.160784 0.168627 0.160784 0.164706 0.176471 0.164706 0.184314 0.168627 0.172549 0.192157 0.180392 0.176471 0.184314 0.180392 0.184314 0.176471 0.184314 0.192157 0.196078 0.196078 0.196078 0.192157 0.196078 0.2 0.2 0.192157 0.196078 0.184314 0.196078 0.196078 0.2 0.184314 0.188235 0.188235 0.176471 0.180392 0.180392 0.188235 0.2 0.184314 0.184314 0.172549 0.203922 0.301961 0.443137 0.529412 0.552941 0.564706 0.552941 0.501961 0.462745 0.419608 0.388235 0.368627 0.356863 0.333333 0.333333 0.305882 0.301961 0.278431 0.282353 0.294118 0.262745 0.305882 0.380392 0.478431 0.509804 0.533333 0.556863 0.576471 0.584314 0.596078 0.6 0.592157 0.588235 0.584314 0.572549 0.54902 0.533333 0.505882 0.478431 0.427451 0.364706 0.239216 0.027451 0 0 0 0 0 0 0 0.00392157 0.156863 0.231373 0.282353 0.321569 0.368627 0.396078 0.423529 0.458824 0.482353 0.498039 0.52549 0.552941 0.580392 0.615686 0.627451 0.670588 0.698039 0.733333 0.752941 0.764706 0.760784 0.741176 0.658824 0.533333 0.368627 0.258824 0.215686 0.172549 0.14902 0.145098 0.156863 0.14902 0.14902 0.160784 0.164706 0.160784 0.160784 0.164706 0.164706 0.176471 0.168627 0.180392 0.184314 0.188235 0.184314 0.180392 0.192157 0.188235 0.184314 0.196078 0.180392 0.184314 0.196078 0.196078 0.196078 0.192157 0.192157 0.196078 0.192157 0.180392 0.203922 0.188235 0.196078 0.192157 0.188235 0.192157 0.196078 0.188235 0.196078 0.184314 0.188235 0.207843 0.227451 0.309804 0.407843 0.529412 0.588235 0.6 0.619608 0.596078 0.572549 0.533333 0.486275 0.458824 0.427451 0.4 0.360784 0.341176 0.329412 0.298039 0.309804 0.337255 0.309804 0.286275 0.313725 0.368627 0.419608 0.4 0.427451 0.498039 0.564706 0.588235 0.615686 0.635294 0.647059 0.643137 0.647059 0.654902 0.654902 0.654902 0.639216 0.627451 0.623529 0.615686 0.572549 0.54902 0.513725 0.462745 0.396078 0.313725 0.109804 0.00784314 0 0 0 0 0 0 0.141176 0.227451 0.27451 0.321569 0.360784 0.376471 0.415686 0.423529 0.458824 0.482353 0.498039 0.517647 0.533333 0.556863 0.572549 0.596078 0.615686 0.627451 0.658824 0.698039 0.717647 0.72549 0.752941 0.780392 0.807843 0.823529 0.847059 0.831373 0.717647 0.6 0.505882 0.431373 0.360784 0.286275 0.239216 0.192157 0.180392 0.168627 0.168627 0.172549 0.176471 0.180392 0.188235 0.188235 0.180392 0.192157 0.2 0.192157 0.192157 0.192157 0.196078 0.2 0.196078 0.192157 0.196078 0.2 0.192157 0.188235 0.2 0.196078 0.196078 0.188235 0.196078 0.215686 0.254902 0.301961 0.364706 0.423529 0.490196 0.572549 0.611765 0.639216 0.658824 0.65098 0.635294 0.627451 0.592157 0.560784 0.533333 0.509804 0.478431 0.443137 0.423529 0.411765 0.380392 0.34902 0.333333 0.317647 0.286275 0.266667 0.254902 0.294118 0.286275 0.305882 0.337255 0.45098 0.47451 0.435294 0.486275 0.572549 0.627451 0.639216 0.654902 0.670588 0.666667 0.682353 0.701961 0.690196 0.690196 0.694118 0.694118 0.678431 0.65098 0.639216 0.623529 0.603922 0.568627 0.52549 0.47451 0.415686 0.32549 0.137255 0.0117647 0 0 0 0 0 0.101961 0.207843 0.262745 0.305882 0.34902 0.372549 0.396078 0.415686 0.439216 0.466667 0.486275 0.498039 0.52549 0.52549 0.541176 0.552941 0.560784 0.584314 0.588235 0.615686 0.615686 0.647059 0.670588 0.670588 0.690196 0.72549 0.737255 0.752941 0.756863 0.803922 0.815686 0.815686 0.839216 0.815686 0.823529 0.772549 0.772549 0.733333 0.717647 0.682353 0.639216 0.611765 0.584314 0.560784 0.52549 0.505882 0.486275 0.490196 0.458824 0.462745 0.47451 0.478431 0.498039 0.501961 0.537255 0.556863 0.568627 0.6 0.623529 0.647059 0.670588 0.682353 0.67451 0.701961 0.701961 0.698039 0.690196 0.666667 0.662745 0.65098 0.635294 0.623529 0.588235 0.568627 0.545098 0.517647 0.505882 0.47451 0.454902 0.427451 0.403922 0.392157 0.368627 0.364706 0.329412 0.313725 0.305882 0.290196 0.270588 0.239216 0.223529 0.266667 0.294118 0.333333 0.376471 0.498039 0.486275 0.486275 0.537255 0.603922 0.666667 0.811765 0.988235 0.945098 0.772549 0.752941 0.709804 0.67451 0.686275 0.690196 0.729412 0.992157 0.984314 0.705882 0.682353 0.682353 0.627451 0.584314 0.537255 0.490196 0.415686 0.317647 0.121569 0.00784314 0 0 0 0 0.0666667 0.180392 0.25098 0.290196 0.333333 0.360784 0.384314 0.411765 0.431373 0.45098 0.462745 0.478431 0.494118 0.501961 0.509804 0.52549 0.537255 0.545098 0.560784 0.580392 0.576471 0.588235 0.596078 0.615686 0.615686 0.643137 0.647059 0.631373 0.666667 0.658824 0.678431 0.682353 0.690196 0.701961 0.709804 0.72549 0.721569 0.741176 0.74902 0.756863 0.764706 0.780392 0.8 0.847059 0.921569 0.972549 0.976471 0.980392 0.862745 0.803922 0.8 0.780392 0.756863 0.760784 0.745098 0.741176 0.733333 0.721569 0.729412 0.698039 0.690196 0.670588 0.666667 0.654902 0.635294 0.643137 0.6 0.572549 0.552941 0.541176 0.533333 0.517647 0.505882 0.490196 0.478431 0.462745 0.447059 0.427451 0.407843 0.384314 0.380392 0.356863 0.356863 0.337255 0.321569 0.290196 0.294118 0.278431 0.25098 0.215686 0.211765 0.266667 0.294118 0.305882 0.439216 0.556863 0.517647 0.513725 0.556863 0.611765 0.647059 0.631373 0.615686 0.592157 0.568627 0.529412 0.517647 0.509804 0.509804 0.537255 0.572549 0.619608 0.635294 0.717647 0.670588 0.654902 0.635294 0.596078 0.560784 0.533333 0.466667 0.388235 0.286275 0.0627451 0.00784314 0 0 0 0.0313725 0.160784 0.239216 0.278431 0.317647 0.364706 0.380392 0.407843 0.427451 0.443137 0.462745 0.466667 0.47451 0.490196 0.462745 0.494118 0.521569 0.529412 0.541176 0.560784 0.552941 0.576471 0.576471 0.592157 0.592157 0.603922 0.611765 0.611765 0.615686 0.611765 0.631373 0.619608 0.643137 0.639216 0.647059 0.635294 0.635294 0.65098 0.643137 0.658824 0.654902 0.65098 0.639216 0.647059 0.666667 0.662745 0.658824 0.670588 0.658824 0.65098 0.654902 0.647059 0.639216 0.627451 0.635294 0.639216 0.623529 0.607843 0.588235 0.6 0.588235 0.572549 0.560784 0.54902 0.552941 0.537255 0.517647 0.505882 0.501961 0.494118 0.486275 0.47451 0.478431 0.454902 0.435294 0.435294 0.403922 0.388235 0.372549 0.356863 0.345098 0.329412 0.313725 0.309804 0.278431 0.27451 0.286275 0.25098 0.239216 0.215686 0.192157 0.258824 0.286275 0.321569 0.486275 0.662745 0.521569 0.521569 0.572549 0.588235 0.564706 0.521569 0.447059 0.345098 0.258824 0.172549 0.133333 0.105882 0.117647 0.164706 0.239216 0.286275 0.439216 0.533333 0.611765 0.639216 0.623529 0.615686 0.588235 0.560784 0.509804 0.454902 0.352941 0.203922 0.0196078 0 0 0 0.00784314 0.141176 0.219608 0.266667 0.309804 0.352941 0.372549 0.403922 0.419608 0.439216 0.45098 0.466667 0.478431 0.486275 0.47451 0.494118 0.498039 0.509804 0.52549 0.52549 0.54902 0.541176 0.552941 0.560784 0.568627 0.576471 0.572549 0.588235 0.588235 0.592157 0.592157 0.592157 0.6 0.607843 0.6 0.615686 0.607843 0.615686 0.615686 0.596078 0.592157 0.603922 0.619608 0.603922 0.603922 0.619608 0.607843 0.603922 0.603922 0.6 0.588235 0.6 0.576471 0.576471 0.580392 0.580392 0.572549 0.564706 0.545098 0.552941 0.537255 0.533333 0.521569 0.521569 0.494118 0.494118 0.498039 0.478431 0.470588 0.454902 0.454902 0.439216 0.45098 0.435294 0.407843 0.388235 0.388235 0.360784 0.352941 0.341176 0.329412 0.305882 0.298039 0.290196 0.270588 0.270588 0.27451 0.254902 0.235294 0.207843 0.192157 0.247059 0.270588 0.364706 0.501961 0.529412 0.513725 0.529412 0.509804 0.462745 0.364706 0.215686 0.0862745 0.027451 0 0 0 0 0 0 0 0 0.0470588 0.270588 0.443137 0.52549 0.811765 0.588235 0.596078 0.592157 0.537255 0.478431 0.411765 0.286275 0.0823529 0.0117647 0 0 0 0.105882 0.192157 0.247059 0.286275 0.333333 0.368627 0.392157 0.411765 0.419608 0.45098 0.470588 0.466667 0.482353 0.498039 0.498039 0.498039 0.501961 0.521569 0.517647 0.517647 0.541176 0.533333 0.533333 0.552941 0.54902 0.54902 0.568627 0.572549 0.572549 0.580392 0.588235 0.580392 0.580392 0.6 0.592157 0.588235 0.592157 0.596078 0.580392 0.592157 0.592157 0.592157 0.580392 0.592157 0.6 0.615686 0.635294 0.623529 0.588235 0.568627 0.54902 0.556863 0.556863 0.560784 0.545098 0.521569 0.529412 0.517647 0.509804 0.505882 0.509804 0.494118 0.490196 0.470588 0.466667 0.470588 0.458824 0.447059 0.431373 0.439216 0.411765 0.411765 0.392157 0.380392 0.380392 0.356863 0.352941 0.337255 0.313725 0.301961 0.301961 0.282353 0.282353 0.270588 0.278431 0.270588 0.25098 0.235294 0.2 0.184314 0.239216 0.27451 0.392157 0.498039 0.498039 0.498039 0.47451 0.376471 0.219608 0.0745098 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0.0980392 0.360784 0.513725 0.666667 0.580392 0.572549 0.541176 0.494118 0.45098 0.345098 0.176471 0.0156863 0 0 0 0.0705882 0.184314 0.235294 0.290196 0.32549 0.356863 0.380392 0.407843 0.419608 0.435294 0.45098 0.458824 0.478431 0.490196 0.498039 0.494118 0.498039 0.501961 0.521569 0.529412 0.52549 0.52549 0.541176 0.537255 0.545098 0.541176 0.545098 0.54902 0.545098 0.552941 0.560784 0.556863 0.556863 0.568627 0.568627 0.572549 0.564706 0.568627 0.568627 0.568627 0.572549 0.564706 0.560784 0.572549 0.572549 0.584314 0.596078 0.588235 0.576471 0.52549 0.545098 0.541176 0.529412 0.52549 0.52549 0.513725 0.513725 0.501961 0.494118 0.494118 0.486275 0.47451 0.466667 0.462745 0.447059 0.45098 0.439216 0.419608 0.419608 0.407843 0.403922 0.392157 0.372549 0.364706 0.34902 0.345098 0.341176 0.329412 0.309804 0.309804 0.298039 0.278431 0.286275 0.266667 0.290196 0.266667 0.239216 0.231373 0.196078 0.176471 0.227451 0.286275 0.4 0.470588 0.478431 0.443137 0.329412 0.156863 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.352941 0.501961 0.564706 0.576471 0.54902 0.509804 0.454902 0.384314 0.223529 0.0392157 0 0 0 0.0392157 0.156863 0.223529 0.262745 0.309804 0.337255 0.376471 0.392157 0.411765 0.435294 0.439216 0.458824 0.47451 0.482353 0.498039 0.494118 0.498039 0.517647 0.517647 0.517647 0.529412 0.52549 0.537255 0.533333 0.537255 0.54902 0.529412 0.541176 0.54902 0.54902 0.541176 0.541176 0.54902 0.552941 0.54902 0.54902 0.54902 0.556863 0.541176 0.545098 0.556863 0.541176 0.541176 0.545098 0.529412 0.533333 0.545098 0.533333 0.529412 0.521569 0.517647 0.509804 0.509804 0.501961 0.505882 0.505882 0.501961 0.482353 0.486275 0.47451 0.458824 0.466667 0.454902 0.435294 0.435294 0.431373 0.415686 0.411765 0.403922 0.376471 0.376471 0.384314 0.368627 0.352941 0.352941 0.341176 0.329412 0.32549 0.309804 0.309804 0.290196 0.278431 0.266667 0.25098 0.278431 0.27451 0.247059 0.215686 0.188235 0.168627 0.231373 0.282353 0.392157 0.443137 0.411765 0.298039 0.137255 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0705882 0.392157 0.513725 0.560784 0.537255 0.513725 0.462745 0.411765 0.290196 0.0901961 0 0 0 0 0.129412 0.2 0.254902 0.298039 0.337255 0.364706 0.388235 0.411765 0.427451 0.435294 0.45098 0.458824 0.47451 0.490196 0.482353 0.494118 0.505882 0.517647 0.513725 0.513725 0.533333 0.529412 0.537255 0.545098 0.521569 0.541176 0.54902 0.537255 0.533333 0.545098 0.537255 0.541176 0.537255 0.54902 0.552941 0.545098 0.537255 0.545098 0.52549 0.54902 0.529412 0.52549 0.533333 0.517647 0.533333 0.517647 0.521569 0.513725 0.509804 0.513725 0.498039 0.498039 0.490196 0.490196 0.47451 0.482353 0.478431 0.470588 0.458824 0.462745 0.45098 0.443137 0.443137 0.431373 0.427451 0.411765 0.403922 0.396078 0.384314 0.384314 0.368627 0.364706 0.356863 0.345098 0.337255 0.329412 0.32549 0.313725 0.313725 0.286275 0.278431 0.258824 0.25098 0.286275 0.258824 0.231373 0.211765 0.184314 0.160784 0.219608 0.278431 0.356863 0.372549 0.294118 0.145098 0.0431373 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.14902 0.443137 0.533333 0.537255 0.509804 0.470588 0.427451 0.333333 0.141176 0 0 0 0 0.0901961 0.176471 0.239216 0.27451 0.317647 0.356863 0.372549 0.384314 0.415686 0.427451 0.447059 0.447059 0.47451 0.47451 0.486275 0.498039 0.498039 0.501961 0.509804 0.513725 0.513725 0.521569 0.521569 0.521569 0.537255 0.529412 0.537255 0.537255 0.541176 0.545098 0.529412 0.529412 0.533333 0.545098 0.537255 0.537255 0.529412 0.545098 0.537255 0.533333 0.533333 0.529412 0.529412 0.529412 0.521569 0.517647 0.513725 0.521569 0.513725 0.509804 0.498039 0.490196 0.486275 0.478431 0.470588 0.47451 0.466667 0.458824 0.454902 0.447059 0.443137 0.443137 0.431373 0.423529 0.419608 0.4 0.392157 0.388235 0.396078 0.364706 0.376471 0.34902 0.356863 0.345098 0.329412 0.313725 0.309804 0.301961 0.294118 0.278431 0.262745 0.254902 0.25098 0.282353 0.254902 0.231373 0.196078 0.160784 0.14902 0.188235 0.258824 0.309804 0.27451 0.164706 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.356863 0.513725 0.509804 0.498039 0.47451 0.407843 0.333333 0.152941 0 0 0 0 0.0313725 0.156863 0.211765 0.258824 0.294118 0.333333 0.360784 0.380392 0.392157 0.419608 0.439216 0.447059 0.458824 0.458824 0.478431 0.482353 0.494118 0.501961 0.513725 0.501961 0.513725 0.509804 0.517647 0.517647 0.517647 0.529412 0.52549 0.52549 0.533333 0.529412 0.521569 0.533333 0.537255 0.537255 0.537255 0.529412 0.529412 0.537255 0.533333 0.521569 0.533333 0.529412 0.529412 0.521569 0.513725 0.529412 0.517647 0.505882 0.501961 0.501961 0.501961 0.498039 0.482353 0.486275 0.478431 0.478431 0.466667 0.466667 0.454902 0.45098 0.439216 0.435294 0.423529 0.423529 0.419608 0.403922 0.4 0.396078 0.380392 0.372549 0.368627 0.352941 0.341176 0.337255 0.32549 0.317647 0.309804 0.294118 0.294118 0.278431 0.266667 0.247059 0.247059 0.27451 0.25098 0.223529 0.184314 0.160784 0.145098 0.168627 0.243137 0.247059 0.168627 0.0823529 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.231373 0.486275 0.517647 0.486275 0.462745 0.4 0.313725 0.160784 0 0 0 0 0 0.121569 0.192157 0.247059 0.282353 0.313725 0.345098 0.368627 0.396078 0.411765 0.419608 0.431373 0.447059 0.462745 0.470588 0.482353 0.490196 0.490196 0.501961 0.509804 0.501961 0.517647 0.505882 0.498039 0.517647 0.529412 0.533333 0.517647 0.533333 0.529412 0.529412 0.529412 0.537255 0.529412 0.533333 0.52549 0.52549 0.54902 0.529412 0.517647 0.529412 0.52549 0.529412 0.517647 0.521569 0.517647 0.505882 0.509804 0.498039 0.505882 0.498039 0.498039 0.494118 0.482353 0.478431 0.470588 0.482353 0.458824 0.458824 0.447059 0.435294 0.419608 0.423529 0.411765 0.407843 0.4 0.396078 0.392157 0.376471 0.376471 0.360784 0.345098 0.337255 0.329412 0.321569 0.301961 0.301961 0.286275 0.27451 0.266667 0.254902 0.25098 0.247059 0.278431 0.239216 0.215686 0.184314 0.14902 0.133333 0.156863 0.2 0.172549 0.0901961 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.176471 0.466667 0.517647 0.478431 0.447059 0.396078 0.301961 0.145098 0 0 0 0 0 0.0862745 0.168627 0.223529 0.270588 0.313725 0.32549 0.356863 0.380392 0.392157 0.411765 0.427451 0.443137 0.447059 0.462745 0.470588 0.478431 0.482353 0.486275 0.498039 0.490196 0.505882 0.501961 0.509804 0.52549 0.517647 0.52549 0.52549 0.517647 0.521569 0.521569 0.52549 0.529412 0.52549 0.533333 0.517647 0.533333 0.517647 0.529412 0.513725 0.517647 0.505882 0.517647 0.501961 0.509804 0.505882 0.490196 0.501961 0.498039 0.490196 0.490196 0.490196 0.47451 0.486275 0.470588 0.478431 0.458824 0.447059 0.443137 0.45098 0.435294 0.419608 0.423529 0.407843 0.396078 0.396078 0.392157 0.384314 0.364706 0.368627 0.345098 0.32549 0.321569 0.32549 0.309804 0.298039 0.298039 0.286275 0.27451 0.254902 0.239216 0.235294 0.262745 0.258824 0.227451 0.207843 0.164706 0.137255 0.129412 0.133333 0.113725 0.0431373 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.121569 0.431373 0.509804 0.482353 0.431373 0.372549 0.278431 0.113725 0 0 0 0 0 0.0313725 0.137255 0.207843 0.25098 0.294118 0.32549 0.34902 0.364706 0.376471 0.407843 0.415686 0.431373 0.439216 0.45098 0.454902 0.47451 0.47451 0.490196 0.494118 0.498039 0.498039 0.505882 0.505882 0.517647 0.513725 0.517647 0.517647 0.513725 0.52549 0.509804 0.513725 0.521569 0.521569 0.521569 0.52549 0.517647 0.521569 0.513725 0.52549 0.513725 0.509804 0.521569 0.505882 0.498039 0.501961 0.501961 0.494118 0.494118 0.490196 0.486275 0.478431 0.47451 0.470588 0.458824 0.45098 0.447059 0.45098 0.447059 0.431373 0.431373 0.415686 0.403922 0.403922 0.4 0.392157 0.372549 0.380392 0.364706 0.360784 0.341176 0.341176 0.333333 0.321569 0.301961 0.294118 0.286275 0.282353 0.262745 0.247059 0.235294 0.235294 0.258824 0.258824 0.235294 0.196078 0.164706 0.141176 0.117647 0.109804 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.105882 0.415686 0.513725 0.470588 0.415686 0.341176 0.266667 0.117647 0 0 0 0 0 0.0117647 0.12549 0.184314 0.235294 0.266667 0.313725 0.333333 0.352941 0.376471 0.396078 0.407843 0.419608 0.427451 0.439216 0.45098 0.458824 0.470588 0.486275 0.482353 0.486275 0.494118 0.498039 0.498039 0.505882 0.505882 0.52549 0.509804 0.513725 0.521569 0.517647 0.513725 0.517647 0.501961 0.509804 0.517647 0.521569 0.509804 0.498039 0.521569 0.501961 0.498039 0.505882 0.509804 0.505882 0.494118 0.498039 0.490196 0.482353 0.482353 0.494118 0.47451 0.47451 0.462745 0.45098 0.458824 0.447059 0.443137 0.447059 0.431373 0.427451 0.411765 0.403922 0.403922 0.4 0.380392 0.372549 0.364706 0.356863 0.337255 0.341176 0.329412 0.321569 0.309804 0.294118 0.286275 0.270588 0.270588 0.25098 0.25098 0.235294 0.227451 0.266667 0.247059 0.215686 0.2 0.14902 0.121569 0.113725 0.0470588 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.164706 0.447059 0.505882 0.458824 0.392157 0.32549 0.223529 0.0745098 0 0 0 0 0 0 0.0666667 0.156863 0.2 0.247059 0.290196 0.321569 0.337255 0.364706 0.388235 0.403922 0.415686 0.423529 0.431373 0.443137 0.454902 0.454902 0.466667 0.470588 0.478431 0.490196 0.494118 0.494118 0.498039 0.505882 0.498039 0.501961 0.498039 0.513725 0.501961 0.509804 0.513725 0.505882 0.509804 0.498039 0.505882 0.517647 0.505882 0.501961 0.501961 0.498039 0.505882 0.498039 0.498039 0.498039 0.482353 0.478431 0.482353 0.470588 0.482353 0.478431 0.458824 0.458824 0.443137 0.447059 0.439216 0.435294 0.427451 0.411765 0.411765 0.411765 0.392157 0.392157 0.384314 0.372549 0.356863 0.360784 0.34902 0.34902 0.321569 0.321569 0.313725 0.305882 0.290196 0.282353 0.270588 0.258824 0.235294 0.243137 0.219608 0.215686 0.278431 0.227451 0.219608 0.188235 0.137255 0.113725 0.0980392 0.00784314 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.239216 0.462745 0.498039 0.443137 0.376471 0.301961 0.203922 0.0627451 0 0 0 0 0 0 0.0313725 0.141176 0.192157 0.239216 0.286275 0.305882 0.333333 0.356863 0.376471 0.380392 0.411765 0.411765 0.431373 0.431373 0.45098 0.45098 0.470588 0.47451 0.47451 0.470588 0.486275 0.490196 0.47451 0.498039 0.490196 0.498039 0.501961 0.513725 0.505882 0.498039 0.498039 0.509804 0.505882 0.501961 0.498039 0.501961 0.501961 0.498039 0.486275 0.498039 0.498039 0.494118 0.490196 0.486275 0.486275 0.482353 0.462745 0.462745 0.466667 0.458824 0.447059 0.454902 0.443137 0.443137 0.431373 0.427451 0.419608 0.411765 0.407843 0.396078 0.392157 0.384314 0.376471 0.376471 0.352941 0.352941 0.345098 0.337255 0.32549 0.309804 0.309804 0.294118 0.286275 0.27451 0.262745 0.25098 0.243137 0.231373 0.219608 0.211765 0.270588 0.223529 0.2 0.168627 0.121569 0.101961 0.054902 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.105882 0.372549 0.509804 0.498039 0.419608 0.345098 0.266667 0.141176 0.0156863 0 0 0 0 0 0 0 0.0980392 0.168627 0.223529 0.254902 0.286275 0.321569 0.337255 0.364706 0.384314 0.392157 0.407843 0.415686 0.423529 0.439216 0.443137 0.458824 0.458824 0.466667 0.478431 0.458824 0.482353 0.486275 0.490196 0.490196 0.494118 0.494118 0.498039 0.494118 0.498039 0.498039 0.498039 0.501961 0.482353 0.494118 0.498039 0.494118 0.490196 0.482353 0.486275 0.490196 0.478431 0.482353 0.470588 0.458824 0.470588 0.47451 0.458824 0.466667 0.45098 0.458824 0.443137 0.45098 0.435294 0.419608 0.415686 0.411765 0.4 0.4 0.384314 0.380392 0.384314 0.368627 0.34902 0.356863 0.345098 0.337255 0.32549 0.317647 0.305882 0.294118 0.290196 0.278431 0.262745 0.258824 0.247059 0.239216 0.223529 0.207843 0.211765 0.262745 0.215686 0.196078 0.160784 0.133333 0.0901961 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.282353 0.454902 0.541176 0.482353 0.396078 0.301961 0.219608 0.0941176 0 0 0 0 0 0 0 0 0.0352941 0.133333 0.192157 0.231373 0.262745 0.301961 0.317647 0.341176 0.360784 0.364706 0.380392 0.411765 0.423529 0.427451 0.431373 0.439216 0.458824 0.458824 0.466667 0.462745 0.478431 0.47451 0.470588 0.482353 0.486275 0.490196 0.498039 0.490196 0.486275 0.494118 0.486275 0.494118 0.498039 0.486275 0.486275 0.482353 0.486275 0.490196 0.482353 0.482353 0.470588 0.466667 0.462745 0.458824 0.458824 0.458824 0.454902 0.462745 0.439216 0.45098 0.431373 0.439216 0.419608 0.431373 0.419608 0.4 0.403922 0.392157 0.376471 0.364706 0.368627 0.364706 0.352941 0.341176 0.337255 0.337255 0.298039 0.317647 0.298039 0.286275 0.282353 0.270588 0.258824 0.254902 0.231373 0.219608 0.211765 0.196078 0.223529 0.247059 0.211765 0.192157 0.156863 0.109804 0.0745098 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.227451 0.4 0.533333 0.54902 0.45098 0.352941 0.254902 0.164706 0.027451 0 0 0 0 0 0 0 0 0 0.101961 0.176471 0.223529 0.25098 0.286275 0.313725 0.321569 0.356863 0.372549 0.376471 0.388235 0.407843 0.423529 0.423529 0.431373 0.454902 0.443137 0.470588 0.462745 0.458824 0.466667 0.470588 0.482353 0.486275 0.470588 0.478431 0.478431 0.486275 0.482353 0.482353 0.486275 0.47451 0.478431 0.47451 0.47451 0.470588 0.466667 0.458824 0.466667 0.466667 0.466667 0.458824 0.454902 0.45098 0.443137 0.439216 0.443137 0.435294 0.439216 0.435294 0.423529 0.431373 0.411765 0.4 0.392157 0.396078 0.392157 0.380392 0.372549 0.356863 0.34902 0.337255 0.333333 0.32549 0.317647 0.301961 0.298039 0.298039 0.278431 0.270588 0.262745 0.25098 0.239216 0.231373 0.211765 0.2 0.184314 0.227451 0.235294 0.203922 0.188235 0.152941 0.105882 0.0431373 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.027451 0.223529 0.384314 0.505882 0.580392 0.513725 0.403922 0.305882 0.211765 0.101961 0 0 0 0 0 0 0 0 0 0 0.054902 0.14902 0.196078 0.231373 0.266667 0.294118 0.317647 0.337255 0.360784 0.376471 0.388235 0.396078 0.419608 0.419608 0.435294 0.427451 0.45098 0.447059 0.454902 0.466667 0.462745 0.462745 0.470588 0.47451 0.478431 0.470588 0.47451 0.478431 0.470588 0.470588 0.478431 0.482353 0.478431 0.482353 0.478431 0.470588 0.47451 0.462745 0.466667 0.458824 0.462745 0.447059 0.458824 0.447059 0.443137 0.447059 0.443137 0.427451 0.431373 0.427451 0.415686 0.415686 0.407843 0.4 0.396078 0.376471 0.380392 0.368627 0.360784 0.360784 0.341176 0.329412 0.329412 0.317647 0.313725 0.301961 0.290196 0.278431 0.270588 0.266667 0.247059 0.235294 0.231373 0.207843 0.207843 0.192157 0.172549 0.219608 0.227451 0.196078 0.184314 0.141176 0.0941176 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0941176 0.243137 0.384314 0.501961 0.584314 0.568627 0.443137 0.345098 0.243137 0.145098 0.0235294 0 0 0 0 0 0 0 0 0 0 0.00392157 0.113725 0.176471 0.207843 0.25098 0.278431 0.301961 0.329412 0.337255 0.364706 0.372549 0.376471 0.396078 0.403922 0.419608 0.423529 0.431373 0.431373 0.447059 0.431373 0.454902 0.466667 0.466667 0.466667 0.462745 0.466667 0.482353 0.466667 0.478431 0.478431 0.466667 0.470588 0.466667 0.47451 0.462745 0.458824 0.466667 0.458824 0.45098 0.447059 0.458824 0.45098 0.427451 0.439216 0.443137 0.431373 0.419608 0.423529 0.431373 0.407843 0.415686 0.403922 0.396078 0.396078 0.376471 0.372549 0.368627 0.352941 0.341176 0.34902 0.333333 0.321569 0.317647 0.305882 0.301961 0.290196 0.286275 0.27451 0.266667 0.254902 0.235294 0.231373 0.223529 0.207843 0.2 0.172549 0.176471 0.227451 0.219608 0.2 0.176471 0.117647 0.0588235 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0588235 0.2 0.313725 0.411765 0.521569 0.6 0.592157 0.478431 0.368627 0.266667 0.168627 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0.0784314 0.145098 0.192157 0.227451 0.254902 0.294118 0.321569 0.329412 0.345098 0.360784 0.372549 0.376471 0.396078 0.407843 0.419608 0.415686 0.423529 0.407843 0.443137 0.443137 0.447059 0.45098 0.454902 0.458824 0.454902 0.458824 0.470588 0.462745 0.45098 0.45098 0.462745 0.470588 0.458824 0.454902 0.458824 0.443137 0.458824 0.435294 0.45098 0.439216 0.447059 0.435294 0.435294 0.431373 0.419608 0.423529 0.423529 0.4 0.407843 0.403922 0.396078 0.392157 0.380392 0.372549 0.356863 0.352941 0.333333 0.341176 0.32549 0.317647 0.321569 0.309804 0.305882 0.290196 0.290196 0.27451 0.270588 0.243137 0.247059 0.235294 0.231373 0.207843 0.203922 0.2 0.176471 0.180392 0.227451 0.215686 0.196078 0.176471 0.0941176 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0627451 0.203922 0.278431 0.376471 0.466667 0.556863 0.615686 0.619608 0.501961 0.384314 0.258824 0.180392 0.0745098 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.12549 0.168627 0.215686 0.227451 0.27451 0.298039 0.313725 0.333333 0.345098 0.368627 0.380392 0.384314 0.4 0.411765 0.4 0.427451 0.419608 0.431373 0.435294 0.435294 0.439216 0.45098 0.447059 0.439216 0.447059 0.454902 0.447059 0.447059 0.462745 0.447059 0.443137 0.443137 0.45098 0.454902 0.439216 0.45098 0.447059 0.435294 0.439216 0.427451 0.431373 0.431373 0.419608 0.411765 0.407843 0.407843 0.396078 0.384314 0.384314 0.388235 0.384314 0.372549 0.372549 0.352941 0.345098 0.345098 0.333333 0.321569 0.313725 0.309804 0.301961 0.286275 0.282353 0.262745 0.270588 0.254902 0.247059 0.235294 0.223529 0.207843 0.2 0.192157 0.180392 0.168627 0.172549 0.227451 0.203922 0.188235 0.168627 0.0627451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.12549 0.227451 0.290196 0.372549 0.458824 0.513725 0.596078 0.647059 0.611765 0.501961 0.376471 0.262745 0.168627 0.0823529 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.137255 0.184314 0.219608 0.247059 0.282353 0.298039 0.32549 0.345098 0.34902 0.368627 0.376471 0.384314 0.388235 0.4 0.411765 0.411765 0.415686 0.415686 0.431373 0.435294 0.447059 0.435294 0.431373 0.45098 0.45098 0.443137 0.443137 0.435294 0.443137 0.439216 0.447059 0.439216 0.447059 0.443137 0.435294 0.443137 0.431373 0.427451 0.435294 0.419608 0.415686 0.411765 0.403922 0.411765 0.384314 0.388235 0.384314 0.376471 0.364706 0.364706 0.352941 0.352941 0.341176 0.345098 0.329412 0.317647 0.313725 0.301961 0.294118 0.290196 0.282353 0.270588 0.266667 0.262745 0.243137 0.231373 0.227451 0.219608 0.2 0.2 0.180392 0.168627 0.164706 0.156863 0.235294 0.203922 0.184314 0.160784 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0666667 0.14902 0.211765 0.266667 0.329412 0.376471 0.458824 0.517647 0.588235 0.631373 0.662745 0.603922 0.490196 0.364706 0.254902 0.168627 0.0705882 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.121569 0.172549 0.192157 0.243137 0.266667 0.278431 0.309804 0.32549 0.34902 0.352941 0.352941 0.372549 0.388235 0.392157 0.4 0.4 0.419608 0.415686 0.419608 0.431373 0.435294 0.439216 0.439216 0.427451 0.423529 0.443137 0.427451 0.435294 0.443137 0.443137 0.431373 0.431373 0.435294 0.427451 0.419608 0.431373 0.415686 0.415686 0.423529 0.403922 0.419608 0.403922 0.396078 0.384314 0.388235 0.392157 0.380392 0.372549 0.372549 0.356863 0.352941 0.345098 0.341176 0.345098 0.309804 0.317647 0.305882 0.290196 0.294118 0.282353 0.27451 0.266667 0.254902 0.243137 0.243137 0.235294 0.219608 0.211765 0.192157 0.188235 0.168627 0.164706 0.152941 0.168627 0.235294 0.192157 0.192157 0.0941176 0 0 0 0 0 0 0 0 0 0 0.00392157 0.0156863 0.0823529 0.164706 0.203922 0.235294 0.270588 0.32549 0.380392 0.447059 0.501961 0.541176 0.596078 0.65098 0.670588 0.635294 0.552941 0.439216 0.317647 0.227451 0.133333 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0784314 0.145098 0.164706 0.215686 0.25098 0.266667 0.286275 0.313725 0.329412 0.34902 0.352941 0.364706 0.376471 0.384314 0.392157 0.403922 0.4 0.415686 0.403922 0.423529 0.423529 0.427451 0.423529 0.431373 0.435294 0.427451 0.431373 0.431373 0.435294 0.431373 0.427451 0.423529 0.419608 0.427451 0.407843 0.419608 0.411765 0.407843 0.415686 0.407843 0.407843 0.392157 0.396078 0.384314 0.380392 0.376471 0.372549 0.360784 0.352941 0.352941 0.345098 0.337255 0.329412 0.329412 0.313725 0.309804 0.301961 0.294118 0.282353 0.282353 0.266667 0.262745 0.243137 0.231373 0.231373 0.215686 0.215686 0.203922 0.184314 0.176471 0.160784 0.14902 0.145098 0.168627 0.262745 0.2 0.172549 0.121569 0.0196078 0 0 0.00784314 0.0431373 0.0666667 0.109804 0.14902 0.188235 0.211765 0.231373 0.254902 0.282353 0.309804 0.337255 0.388235 0.439216 0.490196 0.537255 0.596078 0.627451 0.662745 0.682353 0.65098 0.588235 0.486275 0.376471 0.266667 0.180392 0.105882 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.12549 0.160784 0.2 0.235294 0.247059 0.282353 0.298039 0.317647 0.329412 0.34902 0.356863 0.360784 0.376471 0.380392 0.380392 0.392157 0.403922 0.403922 0.407843 0.415686 0.419608 0.427451 0.419608 0.415686 0.431373 0.427451 0.419608 0.427451 0.423529 0.419608 0.407843 0.423529 0.423529 0.423529 0.415686 0.407843 0.403922 0.4 0.4 0.396078 0.392157 0.396078 0.368627 0.372549 0.376471 0.352941 0.352941 0.356863 0.341176 0.337255 0.333333 0.313725 0.321569 0.305882 0.305882 0.298039 0.282353 0.27451 0.262745 0.258824 0.247059 0.239216 0.227451 0.223529 0.203922 0.196078 0.188235 0.172549 0.172549 0.14902 0.141176 0.133333 0.196078 0.254902 0.196078 0.188235 0.160784 0.117647 0.145098 0.172549 0.203922 0.223529 0.247059 0.27451 0.27451 0.309804 0.341176 0.360784 0.4 0.423529 0.45098 0.505882 0.556863 0.603922 0.635294 0.67451 0.705882 0.698039 0.639216 0.560784 0.470588 0.376471 0.266667 0.184314 0.113725 0.0392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.145098 0.176471 0.203922 0.243137 0.262745 0.270588 0.298039 0.317647 0.329412 0.341176 0.352941 0.360784 0.380392 0.376471 0.380392 0.388235 0.396078 0.4 0.4 0.392157 0.419608 0.4 0.411765 0.415686 0.407843 0.415686 0.415686 0.431373 0.415686 0.419608 0.4 0.407843 0.4 0.403922 0.403922 0.396078 0.403922 0.396078 0.392157 0.376471 0.368627 0.368627 0.368627 0.364706 0.34902 0.341176 0.337255 0.329412 0.317647 0.32549 0.305882 0.317647 0.298039 0.294118 0.270588 0.262745 0.27451 0.258824 0.25098 0.25098 0.231373 0.223529 0.2 0.2 0.184314 0.176471 0.164706 0.156863 0.145098 0.137255 0.121569 0.211765 0.243137 0.207843 0.243137 0.239216 0.254902 0.27451 0.294118 0.329412 0.356863 0.380392 0.403922 0.411765 0.447059 0.486275 0.505882 0.541176 0.584314 0.635294 0.658824 0.682353 0.717647 0.705882 0.658824 0.584314 0.505882 0.427451 0.32549 0.243137 0.164706 0.105882 0.0509804 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0156863 0.113725 0.156863 0.188235 0.219608 0.247059 0.266667 0.290196 0.305882 0.317647 0.329412 0.34902 0.356863 0.356863 0.368627 0.380392 0.380392 0.388235 0.388235 0.388235 0.4 0.403922 0.396078 0.4 0.411765 0.407843 0.411765 0.4 0.403922 0.403922 0.403922 0.407843 0.396078 0.396078 0.392157 0.4 0.396078 0.392157 0.396078 0.376471 0.372549 0.364706 0.364706 0.360784 0.352941 0.345098 0.341176 0.345098 0.321569 0.321569 0.317647 0.317647 0.298039 0.286275 0.278431 0.270588 0.258824 0.247059 0.25098 0.239216 0.227451 0.219608 0.211765 0.2 0.184314 0.176471 0.168627 0.164706 0.152941 0.133333 0.12549 0.121569 0.211765 0.215686 0.239216 0.317647 0.364706 0.380392 0.403922 0.431373 0.45098 0.47451 0.494118 0.521569 0.54902 0.576471 0.6 0.65098 0.694118 0.713725 0.733333 0.67451 0.623529 0.568627 0.498039 0.419608 0.333333 0.258824 0.188235 0.137255 0.0784314 0.0313725 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0666667 0.137255 0.180392 0.211765 0.227451 0.254902 0.278431 0.298039 0.305882 0.313725 0.341176 0.345098 0.360784 0.356863 0.360784 0.368627 0.368627 0.372549 0.388235 0.372549 0.403922 0.396078 0.396078 0.392157 0.392157 0.396078 0.4 0.396078 0.396078 0.403922 0.396078 0.396078 0.392157 0.396078 0.384314 0.376471 0.388235 0.364706 0.372549 0.376471 0.360784 0.360784 0.352941 0.34902 0.341176 0.333333 0.337255 0.317647 0.309804 0.305882 0.305882 0.286275 0.282353 0.282353 0.270588 0.254902 0.25098 0.247059 0.231373 0.223529 0.215686 0.196078 0.192157 0.184314 0.176471 0.14902 0.14902 0.152941 0.129412 0.117647 0.117647 0.184314 0.188235 0.298039 0.427451 0.466667 0.498039 0.521569 0.54902 0.576471 0.576471 0.603922 0.666667 0.686275 0.654902 0.682353 0.631373 0.584314 0.54902 0.498039 0.427451 0.368627 0.301961 0.231373 0.172549 0.129412 0.0823529 0.0352941 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.101961 0.14902 0.188235 0.215686 0.235294 0.258824 0.282353 0.298039 0.309804 0.329412 0.337255 0.345098 0.34902 0.356863 0.360784 0.376471 0.376471 0.376471 0.384314 0.396078 0.392157 0.384314 0.392157 0.380392 0.388235 0.392157 0.384314 0.392157 0.384314 0.376471 0.376471 0.384314 0.380392 0.372549 0.376471 0.376471 0.360784 0.368627 0.364706 0.352941 0.352941 0.337255 0.337255 0.337255 0.329412 0.321569 0.309804 0.294118 0.309804 0.286275 0.286275 0.27451 0.270588 0.262745 0.25098 0.243137 0.243137 0.223529 0.215686 0.2 0.203922 0.180392 0.172549 0.156863 0.152941 0.141176 0.12549 0.113725 0.101961 0.121569 0.14902 0.203922 0.415686 0.498039 0.545098 0.556863 0.576471 0.580392 0.568627 0.564706 0.533333 0.509804 0.494118 0.462745 0.427451 0.380392 0.337255 0.290196 0.227451 0.188235 0.141176 0.109804 0.0705882 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0431373 0.113725 0.160784 0.196078 0.215686 0.247059 0.270588 0.286275 0.298039 0.317647 0.321569 0.333333 0.337255 0.352941 0.34902 0.360784 0.368627 0.364706 0.376471 0.380392 0.388235 0.376471 0.380392 0.380392 0.384314 0.376471 0.376471 0.388235 0.380392 0.368627 0.368627 0.376471 0.376471 0.356863 0.360784 0.356863 0.352941 0.360784 0.360784 0.34902 0.341176 0.333333 0.333333 0.329412 0.317647 0.301961 0.298039 0.294118 0.294118 0.286275 0.27451 0.262745 0.254902 0.254902 0.243137 0.235294 0.219608 0.219608 0.2 0.188235 0.188235 0.172549 0.152941 0.160784 0.141176 0.129412 0.129412 0.113725 0.0901961 0.105882 0.145098 0.243137 0.341176 0.403922 0.431373 0.431373 0.419608 0.396078 0.364706 0.345098 0.321569 0.286275 0.262745 0.215686 0.188235 0.152941 0.121569 0.0941176 0.0627451 0.0431373 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0823529 0.133333 0.172549 0.203922 0.227451 0.262745 0.270588 0.290196 0.294118 0.313725 0.32549 0.329412 0.333333 0.341176 0.34902 0.352941 0.352941 0.368627 0.368627 0.364706 0.368627 0.376471 0.376471 0.384314 0.372549 0.380392 0.384314 0.376471 0.368627 0.368627 0.368627 0.376471 0.352941 0.368627 0.360784 0.345098 0.34902 0.337255 0.337255 0.333333 0.329412 0.321569 0.305882 0.309804 0.301961 0.298039 0.294118 0.270588 0.27451 0.270588 0.262745 0.247059 0.243137 0.235294 0.219608 0.223529 0.2 0.203922 0.180392 0.176471 0.172549 0.156863 0.141176 0.133333 0.121569 0.109804 0.0901961 0.0705882 0.0941176 0.141176 0.207843 0.227451 0.239216 0.235294 0.219608 0.203922 0.180392 0.160784 0.141176 0.129412 0.109804 0.0784314 0.054902 0.0235294 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.101961 0.145098 0.180392 0.203922 0.235294 0.254902 0.282353 0.286275 0.298039 0.313725 0.301961 0.329412 0.337255 0.341176 0.352941 0.34902 0.34902 0.364706 0.356863 0.356863 0.364706 0.372549 0.380392 0.352941 0.360784 0.364706 0.360784 0.364706 0.360784 0.352941 0.364706 0.352941 0.352941 0.345098 0.333333 0.345098 0.329412 0.333333 0.32549 0.317647 0.313725 0.313725 0.294118 0.301961 0.290196 0.270588 0.27451 0.270588 0.254902 0.25098 0.239216 0.235294 0.219608 0.211765 0.192157 0.2 0.192157 0.176471 0.168627 0.160784 0.145098 0.141176 0.121569 0.109804 0.0941176 0.0627451 0.0470588 0.0823529 0.113725 0.117647 0.101961 0.0862745 0.0862745 0.0784314 0.0627451 0.0509804 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0313725 0.113725 0.152941 0.192157 0.219608 0.239216 0.258824 0.258824 0.278431 0.298039 0.305882 0.317647 0.337255 0.333333 0.345098 0.337255 0.345098 0.364706 0.345098 0.34902 0.360784 0.356863 0.360784 0.360784 0.368627 0.360784 0.356863 0.345098 0.34902 0.356863 0.34902 0.345098 0.345098 0.341176 0.341176 0.337255 0.333333 0.317647 0.305882 0.309804 0.309804 0.301961 0.294118 0.298039 0.27451 0.278431 0.262745 0.258824 0.247059 0.239216 0.223529 0.223529 0.211765 0.207843 0.196078 0.188235 0.184314 0.160784 0.160784 0.152941 0.141176 0.12549 0.113725 0.0941176 0.0705882 0.0392157 0.0509804 0.0431373 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0470588 0.117647 0.156863 0.184314 0.219608 0.231373 0.254902 0.278431 0.290196 0.290196 0.305882 0.309804 0.317647 0.333333 0.337255 0.333333 0.341176 0.34902 0.34902 0.345098 0.34902 0.345098 0.356863 0.360784 0.356863 0.356863 0.34902 0.356863 0.341176 0.345098 0.337255 0.341176 0.345098 0.333333 0.329412 0.32549 0.317647 0.309804 0.305882 0.298039 0.298039 0.282353 0.270588 0.270588 0.258824 0.258824 0.247059 0.247059 0.235294 0.227451 0.223529 0.203922 0.2 0.196078 0.188235 0.172549 0.164706 0.14902 0.14902 0.133333 0.121569 0.101961 0.0784314 0.0509804 0.0313725 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.054902 0.117647 0.160784 0.188235 0.215686 0.243137 0.258824 0.266667 0.282353 0.294118 0.313725 0.321569 0.317647 0.329412 0.321569 0.341176 0.345098 0.333333 0.337255 0.34902 0.34902 0.333333 0.345098 0.352941 0.345098 0.34902 0.345098 0.333333 0.345098 0.32549 0.329412 0.333333 0.32549 0.32549 0.317647 0.305882 0.305882 0.298039 0.286275 0.286275 0.282353 0.270588 0.254902 0.25098 0.247059 0.235294 0.227451 0.223529 0.215686 0.211765 0.196078 0.192157 0.180392 0.172549 0.164706 0.156863 0.145098 0.133333 0.117647 0.101961 0.0901961 0.054902 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00392157 0.0627451 0.0980392 0.141176 0.176471 0.219608 0.235294 0.254902 0.262745 0.278431 0.298039 0.305882 0.301961 0.317647 0.309804 0.329412 0.329412 0.329412 0.32549 0.341176 0.341176 0.341176 0.337255 0.337255 0.32549 0.329412 0.337255 0.329412 0.337255 0.32549 0.321569 0.317647 0.305882 0.309804 0.305882 0.290196 0.294118 0.290196 0.27451 0.27451 0.270588 0.262745 0.254902 0.254902 0.247059 0.227451 0.223529 0.203922 0.207843 0.2 0.196078 0.180392 0.176471 0.152941 0.156863 0.14902 0.129412 0.133333 0.101961 0.0784314 0.0627451 0.027451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.0901961 0.0823529 0.12549 0.172549 0.188235 0.215686 0.243137 0.262745 0.278431 0.278431 0.278431 0.298039 0.305882 0.321569 0.313725 0.32549 0.329412 0.313725 0.317647 0.333333 0.32549 0.321569 0.32549 0.32549 0.32549 0.32549 0.313725 0.313725 0.317647 0.313725 0.305882 0.305882 0.294118 0.290196 0.286275 0.270588 0.27451 0.270588 0.254902 0.254902 0.243137 0.243137 0.231373 0.223529 0.207843 0.203922 0.192157 0.192157 0.176471 0.180392 0.152941 0.160784 0.141176 0.129412 0.121569 0.105882 0.0666667 0.054902 0.0352941 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0392157 0.0862745 0.12549 0.12549 0.145098 0.180392 0.2 0.219608 0.231373 0.243137 0.258824 0.27451 0.282353 0.301961 0.305882 0.313725 0.305882 0.317647 0.321569 0.317647 0.317647 0.313725 0.317647 0.321569 0.317647 0.309804 0.313725 0.305882 0.309804 0.305882 0.294118 0.298039 0.290196 0.278431 0.278431 0.266667 0.25098 0.25098 0.243137 0.25098 0.227451 0.223529 0.223529 0.2 0.207843 0.196078 0.176471 0.180392 0.164706 0.152941 0.145098 0.129412 0.121569 0.101961 0.0784314 0.0627451 0.0588235 0.0509804 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0196078 0.0823529 0.121569 0.160784 0.145098 0.152941 0.152941 0.192157 0.211765 0.223529 0.239216 0.25098 0.278431 0.282353 0.27451 0.290196 0.298039 0.294118 0.294118 0.301961 0.309804 0.305882 0.305882 0.305882 0.309804 0.286275 0.286275 0.294118 0.286275 0.278431 0.270588 0.282353 0.266667 0.262745 0.25098 0.239216 0.235294 0.231373 0.227451 0.219608 0.215686 0.203922 0.196078 0.184314 0.176471 0.160784 0.160784 0.14902 0.129412 0.117647 0.113725 0.0941176 0.0823529 0.0666667 0.0745098 0.0431373 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0117647 0.0941176 0.113725 0.152941 0.188235 0.180392 0.176471 0.172549 0.188235 0.188235 0.207843 0.235294 0.239216 0.247059 0.258824 0.258824 0.27451 0.266667 0.278431 0.286275 0.278431 0.278431 0.278431 0.27451 0.278431 0.266667 0.270588 0.266667 0.258824 0.258824 0.258824 0.243137 0.239216 0.235294 0.231373 0.219608 0.211765 0.203922 0.196078 0.192157 0.180392 0.164706 0.160784 0.160784 0.137255 0.133333 0.121569 0.105882 0.101961 0.0901961 0.0980392 0.0823529 0.0627451 0.0470588 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0470588 0.121569 0.137255 0.145098 0.180392 0.2 0.211765 0.215686 0.2 0.188235 0.196078 0.196078 0.207843 0.219608 0.223529 0.231373 0.235294 0.243137 0.243137 0.235294 0.247059 0.243137 0.25098 0.235294 0.235294 0.243137 0.219608 0.223529 0.223529 0.211765 0.203922 0.219608 0.196078 0.196078 0.176471 0.176471 0.160784 0.160784 0.156863 0.141176 0.137255 0.121569 0.121569 0.12549 0.12549 0.113725 0.113725 0.0901961 0.0705882 0.0627451 0.0470588 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.054902 0.121569 0.156863 0.160784 0.164706 0.180392 0.207843 0.215686 0.239216 0.247059 0.239216 0.231373 0.219608 0.211765 0.196078 0.188235 0.192157 0.196078 0.203922 0.196078 0.211765 0.196078 0.2 0.196078 0.2 0.196078 0.180392 0.176471 0.184314 0.168627 0.160784 0.160784 0.145098 0.133333 0.141176 0.14902 0.156863 0.156863 0.160784 0.152941 0.133333 0.12549 0.109804 0.0901961 0.0823529 0.0784314 0.054902 0.0117647 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0862745 0.0705882 0.0509804 0.0980392 0.14902 0.180392 0.196078 0.180392 0.176471 0.184314 0.188235 0.215686 0.235294 0.235294 0.258824 0.262745 0.254902 0.258824 0.25098 0.25098 0.243137 0.227451 0.231373 0.231373 0.219608 0.219608 0.223529 0.211765 0.223529 0.211765 0.2 0.203922 0.196078 0.188235 0.172549 0.156863 0.156863 0.141176 0.129412 0.12549 0.109804 0.105882 0.0901961 0.0705882 0.0431373 0.0156863 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0745098 0.12549 0.054902 0.0509804 0.0862745 0.0980392 0.129412 0.156863 0.184314 0.192157 0.207843 0.219608 0.203922 0.207843 0.2 0.207843 0.203922 0.196078 0.2 0.203922 0.196078 0.192157 0.196078 0.188235 0.192157 0.192157 0.172549 0.176471 0.168627 0.156863 0.156863 0.156863 0.152941 0.152941 0.14902 0.172549 0.172549 0.152941 0.12549 0.101961 0.0666667 0.0470588 0.027451 0.00392157 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0235294 0.0784314 0.0313725 0.0431373 0.0784314 0.0862745 0.0862745 0.105882 0.12549 0.14902 0.168627 0.188235 0.188235 0.203922 0.211765 0.203922 0.2 0.211765 0.203922 0.192157 0.2 0.203922 0.184314 0.180392 0.172549 0.172549 0.156863 0.152941 0.137255 0.145098 0.160784 0.184314 0.215686 0.196078 0.172549 0.133333 0.0901961 0.0627451 0.0470588 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0509804 0.0980392 0.0431373 0.0431373 0.0588235 0.0627451 0.0705882 0.0823529 0.0862745 0.0941176 0.0980392 0.105882 0.0941176 0.105882 0.101961 0.0980392 0.105882 0.105882 0.101961 0.0862745 0.0941176 0.0980392 0.0862745 0.0862745 0.105882 0.137255 0.176471 0.203922 0.196078 0.156863 0.14902 0.12549 0.12549 0.0784314 0.0196078 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0431373 0.0627451 0.0745098 0.101961 0.0901961 0.0627451 0.0588235 0.0588235 0.054902 0.0509804 0.0627451 0.0588235 0.054902 0.0588235 0.0470588 0.054902 0.0823529 0.0901961 0.121569 0.141176 0.14902 0.152941 0.141176 0.133333 0.0627451 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.00784314 0.0156863 0.0196078 0.0156863 0.0196078 0.0352941 0.0392157 0.0313725 0.0235294 0.0627451 0.109804 0.129412 0.0784314 0.0235294 0.0235294 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/data/points/COIL_database/lucky_cat_PCA1 b/data/points/COIL_database/lucky_cat_PCA1 new file mode 100644 index 00000000..dd0f1eda --- /dev/null +++ b/data/points/COIL_database/lucky_cat_PCA1 @@ -0,0 +1,72 @@ +-1452.382 +-985.983 +-300.7043 +340.9664 +1115.224 +1816.717 +2603.418 +3283.292 +3776.975 +4193.036 +4514.083 +4805.137 +5132.243 +5429.507 +5762.975 +6104.911 +6283.41 +6435.22 +6388.126 +6131.01 +6004.362 +5890.452 +5560.509 +5414.897 +5437.464 +5192.032 +5230.463 +5249.902 +5477.721 +5498.137 +5558.49 +5788.839 +6038.19 +6097.074 +6011.507 +6224.031 +5961.784 +6142.578 +5787.753 +5592.622 +5318.977 +4860.224 +4682.885 +4236.65 +3752.153 +3248.328 +2737.484 +2294.011 +1755.705 +1159.159 +799.5467 +486.5098 +310.7009 +95.86115 +31.67501 +-183.7625 +-297.0857 +-279.4419 +-312.4302 +-608.9743 +-961.9346 +-1167.246 +-1320.912 +-1552.051 +-1915.02 +-2222.397 +-2398.179 +-2565.249 +-2594.809 +-2443.374 +-2182.187 +-1900.618 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c16c9cc..a4e6eb50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -54,6 +54,7 @@ add_subdirectory(example/Spatial_searching) add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) +add_subdirectory(example/Nerve_GIC) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt index d499613d..a4cb0f03 100644 --- a/src/Nerve_GIC/example/CMakeLists.txt +++ b/src/Nerve_GIC/example/CMakeLists.txt @@ -13,9 +13,15 @@ target_link_libraries(MapperDeltaCoord ${Boost_SYSTEM_LIBRARY}) add_executable ( MapperDeltaFunc MapperDeltaFunc.cpp ) target_link_libraries(MapperDeltaFunc ${Boost_SYSTEM_LIBRARY}) +add_executable ( GICvoronoi GICvoronoi.cpp ) +target_link_libraries(GICvoronoi ${Boost_SYSTEM_LIBRARY}) + +file(COPY visu.py km.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + if (TBB_FOUND) target_link_libraries(Nerve ${TBB_LIBRARIES}) target_link_libraries(GIC ${TBB_LIBRARIES}) target_link_libraries(MapperDeltaCoord ${TBB_LIBRARIES}) target_link_libraries(MapperDeltaFunc ${TBB_LIBRARIES}) + target_link_libraries(GICvoronoi ${TBB_LIBRARIES}) endif() \ No newline at end of file diff --git a/src/Nerve_GIC/example/GIC.cpp b/src/Nerve_GIC/example/GIC.cpp index 30a485d5..1ab15ecc 100644 --- a/src/Nerve_GIC/example/GIC.cpp +++ b/src/Nerve_GIC/example/GIC.cpp @@ -3,7 +3,7 @@ void usage(int nbArgs, char * const progName) { std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n"; std::cerr << "Usage: " << progName << " filename.off threshold coordinate resolution gain\n"; - std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 1.5 2 10 0.3 \n"; + std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 0.075 2 10 0.3 \n"; exit(-1); // ----- >> } @@ -17,11 +17,6 @@ int main(int argc, char **argv) { double gain = atof(argv[5]); bool verb = 0; if(argc == 7) verb = 1; - // Type definitions - using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\ - boost::property < vertex_filtration_t, Filtration_value >,\ - boost::property < edge_filtration_t, Filtration_value > >; - // ---------------------------------------------------------------------------- // Init of a graph induced complex from an OFF file // ---------------------------------------------------------------------------- @@ -29,12 +24,16 @@ int main(int argc, char **argv) { Gudhi::graph_induced_complex::Graph_induced_complex GIC; GIC.set_verbose(verb); - GIC.set_graph_from_rips(threshold, off_file_name); - GIC.set_function_from_coordinate(coord, off_file_name); GIC.set_color_from_coordinate(off_file_name, coord); + GIC.set_function_from_coordinate(coord, off_file_name); + + GIC.set_graph_from_rips(threshold, off_file_name); + GIC.set_resolution_double(resolution); GIC.set_gain(gain); GIC.set_cover_from_function(1); + GIC.find_GIC_simplices(); + GIC.plot_with_KeplerMapper(); Simplex_tree stree; GIC.create_complex(stree); diff --git a/src/Nerve_GIC/example/GICvoronoi.cpp b/src/Nerve_GIC/example/GICvoronoi.cpp new file mode 100644 index 00000000..2d50ab4d --- /dev/null +++ b/src/Nerve_GIC/example/GICvoronoi.cpp @@ -0,0 +1,59 @@ +#include + +void usage(int nbArgs, char * const progName) { + std::cerr << "Error: Number of arguments (" << nbArgs << ") is not correct\n"; + std::cerr << "Usage: " << progName << " filename.off threshold N\n"; + std::cerr << " i.e.: " << progName << " ../../../data/points/human.off 0.075 100 \n"; + exit(-1); // ----- >> +} + +int main(int argc, char **argv) { + if ((argc != 4) && (argc != 5)) usage(argc, (argv[0] - 1)); + + std::string off_file_name(argv[1]); + double threshold = atof(argv[2]); + int m = atoi(argv[3]); + bool verb = 0; if(argc == 5) verb = 1; + + // ---------------------------------------------------------------------------- + // Init of a graph induced complex from an OFF file + // ---------------------------------------------------------------------------- + + Gudhi::graph_induced_complex::Graph_induced_complex GIC; + GIC.set_verbose(verb); + + GIC.set_color_from_coordinate(off_file_name); + + GIC.set_graph_from_OFF(off_file_name); + + GIC.set_cover_from_Voronoi(m, off_file_name); + + GIC.find_GIC_simplices(); + + GIC.plot_with_KeplerMapper(); + + Simplex_tree stree; GIC.create_complex(stree); + + std::streambuf* streambufffer = std::cout.rdbuf(); + std::ostream output_stream(streambufffer); + + // ---------------------------------------------------------------------------- + // Display information about the graph induced complex + // ---------------------------------------------------------------------------- + + if(verb){ + output_stream << "Graph induced complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; + + output_stream << "Iterator on graph induced complex simplices" << std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + output_stream << vertex << " "; + } + output_stream << std::endl; + } + } + + return 0; +} diff --git a/src/Nerve_GIC/example/MapperDeltaCoord.cpp b/src/Nerve_GIC/example/MapperDeltaCoord.cpp index aa12afe6..950ee58a 100644 --- a/src/Nerve_GIC/example/MapperDeltaCoord.cpp +++ b/src/Nerve_GIC/example/MapperDeltaCoord.cpp @@ -14,11 +14,6 @@ int main(int argc, char **argv) { int coord = atoi(argv[2]); bool verb = 0; if(argc == 4) verb = 1; - // Type definitions - using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\ - boost::property < vertex_filtration_t, Filtration_value >,\ - boost::property < edge_filtration_t, Filtration_value > >; - // --------------------------------------- // Init of a Mapper Delta from an OFF file // --------------------------------------- @@ -26,12 +21,16 @@ int main(int argc, char **argv) { Gudhi::graph_induced_complex::Graph_induced_complex GIC; GIC.set_verbose(verb); - GIC.set_graph_from_automatic_rips(off_file_name); - GIC.set_function_from_coordinate(coord, off_file_name); GIC.set_color_from_coordinate(off_file_name, coord); + GIC.set_function_from_coordinate(coord, off_file_name); + + GIC.set_graph_from_automatic_rips(off_file_name); + GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain(); GIC.set_cover_from_function(1); + GIC.find_GICMAP_simplices_with_functional_minimal_cover(); + GIC.plot_with_KeplerMapper(); Simplex_tree stree; GIC.create_complex(stree); diff --git a/src/Nerve_GIC/example/MapperDeltaFunc.cpp b/src/Nerve_GIC/example/MapperDeltaFunc.cpp index 20924b9c..658b0273 100644 --- a/src/Nerve_GIC/example/MapperDeltaFunc.cpp +++ b/src/Nerve_GIC/example/MapperDeltaFunc.cpp @@ -14,11 +14,6 @@ int main(int argc, char **argv) { std::string func_file_name = argv[2]; bool verb = 0; if(argc == 4) verb = 1; - // Type definitions - using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\ - boost::property < vertex_filtration_t, Filtration_value >,\ - boost::property < edge_filtration_t, Filtration_value > >; - // --------------------------------------- // Init of a Mapper Delta from an OFF file // --------------------------------------- @@ -26,12 +21,16 @@ int main(int argc, char **argv) { Gudhi::graph_induced_complex::Graph_induced_complex GIC; GIC.set_verbose(verb); - GIC.set_graph_from_automatic_rips(off_file_name); - GIC.set_function_from_file(func_file_name); GIC.set_color_from_file(func_file_name); + GIC.set_function_from_file(func_file_name); + + GIC.set_graph_from_automatic_rips(off_file_name); + GIC.set_automatic_resolution_for_GICMAP(); GIC.set_gain(); GIC.set_cover_from_function(1); + GIC.find_GICMAP_simplices_with_functional_minimal_cover(); + GIC.plot_with_KeplerMapper(); Simplex_tree stree; GIC.create_complex(stree); diff --git a/src/Nerve_GIC/example/Nerve.cpp b/src/Nerve_GIC/example/Nerve.cpp index d4a68c71..a0de31ae 100644 --- a/src/Nerve_GIC/example/Nerve.cpp +++ b/src/Nerve_GIC/example/Nerve.cpp @@ -16,11 +16,6 @@ int main(int argc, char **argv) { double gain = atof(argv[4]); bool verb = 0; if(argc == 6) verb = 1; - // Type definitions - using Graph_t = boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS,\ - boost::property < vertex_filtration_t, Filtration_value >,\ - boost::property < edge_filtration_t, Filtration_value > >; - // -------------------------------- // Init of a Nerve from an OFF file // -------------------------------- @@ -28,12 +23,16 @@ int main(int argc, char **argv) { Gudhi::graph_induced_complex::Graph_induced_complex GIC; GIC.set_verbose(verb); - GIC.set_graph_from_OFF(off_file_name); + GIC.set_color_from_coordinate(off_file_name, coord); GIC.set_function_from_coordinate(coord, off_file_name); - GIC.set_color_from_coordinate(off_file_name, --coord); + + GIC.set_graph_from_OFF(off_file_name); + GIC.set_resolution_int(resolution); GIC.set_gain(gain); GIC.set_cover_from_function(0); + GIC.find_Nerve_simplices(); + GIC.plot_with_KeplerMapper(); Simplex_tree stree; GIC.create_complex(stree); diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index e9b7a1f1..205aa87e 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include @@ -51,11 +53,18 @@ #define ETA 0.001 #define MASK 0 +namespace gss = Gudhi::spatial_searching; + using Simplex_tree = Gudhi::Simplex_tree<>; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Point = std::vector; +typedef CGAL::Epick_d > K; +typedef typename K::Point_d Pointd; +typedef std::vector Pointsd; +typedef gss::Kd_tree_search Points_ds; + std::map func; std::map func_color; @@ -88,14 +97,14 @@ namespace graph_induced_complex { class Graph_induced_complex { private: - bool verbose; - typedef int Cover_t; + bool verbose; // whether to display information. + typedef int Cover_t; // elements of cover C are indexed by integers. std::vector > simplices; std::map > cover; - int maximal_dim; - int data_dimension; - std::map cover_fct; - std::map > cover_color; + int maximal_dim; // maximal dimension of output simplicial complex. + int data_dimension; // dimension of input data. + std::map cover_fct; // integer-valued function that allows to state if two elements of the cover are consecutive or not. + std::map > cover_color; // size and coloring of the vertices of the output simplicial complex. Simplex_tree<> st; std::map > adjacency_matrix; int resolution_int; @@ -187,10 +196,10 @@ class Graph_induced_complex { * */ void set_graph_from_OFF(const std::string& off_file_name){ - int numpts, numedges, numfaces, i; std::vector edge(2); double x; int num; std::vector simplex; + int n, numedges, numfaces, i; std::vector edge(2); double x; int num; std::vector simplex; std::ifstream input(off_file_name); std::string line; getline(input, line); - input >> numpts; input >> numfaces; input >> numedges; - i = 0; while(i < numpts){input >> x; input >> x; input >> x; i++;} + input >> n; input >> numfaces; input >> numedges; + i = 0; while(i < n){input >> x; input >> x; input >> x; i++;} i = 0; while(i < numfaces){ simplex.clear(); input >> num; for(int j = 0; j < num; j++){int k; input >> k; simplex.push_back(k);} @@ -204,7 +213,7 @@ class Graph_induced_complex { } std::vector empty; - for(int i = 0; i < numpts; i++) adjacency_matrix.insert(std::pair >(i,empty)); + for(int i = 0; i < n; i++) adjacency_matrix.insert(std::pair >(i,empty)); for (auto simplex : st.complex_simplex_range()) { if(st.dimension(simplex) == 1){ std::vector vertices; @@ -292,7 +301,7 @@ class Graph_induced_complex { } } - #pragma omp parallel for + //#pragma omp parallel for for (int i = 0; i < N; i++){ SampleWithoutReplacement(n,m,samples); @@ -349,8 +358,8 @@ class Graph_induced_complex { */ void set_function_from_coordinate(const int& k, const std::string& off_file_name){ Points_off_reader off_reader(off_file_name); - int numpts = off_reader.get_point_cloud().size(); - for(int i = 0; i < numpts; i++) func.insert(std::pair(i,off_reader.get_point_cloud()[i][k])); + int n = off_reader.get_point_cloud().size(); + for(int i = 0; i < n; i++) func.insert(std::pair(i,off_reader.get_point_cloud()[i][k])); } public: // Set function from vector. @@ -360,7 +369,8 @@ class Graph_induced_complex { * */ void set_function_from_vector(const std::vector& function){ - for(int i = 0; i < function.size(); i++) func.insert(std::pair(i, function[i])); + int n = function.size(); + for(int i = 0; i < n; i++) func.insert(std::pair(i, function[i])); } // ******************************************************************************************************************* @@ -379,12 +389,56 @@ class Graph_induced_complex { std::ifstream input(cover_file_name); std::string line; while(std::getline(input,line)){ cov_elts.clear(); std::stringstream stream(line); - while(stream >> cov){cov_elts.push_back(cov); cov_number.push_back(cov); cover_fct.insert(std::pair(cov,cov));} - cover.insert(std::pair >(vertex_id, cov_elts)); vertex_id++; + while(stream >> cov){ + cov_elts.push_back(cov); cov_number.push_back(cov); + cover_fct[cov] = cov; cover_color[cov].second += func_color[vertex_id]; cover_color[cov].first++; + } + cover[vertex_id] = cov_elts; vertex_id++; } std::vector::iterator it; std::sort(cov_number.begin(),cov_number.end()); it = std::unique(cov_number.begin(),cov_number.end()); - cov_number.resize(std::distance(cov_number.begin(),it)); maximal_dim = cov_number.size(); + cov_number.resize(std::distance(cov_number.begin(),it)); maximal_dim = cov_number.size()-1; + for(int i = 0; i <= maximal_dim; i++) cover_color[i].second /= cover_color[i].first; + } + + public: // Set cover from Voronoi + /** \brief Creates the cover C from the Voronoï cells of a subsampling of the point cloud. + * + * @param[in] m number of points in the subsample. + * @param[in] off_file_name name of the input .OFF file. + * + */ + void set_cover_from_Voronoi(const int& m, const std::string& off_file_name){ + Points_off_reader off_reader(off_file_name); + int n = off_reader.get_point_cloud().size(); data_dimension = off_reader.get_point_cloud()[0].size(); + Pointsd pointsd(m+1); std::vector samples(m); SampleWithoutReplacement(n,m,samples); + double* coord = new double[data_dimension]; + + for(int i = 1; i <= m; i++){ + for(int j = 0; j < data_dimension; j++) coord[j] = off_reader.get_point_cloud()[samples[i-1]][j]; + pointsd[i] = Pointd(data_dimension, coord+0, coord + data_dimension); cover_fct[i-1] = i-1; + } std::cout << std::endl; + + int curr_subsample = 0; + for(int i = 0; i < n; i++){ + for(int j = 0; j < data_dimension; j++) coord[j] = off_reader.get_point_cloud()[i][j]; + pointsd[0] = Pointd(data_dimension, coord+0, coord + data_dimension); Points_ds points_ds(pointsd); + auto knn_range = points_ds.query_k_nearest_neighbors(pointsd[0], 2, true); + Cover_t cluster = (knn_range.begin()+1)->first-1; + if(cluster >= 0){ // Case where i is not a subsample point. + cover[i].push_back(cluster); cover_color[cluster].second += func_color[i]; cover_color[cluster].first++; + } + else{ // Case where i is a subsample point. + cover[i].push_back(curr_subsample); cover_color[curr_subsample].second += func_color[i]; + cover_color[curr_subsample].first++; curr_subsample++; + } + } + + for(int i = 0; i < m; i++) cover_color[i].second /= cover_color[i].first; + + delete [] coord; + maximal_dim = m-1; + } public: // Automatic tuning of resolution for Mapper Delta. @@ -448,9 +502,10 @@ class Graph_induced_complex { void set_cover_from_function(const bool& token){ // Read function values and compute min and max - std::map::iterator it; double maxf, minf; minf = std::numeric_limits::max(); maxf = std::numeric_limits::min(); + std::map::iterator it; + double maxf, minf; minf = std::numeric_limits::max(); maxf = std::numeric_limits::min(); for(it = func.begin(); it != func.end(); it++){minf = std::min(minf, it->second); maxf = std::max(maxf, it->second);} - int num_pts = func.size(); if(verbose) std::cout << "Min function value = " << minf << " and Max function value = " << maxf << std::endl; + int n = func.size(); if(verbose) std::cout << "Min function value = " << minf << " and Max function value = " << maxf << std::endl; // Compute cover of im(f) std::vector > intervals; int res; @@ -477,40 +532,41 @@ class Graph_induced_complex { y = x + resolution_double; } std::pair interM(x,maxf); intervals.push_back(interM); res = intervals.size(); - for(int i = 0; i < res; i++) if(verbose) std::cout << "Interval " << i << " = [" << intervals[i].first << ", " << intervals[i].second << "]" << std::endl; + for(int i = 0; i < res; i++) if(verbose) std::cout << "Interval " << i << " = [" << \ + intervals[i].first << ", " << intervals[i].second << "]" << std::endl; } // Sort points according to function values - std::vector points(num_pts); for(int i = 0; i < num_pts; i++) points[i] = i; + std::vector points(n); for(int i = 0; i < n; i++) points[i] = i; std::sort(points.begin(),points.end(),functional_comp); - int id = 0; int pos = 0; double min_prop_int; double max_prop_int; + int id = 0; int pos = 0; for(int i = 0; i < res; i++){ // Find points in the preimage std::map > prop; prop.clear(); - std::pair inter1 = intervals[i]; min_prop_int = inter1.first; + std::pair inter1 = intervals[i]; int tmp = pos; if(i != res-1){ if(i != 0){ - std::pair inter3 = intervals[i-1]; min_prop_int = inter3.second; - while(func[points[tmp]] < inter3.second && tmp != num_pts){ + std::pair inter3 = intervals[i-1]; + while(func[points[tmp]] < inter3.second && tmp != n){ prop.insert(std::pair >(points[tmp],adjacency_matrix[points[tmp]])); tmp++; } } - std::pair inter2 = intervals[i+1]; max_prop_int = inter2.first; - while(func[points[tmp]] < inter2.first && tmp != num_pts){ + std::pair inter2 = intervals[i+1]; + while(func[points[tmp]] < inter2.first && tmp != n){ prop.insert(std::pair >(points[tmp],adjacency_matrix[points[tmp]])); tmp++; } pos = tmp; - while(func[points[tmp]] < inter1.second && tmp != num_pts){ + while(func[points[tmp]] < inter1.second && tmp != n){ prop.insert(std::pair >(points[tmp],adjacency_matrix[points[tmp]])); tmp++; } @@ -520,13 +576,12 @@ class Graph_induced_complex { else{ std::pair inter3 = intervals[i-1]; - min_prop_int = inter3.second; max_prop_int = inter1.second; - while(func[points[tmp]] < inter3.second && tmp != num_pts){ + while(func[points[tmp]] < inter3.second && tmp != n){ prop.insert(std::pair >(points[tmp],adjacency_matrix[points[tmp]])); tmp++; } - while(tmp != num_pts){ + while(tmp != n){ prop.insert(std::pair >(points[tmp],adjacency_matrix[points[tmp]])); tmp++; } @@ -552,7 +607,7 @@ class Graph_induced_complex { if(verbose) std::cout << std::endl; } - maximal_dim = id; + maximal_dim = id-1; } @@ -583,8 +638,8 @@ class Graph_induced_complex { */ void set_color_from_coordinate(const std::string& off_file_name, int k = 0){ Points_off_reader off_reader(off_file_name); - int numpts = off_reader.get_point_cloud().size(); - for(int i = 0; i < numpts; i++) func_color.insert(std::pair(i,off_reader.get_point_cloud()[i][k])); + int n = off_reader.get_point_cloud().size(); + for(int i = 0; i < n; i++) func_color[i] = off_reader.get_point_cloud()[i][k]; } public: // Set color from vector. @@ -594,7 +649,7 @@ class Graph_induced_complex { * */ void set_color_from_vector(const std::vector& color){ - for(int i = 0; i < color.size(); i++) func_color.insert(std::pair(i, color[i])); + for(unsigned int i = 0; i < color.size(); i++) func_color.insert(std::pair(i, color[i])); } public: // Create a .dot file that can be compiled with neato to produce a .pdf file @@ -605,7 +660,7 @@ class Graph_induced_complex { double maxv, minv; maxv = std::numeric_limits::min(); minv = std::numeric_limits::max(); for (std::map >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++){ maxv = std::max(maxv, iit->second.second); minv = std::min(minv, iit->second.second); - } + } //std::cout << minv << " " << maxv << std::endl; int k = 0; std::vector nodes; nodes.clear(); for (std::map >::iterator iit = cover_color.begin(); iit != cover_color.end(); iit++){ if(iit->second.first > MASK){ @@ -622,6 +677,9 @@ class Graph_induced_complex { if (cover_color[simplices[i][0]].first > MASK && cover_color[simplices[i][1]].first > MASK){ graphic << " " << simplices[i][0] << " -- " << simplices[i][1] << " [weight=15];" << std::endl; ke++;} graphic << "}"; graphic.close(); + char command[100]; sprintf(command, "neato SC.dot -Tpdf -o SC_visu.pdf && rm SC.dot"); + int systemRet = system(command); + if(systemRet == -1) std::cout << "Visualization failed. Do you have neato?" << std::endl; } public: // Create a .txt file that can be compiled with KeplerMapper to produce a .html file @@ -649,6 +707,9 @@ class Graph_induced_complex { if (cover_color[simplices[i][0]].first > MASK && cover_color[simplices[i][1]].first > MASK) graphic << simplices[i][0] << " " << simplices[i][1] << std::endl; graphic.close(); + char command[100]; sprintf(command, "python visu.py && firefox SC_visu.html"); + int systemRet = system(command); + if(systemRet == -1) std::cout << "Visualization failed. Do you have python and firefox?" << std::endl; } // ******************************************************************************************************************* @@ -663,8 +724,8 @@ class Graph_induced_complex { */ template void create_complex(SimplicialComplexForGIC & complex) { - size_t sz = simplices.size(); int dimension = 0; - for(int i = 0; i < sz; i++){ + size_t sz = simplices.size(); unsigned int dimension = 0; + for(unsigned int i = 0; i < sz; i++){ complex.insert_simplex_and_subfaces(simplices[i]); if(dimension < simplices[i].size()-1) dimension = simplices[i].size()-1; } @@ -681,7 +742,7 @@ class Graph_induced_complex { int num_nodes = cover_elts.size(); std::vector simplex; for(int i = 0; i < num_nodes; i++) - for(int j = 0; j < cover_elts[i].size(); j++) + for(unsigned int j = 0; j < cover_elts[i].size(); j++) simplex.push_back(cover_elts[i][j]); std::sort(simplex.begin(),simplex.end()); std::vector::iterator it = std::unique(simplex.begin(),simplex.end()); simplex.resize(std::distance(simplex.begin(),it)); diff --git a/src/Nerve_GIC/test/CMakeLists.txt b/src/Nerve_GIC/test/CMakeLists.txt new file mode 100644 index 00000000..627778fa --- /dev/null +++ b/src/Nerve_GIC/test/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 2.6) +project(Graph_induced_complex_tests) + +if (GCOVR_PATH) + # for gcovr to make coverage reports - Corbera Jenkins plugin + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") +endif() +if (GPROF_PATH) + # for gprof to make coverage reports - Jenkins + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") +endif() + +add_executable ( graph_induced_complex_UT test_GIC.cpp ) +target_link_libraries(graph_induced_complex_UT ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(graph_induced_complex_UT ${TBB_LIBRARIES}) +endif() + +file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + +add_test(graph_induced_complex_UT ${CMAKE_CURRENT_BINARY_DIR}/graph_induced_complex_UT + # XML format for Jenkins xUnit plugin + --log_format=XML --log_sink=${CMAKE_SOURCE_DIR}/graph_induced_complex_UT.xml --log_level=test_suite --report_level=no) diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index e6f29fa8..b1625e69 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -93,6 +93,24 @@ User manual: \ref simplex_tree - Reference manual: Gudhi::Simplex_tree + + \subsection GICDataStructure Nerves and Graph Induced Complexes + \image html "gic_complex.png" "Graph Induced Complex of a point cloud." + + + + +
+ Author: Mathieu Carrière
+ Introduced in: GUDHI 2.0.1
+ Copyright: GPL v3
+
+ Nerves and Graph Induced Complexes are simplicial complexes that provably contain + topological information about the input data. They can be computed with a cover of the + data, that often comes from the preimage of a family of intervals covering the image + of a scalar-valued function defined on the data.
+ User manual: \ref graph_induced_complex - Reference manual: Gudhi::graph_induced_complex::Graph_induced_complex +
\subsection SkeletonBlockerDataStructure Skeleton blocker \image html "ds_representation.png" "Skeleton blocker representation" -- cgit v1.2.3 From 0654bfbab17fe16edf90445f0a351454b460028f Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 30 May 2017 15:20:29 +0000 Subject: Fix spell checker errors git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/persistence_representation_integration@2475 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 94422e6f356532b2db4dc5a55cbb851210b3c36d --- CMakeLists.txt | 16 +- src/CMakeLists.txt | 12 +- src/Doxyfile | 4 +- .../concept/Real_valued_topological_data.h | 21 ++- .../concept/Topological_data_with_averages.h | 11 +- .../concept/Topological_data_with_distances.h | 22 ++- .../concept/Topological_data_with_scalar_product.h | 15 +- .../concept/Vectorized_topological_data.h | 15 +- .../doc/Persistence_representations_doc.h | 52 +++--- .../example/persistence_heat_maps.cpp | 4 +- .../example/persistence_intervals.cpp | 4 +- .../example/persistence_landscape.cpp | 4 +- .../example/persistence_landscape_on_grid.cpp | 2 +- .../include/gudhi/PSSK.h | 15 +- .../include/gudhi/Persistence_heat_maps.h | 85 +++++---- .../include/gudhi/Persistence_intervals.h | 106 +++--------- .../gudhi/Persistence_intervals_with_distances.h | 12 +- .../include/gudhi/Persistence_landscape.h | 116 +++++-------- .../include/gudhi/Persistence_landscape_on_grid.h | 192 ++++++--------------- .../include/gudhi/Persistence_vectors.h | 105 ++++------- .../gudhi/common_persistence_representations.h | 28 ++- .../include/gudhi/read_persistence_from_file.h | 104 ++--------- .../compute_distance_of_persistence_heat_maps.cpp | 9 +- ...h_m_weighted_by_arctan_of_their_persistence.cpp | 4 +- ...te_p_h_m_weighted_by_distance_from_diagonal.cpp | 4 +- ...ate_p_h_m_weighted_by_squared_diag_distance.cpp | 2 +- .../create_persistence_heat_maps.cpp | 2 +- .../persistence_heat_maps/create_pssk.cpp | 2 +- .../plot_persistence_heat_map.cpp | 2 +- .../compute_bottleneck_distance.cpp | 2 +- .../plot_histogram_of_intervals_lengths.cpp | 2 +- .../plot_persistence_Betti_numbers.cpp | 7 +- .../compute_distance_of_landscapes.cpp | 2 +- .../persistence_landscapes/plot_landscapes.cpp | 2 +- .../compute_distance_of_landscapes_on_grid.cpp | 6 +- .../plot_landscapes_on_grid.cpp | 2 +- .../compute_distance_of_persistence_vectors.cpp | 3 +- .../create_persistence_vectors.cpp | 3 +- src/cmake/modules/GUDHI_user_version_target.txt | 2 +- src/common/doc/main_page.h | 13 +- src/common/include/gudhi/distance_functions.h | 5 + 41 files changed, 384 insertions(+), 635 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c772506..30306885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ include_directories(src/Spatial_searching/include/) include_directories(src/Subsampling/include/) include_directories(src/Tangential_complex/include/) include_directories(src/Witness_complex/include/) -include_directories(src/Gudhi_stat/include/) +include_directories(src/Persistence_representations/include/) add_subdirectory(src/common/example) add_subdirectory(src/common/test) @@ -82,13 +82,13 @@ add_subdirectory(src/Bottleneck_distance/test) add_subdirectory(src/Bottleneck_distance/benchmark) add_subdirectory(src/Rips_complex/example) add_subdirectory(src/Rips_complex/test) -add_subdirectory(src/Gudhi_stat/test) -add_subdirectory(src/Gudhi_stat/example) -add_subdirectory(src/Gudhi_stat/utilities/persistence_heat_maps) -add_subdirectory(src/Gudhi_stat/utilities/persistence_intervals) -add_subdirectory(src/Gudhi_stat/utilities/persistence_landscapes) -add_subdirectory(src/Gudhi_stat/utilities/persistence_landscapes_on_grid) -add_subdirectory(src/Gudhi_stat/utilities/persistence_vectors) +add_subdirectory(src/Persistence_representations/test) +add_subdirectory(src/Persistence_representations/example) +add_subdirectory(src/Persistence_representations/utilities/persistence_heat_maps) +add_subdirectory(src/Persistence_representations/utilities/persistence_intervals) +add_subdirectory(src/Persistence_representations/utilities/persistence_landscapes) +add_subdirectory(src/Persistence_representations/utilities/persistence_landscapes_on_grid) +add_subdirectory(src/Persistence_representations/utilities/persistence_vectors) # data points generator add_subdirectory(data/points/generator) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe4eb677..06e479be 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,12 +52,12 @@ add_subdirectory(example/Spatial_searching) add_subdirectory(example/Subsampling) add_subdirectory(example/Tangential_complex) add_subdirectory(example/Bottleneck_distance) -add_subdirectory(example/Gudhi_stat) -add_subdirectory(utilities/Gudhi_stat/persistence_heat_maps) -add_subdirectory(utilities/Gudhi_stat/persistence_intervals) -add_subdirectory(utilities/Gudhi_stat/persistence_landscapes) -add_subdirectory(utilities/Gudhi_stat/persistence_landscapes_on_grid) -add_subdirectory(utilities/Gudhi_stat/persistence_vectors) +add_subdirectory(example/Persistence_representations) +add_subdirectory(utilities/Persistence_representations/persistence_heat_maps) +add_subdirectory(utilities/Persistence_representations/persistence_intervals) +add_subdirectory(utilities/Persistence_representations/persistence_landscapes) +add_subdirectory(utilities/Persistence_representations/persistence_landscapes_on_grid) +add_subdirectory(utilities/Persistence_representations/persistence_vectors) # data points generator add_subdirectory(data/points/generator) diff --git a/src/Doxyfile b/src/Doxyfile index f4df4e84..eb0b3e9e 100644 --- a/src/Doxyfile +++ b/src/Doxyfile @@ -852,7 +852,7 @@ IMAGE_PATH = doc/Skeleton_blocker/ \ doc/Spatial_searching/ \ doc/Tangential_complex/ \ doc/Bottleneck_distance/ \ - doc/Gudhi_stat/ + doc/Persistence_representations/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -2116,7 +2116,7 @@ COLLABORATION_GRAPH = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling diff --git a/src/Persistence_representations/concept/Real_valued_topological_data.h b/src/Persistence_representations/concept/Real_valued_topological_data.h index 4d4ee8d3..5a15c769 100644 --- a/src/Persistence_representations/concept/Real_valued_topological_data.h +++ b/src/Persistence_representations/concept/Real_valued_topological_data.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,6 +20,14 @@ * along with this program. If not, see . */ +#ifndef CONCEPT_REAL_VALUED_TOPOLOGICAL_DATA_H_ +#define CONCEPT_REAL_VALUED_TOPOLOGICAL_DATA_H_ + +namespace Gudhi { + +namespace Persistence_representations { + + /** \brief The concept Real_valued_topological_data describes the requirements * for a type to implement a container that allows computations of its projections to R. */ @@ -27,12 +35,19 @@ class Real_valued_topological_data { public: /** - * Typically there are various ways data can be projected to R. This function give us the number of functions for vectorization provided by a given class. + * Typically there are various ways data can be projected to R. This function gives us the number of functions for + * vectorization provided by a given class. **/ size_t number_of_projections_to_R(); /** - * This is a function to compute the projection from this container to reals. The parameter of a function have to be between 0 and the value returned by number_of_projections_to_R(). + * This is a function to compute the projection from this container to reals. The parameter of a function have to + * be between 0 and the value returned by number_of_projections_to_R(). **/ double project_to_R( size_t number_of_projection ); }; +} // namespace Persistence_representations + +} // namespace Gudhi + +#endif // CONCEPT_REAL_VALUED_TOPOLOGICAL_DATA_H_ diff --git a/src/Persistence_representations/concept/Topological_data_with_averages.h b/src/Persistence_representations/concept/Topological_data_with_averages.h index aeeb94f0..0501c306 100644 --- a/src/Persistence_representations/concept/Topological_data_with_averages.h +++ b/src/Persistence_representations/concept/Topological_data_with_averages.h @@ -5,7 +5,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -21,7 +21,12 @@ * along with this program. If not, see . */ +#ifndef CONCEPT_TOPOLOGICAL_DATA_WITH_AVERAGES_H_ +#define CONCEPT_TOPOLOGICAL_DATA_WITH_AVERAGES_H_ +namespace Gudhi { + +namespace Persistence_representations { /** \brief The concept Topological_data_with_averages describes the requirements * for a type to implement a container that allows computations of averages. @@ -33,4 +38,8 @@ public: void compute_average( const std::vector< Topological_data_with_averages* >& to_average ); }; +} // namespace Persistence_representations + +} // namespace Gudhi +#endif // CONCEPT_TOPOLOGICAL_DATA_WITH_AVERAGES_H_ diff --git a/src/Persistence_representations/concept/Topological_data_with_distances.h b/src/Persistence_representations/concept/Topological_data_with_distances.h index 1318b9d1..2e6de729 100644 --- a/src/Persistence_representations/concept/Topological_data_with_distances.h +++ b/src/Persistence_representations/concept/Topological_data_with_distances.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,11 +20,22 @@ * along with this program. If not, see . */ +#ifndef CONCEPT_TOPOLOGICAL_DATA_WITH_DISTANCES_H_ +#define CONCEPT_TOPOLOGICAL_DATA_WITH_DISTANCES_H_ + +namespace Gudhi { + +namespace Persistence_representations { + + /** \brief The concept Topological_data_with_distances describes the requirements - * for a type to implement a container that allows computations of distance to another contained of that type. + * for a type to implement a container that allows computations of distance to another contained of that type. + * \details * The second parameter of the distance function allow to declare power of a distance. The exact meaning of that * number will be different for different distances. A few examples are given below: - * In case of p-Wasserstein distance, the power is equal to p. power = std::limit::max() for bottleneck distance. + * In case of p-Wasserstein distance, the power is equal to p. power = std::limit::max() for bottleneck + * distance. + * * In case of L^p landscape distance, the power is equal to p. s */ class Topological_data_with_distances @@ -33,3 +44,8 @@ public: double distance( const Topological_data_with_distances& second , double power = 1); }; +} // namespace Persistence_representations + +} // namespace Gudhi + +#endif // CONCEPT_TOPOLOGICAL_DATA_WITH_DISTANCES_H_ diff --git a/src/Persistence_representations/concept/Topological_data_with_scalar_product.h b/src/Persistence_representations/concept/Topological_data_with_scalar_product.h index f32271c7..203a1d91 100644 --- a/src/Persistence_representations/concept/Topological_data_with_scalar_product.h +++ b/src/Persistence_representations/concept/Topological_data_with_scalar_product.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,6 +20,13 @@ * along with this program. If not, see . */ +#ifndef CONCEPT_TOPOLOGICAL_DATA_WITH_SCALAR_PRODUCT_H_ +#define CONCEPT_TOPOLOGICAL_DATA_WITH_SCALAR_PRODUCT_H_ + +namespace Gudhi { + +namespace Persistence_representations { + /** \brief The concept Topological_data_with_scalar_product describes the requirements * for a type to implement a container that allows computations of scalar products. @@ -29,3 +36,9 @@ class Topological_data_with_scalar_product public: double compute_scalar_product( const Topological_data_with_scalar_product& second ); }; + +} // namespace Persistence_representations + +} // namespace Gudhi + +#endif // CONCEPT_TOPOLOGICAL_DATA_WITH_SCALAR_PRODUCT_H_ diff --git a/src/Persistence_representations/concept/Vectorized_topological_data.h b/src/Persistence_representations/concept/Vectorized_topological_data.h index 2dd966fd..8d4105a2 100644 --- a/src/Persistence_representations/concept/Vectorized_topological_data.h +++ b/src/Persistence_representations/concept/Vectorized_topological_data.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,6 +20,12 @@ * along with this program. If not, see . */ +#ifndef CONCEPT_VECTORIZED_TOPOLOGICAL_DATA_H_ +#define CONCEPT_VECTORIZED_TOPOLOGICAL_DATA_H_ + +namespace Gudhi { + +namespace Persistence_representations { /** \brief The concept Vectorized_topological_data describes the requirements * for a type to implement a container that allows vectorization. @@ -28,7 +34,7 @@ class Vectorized_topological_data { public: /** - * There are various ways data can be verctorized. This function give us the number of functions for vectorization provided by a given class. + * There are various ways data can be vectorized. This function give us the number of functions for vectorization provided by a given class. **/ size_t number_of_vectorize_functions(); /** @@ -37,3 +43,8 @@ public: std::vector vectorize( int number_of_function ); }; +} // namespace Persistence_representations + +} // namespace Gudhi + +#endif // CONCEPT_VECTORIZED_TOPOLOGICAL_DATA_H_ diff --git a/src/Persistence_representations/doc/Persistence_representations_doc.h b/src/Persistence_representations/doc/Persistence_representations_doc.h index 215616a0..bc11d2c4 100644 --- a/src/Persistence_representations/doc/Persistence_representations_doc.h +++ b/src/Persistence_representations/doc/Persistence_representations_doc.h @@ -28,12 +28,12 @@ namespace Gudhi { namespace Persistence_representations { -/** \defgroup Persistence_representations Persistence_representations +/** \defgroup Persistence_representations Persistence representations * * \author Pawel Dlotko * * @{ - *\section idea Idea + *\section Persistence_representations_idea Idea *In order to perform most of the statistical tests and machine learning algorithms on a data one need to be able to perform only a very limited number of operations on them. Let us fix a representation of * data of a type A. To perform most of the statistical and machine learning operations one need to be able to compute average of objects of type A (so that the averaged object is also of a type A), to @@ -71,24 +71,24 @@ namespace Persistence_representations { *\li Persistence diagrams / barcodes (allow computation of distances, vectorizations and real value characteristics). * * - *Note that at the while functionalities like averaging, distances and scalar products are fixed, there is no canonical way of vectorizing and computing real valued characteristics of objects. Therefore the + * Note that at the while functionalities like averaging, distances and scalar products are fixed, there is no canonical way of vectorizing and computing real valued characteristics of objects. Therefore the * vectorizations and computation of real value characteristics procedures are quite likely to evolve in the furthering versions of the library. * - *The main aim of this implementation is to be able to implement various statistical methods, both on the level of C++ and on the level of python. The methods will operate on the functionalities offered + * The main aim of this implementation is to be able to implement various statistical methods, both on the level of C++ and on the level of python. The methods will operate on the functionalities offered * by concepts. That means that the statistical and ML methods will be able to operate on any representation that implement the required concept (including the ones that are not in the library at the moment). * That gives provides a framework, that is very easy to extend, for topological statistics. * - *Below we are discussing the representations which are currently implemented in Persistence\_representations package: + * Below we are discussing the representations which are currently implemented in Persistence\_representations package: * - *\section sec_persistence_landscapes Persistence Landscapes - * Reference manual: \ref Gudhi::Persistence_representations::Persistence_landscape - *Persistence landscapes were originally proposed by Bubenik in \cite bubenik_landscapes_2015. Efficient algorithms to compute them rigorously were proposed by Bubenik and Dlotko in \cite bubenik_dlotko_landscapes_2016. The idea of + * \section sec_persistence_landscapes Persistence Landscapes + * Reference manual: \ref Gudhi::Persistence_representations::Persistence_landscape
+ * Persistence landscapes were originally proposed by Bubenik in \cite bubenik_landscapes_2015. Efficient algorithms to compute them rigorously were proposed by Bubenik and Dlotko in \cite bubenik_dlotko_landscapes_2016. The idea of * persistence landscapes is shortly summarized in below. * - *To begin with, suppose we are given a point \f$(b,d) \in \mathbb{R}^2\f$ in a - *persistence diagram. With this point, we associate a piecewise - *linear function \f$f_{(b,d)} : \mathbb{R} \rightarrow [0,\infty)\f$, which is - *defined as + * To begin with, suppose we are given a point \f$(b,d) \in \mathbb{R}^2\f$ in a + * persistence diagram. With this point, we associate a piecewise + * linear function \f$f_{(b,d)} : \mathbb{R} \rightarrow [0,\infty)\f$, which is + * defined as * * \f[f_{(b,d)}(x) = * \left\{ \begin{array}{ccl} @@ -100,16 +100,16 @@ namespace Persistence_representations { * \end{array} \right. *\f] * - *A persistence landscape of the birth-death - *pairs \f$(b_i , d_i)\f$, where \f$i = 1,\ldots,m\f$, which constitute the given - *persistence diagram is the sequence of functions \f$\lambda_k : \mathbb{R} \rightarrow [0,\infty)\f$ for \f$k \in \mathbb{N}\f$, where \f$\lambda_k(x)\f$ - *denotes the \f$k^{\rm th}\f$ largest value of the numbers \f$f_{(b_i,d_i)}(x)\f$, - *for \f$i = 1, \ldots, m\f$, and we define \f$\lambda_k(x) = 0\f$ if \f$k > m\f$. - *Equivalently, this sequence of functions can be combined into a single - *function \f$L : \mathbb{N} \times \mathbb{R} \to [0,\infty)\f$ of two - *variables, if we define \f$L(k,t) = \lambda_k(t)\f$. + * A persistence landscape of the birth-death + * pairs \f$(b_i , d_i)\f$, where \f$i = 1,\ldots,m\f$, which constitute the given + * persistence diagram is the sequence of functions \f$\lambda_k : \mathbb{R} \rightarrow [0,\infty)\f$ for \f$k \in \mathbb{N}\f$, where \f$\lambda_k(x)\f$ + * denotes the \f$k^{\rm th}\f$ largest value of the numbers \f$f_{(b_i,d_i)}(x)\f$, + * for \f$i = 1, \ldots, m\f$, and we define \f$\lambda_k(x) = 0\f$ if \f$k > m\f$. + * Equivalently, this sequence of functions can be combined into a single + * function \f$L : \mathbb{N} \times \mathbb{R} \to [0,\infty)\f$ of two + * variables, if we define \f$L(k,t) = \lambda_k(t)\f$. * - *The detailed description of algorithms used to compute persistence landscapes can be found in \cite bubenik_dlotko_landscapes_2016. + * The detailed description of algorithms used to compute persistence landscapes can be found in \cite bubenik_dlotko_landscapes_2016. * Note that this implementation provides exact representation of landscapes. That have many advantages, but also a few drawbacks. For instance, as discussed * in \cite bubenik_dlotko_landscapes_2016, the exact representation of landscape may be of quadratic size with respect to the input persistence diagram. It may therefore happen * that, for very large diagrams, using this representation may be memory--prohibitive. In such a case, there are two possible ways to proceed: @@ -120,13 +120,13 @@ namespace Persistence_representations { * * *\section sec_landscapes_on_grid Persistence Landscapes on a grid - * Reference manual: \ref Gudhi::Persistence_representations::Persistence_landscape_on_grid - *This is an alternative, not--exact, representation of persistence landscapes defined in the Section \ref sec_persistence_landscapes. Unlike in the Section \ref sec_persistence_landscapes we build a + * Reference manual: \ref Gudhi::Persistence_representations::Persistence_landscape_on_grid
+ * This is an alternative, not--exact, representation of persistence landscapes defined in the Section \ref sec_persistence_landscapes. Unlike in the Section \ref sec_persistence_landscapes we build a * representation of persistence landscape by sampling its values on a finite, equally distributed grid of points. * Since, the persistence landscapes that originate from persistence diagrams have slope \f$1\f$ or \f$-1\f$, we have an estimate of a region between the grid points where the landscape cab be located. * That allows to estimate an error make when performing various operations on landscape. Note that for average landscapes the slope is in range \f$[-1,1]\f$ and similar estimate can be used. * - *Due to a lack of rigorous description of the algorithms to deal with this non--rigorous representaion of persistence landscapes in the literature, we are providing a short discussion of them in below. + * Due to a lack of rigorous description of the algorithms to deal with this non--rigorous representation of persistence landscapes in the literature, we are providing a short discussion of them in below. * *Let us assume that we want to compute persistence landscape on a interval \f$[x,y]\f$. Let us assume that we want to use \f$N\f$ grid points for that purpose. * Then we will sample the persistence landscape on points \f$x_1 = x , x_2 = x + \frac{y-x}{N}, \ldots , x_{N} = y\f$. Persistence landscapes are represented as a vector of @@ -153,7 +153,7 @@ namespace Persistence_representations { *Note that the same representation is used in TDA R-package \cite Fasy_Kim_Lecci_Maria_tda. * *\section sec_persistence_heat_maps Persistence heat maps - * Reference manual: \ref Gudhi::Persistence_representations::Persistence heat maps + * Reference manual: \ref Gudhi::Persistence_representations::Persistence_heat_maps
*This is a general class of discrete structures which are based on idea of placing a kernel in the points of persistence diagrams. *This idea appeared in work by many authors over the last 15 years. As far as we know this idea was firstly described in the work of Bologna group in \cite Ferri_Frosini_comparision_sheme_1 and \cite Ferri_Frosini_comparision_sheme_2. *Later it has been described by Colorado State University group in \cite Persistence_Images_2017. The presented paper in the first time provide a discussion of stability of the representation. @@ -177,7 +177,7 @@ namespace Persistence_representations { * * *\section sec_persistence_vectors Persistence vectors - * Reference manual: \ref Gudhi::Persistence_representations::Persistence vectors + * Reference manual: \ref Gudhi::Persistence_representations::Vector_distances_in_diagram
*This is a representation of persistent homology in a form of a vector which was designed for an application in 3d graphic in \cite Carriere_Oudot_Ovsjanikov_top_signatures_3d. Below we provide a short description of this representation. * *Given a persistence diagram \f$D = \{ (b_i,d_i) \}\f$, for every pair of birth--death points \f$(b_1,d_1)\f$ and \f$(b_2,d_2)\f$ we compute the following three distances: diff --git a/src/Persistence_representations/example/persistence_heat_maps.cpp b/src/Persistence_representations/example/persistence_heat_maps.cpp index da87486d..c75e2731 100644 --- a/src/Persistence_representations/example/persistence_heat_maps.cpp +++ b/src/Persistence_representations/example/persistence_heat_maps.cpp @@ -55,7 +55,7 @@ int main( int argc , char** argv ) persistence2.push_back( std::make_pair(3,5) ); persistence2.push_back( std::make_pair(6,10) ); - //over here we define a function we sill put on a top on every birth--death pair in the persistence interval. It can be anything. Over here we will use standarg Gaussian + //over here we define a function we sill put on a top on every birth--death pair in the persistence interval. It can be anything. Over here we will use standard Gaussian std::vector< std::vector > filter = create_Gaussian_filter(5,1); //creating two heat maps. @@ -72,7 +72,7 @@ int main( int argc , char** argv ) Persistence_heat_maps median; median.compute_median( vector_of_maps ); - //to compute L^1 disance between hm1 and hm2: + //to compute L^1 distance between hm1 and hm2: std::cout << "The L^1 distance is : " << hm1.distance( hm2 , 1 ) << std::endl; //to average of hm1 and hm2: diff --git a/src/Persistence_representations/example/persistence_intervals.cpp b/src/Persistence_representations/example/persistence_intervals.cpp index ed5b4e34..947c9627 100644 --- a/src/Persistence_representations/example/persistence_intervals.cpp +++ b/src/Persistence_representations/example/persistence_intervals.cpp @@ -47,7 +47,7 @@ int main( int argc , char** argv ) std::vector dominant_ten_intervals_length = p.length_of_dominant_intervals(10); - std::cout << "Lendth of ten dominant intervals : " < cumulative_histogram = p.cumulative_histogram_of_lengths( 10 ); - std::cout<< "Cumuative histogram : " <. */ -#pragma once -#ifndef PSSK_H -#define PSSK_H +#ifndef PSSK_H_ +#define PSSK_H_ //gudhi include #include @@ -138,7 +137,7 @@ void PSSK::construct( const std::vector< std::pair >& intervals_ std::cerr << "y_grid : " << y_grid << std::endl; } - //x_grid and y_grid gives a center of the kernel. We want to have its lower left cordner. To get this, we need to shift x_grid and y_grid by a grid diameter. + //x_grid and y_grid gives a center of the kernel. We want to have its lower left corner. To get this, we need to shift x_grid and y_grid by a grid diameter. x_grid -= filter.size()/2; y_grid -= filter.size()/2; //note that the numbers x_grid and y_grid may be negative. @@ -174,8 +173,8 @@ void PSSK::construct( const std::vector< std::pair >& intervals_ } }//construct +} //namespace Persistence_representations +} //namespace Gudhi -#endif -}//namespace Gudhi_stat -}//namespace Gudhi +#endif // PSSK_H_ diff --git a/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h b/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h index 59e58e41..a20702ff 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h +++ b/src/Persistence_representations/include/gudhi/Persistence_heat_maps.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef Persistence_heat_maps_H -#define Persistence_heat_maps_H +#ifndef PERSISTENCE_HEAT_MAPS_H_ +#define PERSISTENCE_HEAT_MAPS_H_ //standard include #include @@ -69,7 +69,7 @@ std::vector< std::vector > create_Gaussian_filter( size_t pixel_radius , if ( dbg ) { - std::cerr << "Kernel initalize \n"; + std::cerr << "Kernel initialize \n"; std::cerr << "pixel_radius : " << pixel_radius << std::endl; std::cerr << "kernel.size() : " << kernel.size() << std::endl; getchar(); @@ -114,7 +114,7 @@ std::vector< std::vector > create_Gaussian_filter( size_t pixel_radius , /* -* There are various options to scale the poits depending on their location. One can for instance: +* There are various options to scale the points depending on their location. One can for instance: * (1) do nothing (scale all of them with the weight 1), as in the function constant_function * (2) Scale them by the distance to the diagonal. This is implemented in function * (3) Scale them with the square of their distance to diagonal. This is implemented in function @@ -123,8 +123,8 @@ std::vector< std::vector > create_Gaussian_filter( size_t pixel_radius , /** - * This is one of a scaling functions used to weight poits depending on their persistence and/or location in the diagram. - * This particular functiona is a finction which always assign value 1 to a point in the diagram. + * This is one of a scaling functions used to weight points depending on their persistence and/or location in the diagram. + * This particular functionality is a function which always assign value 1 to a point in the diagram. **/ class constant_scaling_function { @@ -137,7 +137,7 @@ public: /** - * This is one of a scaling functions used to weight poits depending on their persistence and/or location in the diagram. + * This is one of a scaling functions used to weight points depending on their persistence and/or location in the diagram. * The scaling given by this function to a point (b,d) is Euclidean distance of (b,d) from diagonal. **/ class distance_from_diagonal_scaling @@ -151,7 +151,7 @@ public: }; /** - * This is one of a scaling functions used to weight poits depending on their persistence and/or location in the diagram. + * This is one of a scaling functions used to weight points depending on their persistence and/or location in the diagram. * The scaling given by this function to a point (b,d) is a square of Euclidean distance of (b,d) from diagonal. **/ class squared_distance_from_diagonal_scaling @@ -164,7 +164,7 @@ public: }; /** - * This is one of a scaling functions used to weight poits depending on their persistence and/or location in the diagram. + * This is one of a scaling functions used to weight points depending on their persistence and/or location in the diagram. * The scaling given by this function to a point (b,d) is an arctan of a persistence of a point (i.e. arctan( b-d ). **/ class arc_tan_of_persistence_of_point @@ -177,7 +177,7 @@ public: }; /** - * This is one of a scaling functions used to weight poits depending on their persistence and/or location in the diagram. + * This is one of a scaling functions used to weight points depending on their persistence and/or location in the diagram. * This scaling function do not only depend on a point (p,d) in the diagram, but it depends on the whole diagram. * The longest persistence pair get a scaling 1. Any other pair get a scaling belong to [0,1], which is proportional * to the persistence of that pair. @@ -196,14 +196,19 @@ private: /** - * This class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product -**/ + * \class Persistence_heat_maps Persistence_heat_maps.h gudhi/Persistence_heat_maps.h + * \brief A class implementing persistence heat maps. + * + * \ingroup Persistence_representations +**/ + +// This class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product template class Persistence_heat_maps { public: /** - * The default constructor. A scaling function from the diagonal is set up to a constant function. The image is not erased below the diagonal. The gaussian have diameter 5. + * The default constructor. A scaling function from the diagonal is set up to a constant function. The image is not erased below the diagonal. The Gaussian have diameter 5. **/ Persistence_heat_maps() { @@ -217,7 +222,7 @@ public: /** * Construction that takes at the input the following parameters: * (1) A vector of pairs of doubles (representing persistence intervals). All other parameters are optional. They are: - * (2) a Gausian filter generated by create_Gaussian_filter filter (the default value of this vaiable is a Gaussian filter of a radius 5), + * (2) a Gaussian filter generated by create_Gaussian_filter filter (the default value of this variable is a Gaussian filter of a radius 5), * (3) a boolean value which determines if the area of image below diagonal should, or should not be erased (it will be erased by default). * (4) a number of pixels in each direction (set to 1000 by default). * (5) a min x and y value of points that are to be taken into account. By default it is set to std::numeric_limits::max(), in which case the program compute the values based on the data, @@ -226,12 +231,12 @@ public: Persistence_heat_maps( const std::vector< std::pair< double,double > > & interval , std::vector< std::vector > filter = create_Gaussian_filter(5,1) , bool erase_below_diagonal = false , size_t number_of_pixels = 1000 , double min_ = std::numeric_limits::max() , double max_ = std::numeric_limits::max() ); /** - * Construction that takes at the input a name of a file with persistence intervals, a filter (radius 5 by default), a scaling function (constant by default), a boolean value which determines if the area of image below diagonal should, or should not be erased (should by default). The next parameter is the number of pixels in each direction (set to 1000 by default). and min and max values of images (both set to std::numeric_limits::max() by defaulet. If this is the case, the program will pick the right values based on the data). + * Construction that takes at the input a name of a file with persistence intervals, a filter (radius 5 by default), a scaling function (constant by default), a boolean value which determines if the area of image below diagonal should, or should not be erased (should by default). The next parameter is the number of pixels in each direction (set to 1000 by default) and min and max values of images (both set to std::numeric_limits::max() by default. If this is the case, the program will pick the right values based on the data). **/ /** * Construction that takes at the input the following parameters: - * (1) A a name of a file with persistence intervals. The file shold be readable by the function read_persistence_intervals_in_one_dimension_from_file. All other parameters are optional. They are: - * (2) a Gausian filter generated by create_Gaussian_filter filter (the default value of this vaiable is a Gaussian filter of a radius 5), + * (1) A name of a file with persistence intervals. The file should be readable by the function read_persistence_intervals_in_one_dimension_from_file. All other parameters are optional. They are: + * (2) a Gaussian filter generated by create_Gaussian_filter filter (the default value of this variable is a Gaussian filter of a radius 5), * (3) a boolean value which determines if the area of image below diagonal should, or should not be erased (it will be erased by default). * (4) a number of pixels in each direction (set to 1000 by default). * (5) a min x and y value of points that are to be taken into account. By default it is set to std::numeric_limits::max(), in which case the program compute the values based on the data, @@ -259,14 +264,14 @@ public: //put to file subroutine /** - * The function outputs the perssitence image to a text file. The format as follow: + * The function outputs the persistence image to a text file. The format as follow: * In the first line, the values min and max of the image are stored * In the next lines, we have the persistence images in a form of a bitmap image. **/ void print_to_file( const char* filename )const; /** - * A function that load a heat map from file to the current object (and arase qhatever was stored in the current object before). + * A function that load a heat map from file to the current object (and erase whatever was stored in the current object before). **/ void load_from_file( const char* filename ); @@ -347,7 +352,7 @@ public: /** - * A function to generate a gnuplot script to vizualize the persistent image. + * A function to generate a gnuplot script to visualize the persistent image. **/ void plot( const char* filename )const; @@ -474,7 +479,7 @@ public: //Implementations of functions for various concepts. /** - * This function produce a vector of doubles based on a persisence heat map. It is required in a concept Vectorized_topological_data + * This function produce a vector of doubles based on a persistence heat map. It is required in a concept Vectorized_topological_data */ std::vector vectorize( int number_of_function )const; /** @@ -486,9 +491,9 @@ public: } /** - * This function is required by the Real_valued_topological_data concept. It returns various projections od the persistence heat map to a real line. - * At the moment this function is not tested, since it is quite likelly to be changed in the future. Given this, when using it, keep in mind that it - * will be most likelly changed in the next versions. + * This function is required by the Real_valued_topological_data concept. It returns various projections on the persistence heat map to a real line. + * At the moment this function is not tested, since it is quite likely to be changed in the future. Given this, when using it, keep in mind that it + * will be most likely changed in the next versions. **/ double project_to_R( int number_of_function )const; /** @@ -515,7 +520,7 @@ public: /** * A function to compute scalar product of persistence heat maps. - * The parameter of this functionis a const reference to an object of a class Persistence_heat_maps. + * The parameter of this function is a const reference to an object of a class Persistence_heat_maps. * This function is required in Topological_data_with_scalar_product concept. **/ double compute_scalar_product( const Persistence_heat_maps& second_ )const; @@ -559,7 +564,6 @@ protected: } //data - //double (*scalling_function_with_respect_to_distance_from_diagonal)( const std::pair< double , double >& point_in_diagram ); Scalling_of_kernels f; bool erase_below_diagonal; double min_; @@ -583,7 +587,7 @@ void Persistence_heat_maps::construct( const std::vector< s if ( min_ == max_ ) { - if (dbg)std::cerr << "min and max parameters will be etermined based on intervals \n"; + if (dbg)std::cerr << "min and max parameters will be determined based on intervals \n"; //in this case, we want the program to set up the min_ and max_ values by itself. min_ = std::numeric_limits::max(); max_ = -std::numeric_limits::max(); @@ -636,7 +640,7 @@ void Persistence_heat_maps::construct( const std::vector< s std::cerr << "y_grid : " << y_grid << std::endl; } - //x_grid and y_grid gives a center of the kernel. We want to have its lower left cordner. To get this, we need to shift x_grid and y_grid by a grid diameter. + //x_grid and y_grid gives a center of the kernel. We want to have its lower left corner. To get this, we need to shift x_grid and y_grid by a grid diameter. x_grid -= filter.size()/2; y_grid -= filter.size()/2; //note that the numbers x_grid and y_grid may be negative. @@ -711,11 +715,6 @@ Persistence_heat_maps::Persistence_heat_maps( const char* f { intervals_ = read_persistence_intervals_in_one_dimension_from_file( filename , dimension ); } - //std::cerr << "intervals_.size() : " << intervals_.size() << std::endl; - //for ( size_t i = 0 ; i != intervals_.size() ; ++i ) - //{ - // std::cerr << intervals_[i].first << " " << intervals_[i].second << std::endl; - //} this->construct( intervals_ , filter, erase_below_diagonal , number_of_pixels , min_ , max_ ); this->set_up_parameters_for_basic_classes(); } @@ -956,11 +955,11 @@ double Persistence_heat_maps::distance( const Persistence_h //first we need to check if (*this) and second are defined on the same domain and have the same dimensions: if ( !this->check_if_the_same(second) ) { - std::cerr << "The persistence images are of noncompatible sizes. We cannot therefore compute distance between them. The program will now terminate"; - throw "The persistence images are of noncompatible sizes. We cannot therefore compute distance between them. The program will now terminate"; + std::cerr << "The persistence images are of non compatible sizes. We cannot therefore compute distance between them. The program will now terminate"; + throw "The persistence images are of non compatible sizes. We cannot therefore compute distance between them. The program will now terminate"; } - //if we are here, we know that the two persistence iomages are defined on the same domain, so we can start computing their distances: + //if we are here, we know that the two persistence images are defined on the same domain, so we can start computing their distances: double distance = 0; if ( power < std::numeric_limits::max() ) @@ -1016,11 +1015,11 @@ double Persistence_heat_maps::compute_scalar_product( const //first we need to check if (*this) and second are defined on the same domain and have the same dimensions: if ( !this->check_if_the_same(second) ) { - std::cerr << "The persistence images are of noncompatible sizes. We cannot therefore compute distance between them. The program will now terminate"; - throw "The persistence images are of noncompatible sizes. We cannot therefore compute distance between them. The program will now terminate"; + std::cerr << "The persistence images are of non compatible sizes. We cannot therefore compute distance between them. The program will now terminate"; + throw "The persistence images are of non compatible sizes. We cannot therefore compute distance between them. The program will now terminate"; } - //if we are here, we know that the two persistence iomages are defined on the same domain, so we can start computing their scalar product: + //if we are here, we know that the two persistence images are defined on the same domain, so we can start computing their scalar product: double scalar_prod = 0; for ( size_t i = 0 ; i != this->heat_map.size() ; ++i ) { @@ -1035,8 +1034,8 @@ double Persistence_heat_maps::compute_scalar_product( const -}//namespace Gudhi_stat -}//namespace Gudhi +} // namespace Persistence_representations +} // namespace Gudhi -#endif +#endif // PERSISTENCE_HEAT_MAPS_H_ diff --git a/src/Persistence_representations/include/gudhi/Persistence_intervals.h b/src/Persistence_representations/include/gudhi/Persistence_intervals.h index 792c0a28..40c24670 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_intervals.h +++ b/src/Persistence_representations/include/gudhi/Persistence_intervals.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef Persistence_intervals_H_ -#define Persistence_intervals_H_ +#ifndef PERSISTENCE_INTERVALS_H_ +#define PERSISTENCE_INTERVALS_H_ //gudhi include #include @@ -48,14 +48,14 @@ class Persistence_intervals { public: /** - * This is a constructor of a class Persistence_intervals from a text file. Each line of the input file is supposed to contain two numbers of a type doube (or convertable to double) + * This is a constructor of a class Persistence_intervals from a text file. Each line of the input file is supposed to contain two numbers of a type double (or convertible to double) * representing the birth and the death of the persistence interval. If the pairs are not sorted so that birth <= death, then the constructor will sort then that way. - * * The second parameter of a constructor is a dimension of intervals to be read from a file. If your file contains only birt-death pairs, use the default value. + * * The second parameter of a constructor is a dimension of intervals to be read from a file. If your file contains only birth-death pairs, use the default value. **/ Persistence_intervals( const char* filename , unsigned dimension = std::numeric_limits::max() ); /** - * This is a constructor of a class Persistence_intervals from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elemnets of pairs + * This is a constructor of a class Persistence_intervals from a vector of pairs. Each pair is assumed to represent a persistence interval. We assume that the first elements of pairs * are smaller or equal the second elements of pairs. **/ Persistence_intervals( const std::vector< std::pair< double,double > >& intervals ); @@ -102,15 +102,15 @@ public: std::vector< std::pair > dominant_intervals( size_t where_to_cut = 100 )const; /** - * Procedure to compute a histogram of interva's length. A histogram is a block plot. The number of blocks is determined by the first parameter of the function (set by default to 10). + * Procedure to compute a histogram of interval's length. A histogram is a block plot. The number of blocks is determined by the first parameter of the function (set by default to 10). * For the sake of argument let us assume that the length of the longest interval is 1 and the number of bins is 10. In this case the i-th block correspond to a range between i-1/10 and i10. * The vale of a block supported at the interval is the number of persistence intervals of a length between x_0 and x_1. **/ std::vector< size_t > histogram_of_lengths( size_t number_of_bins = 10 )const; /** - * Based on a histogram of intervals lengts computed by the function histogram_of_lengths H the procedure below computes the cumulative histogram. The i-th position of the resulting histogram - * is the sume of values of H for the positions from 0 to i. + * Based on a histogram of intervals lengths computed by the function histogram_of_lengths H the procedure below computes the cumulative histogram. The i-th position of the resulting histogram + * is the sum of values of H for the positions from 0 to i. **/ std::vector< size_t > cumulative_histogram_of_lengths( size_t number_of_bins = 10 )const; @@ -127,13 +127,13 @@ public: std::vector< double > cumulative_characteristic_function_of_diagram( double x_min , double x_max , size_t number_of_bins = 10 )const; /** - * Compute the funtion of persistence Betti numbers. The returned value is a vector of pair. First element of each pair is a place where persistence Betti numbers change. + * Compute the function of persistence Betti numbers. The returned value is a vector of pair. First element of each pair is a place where persistence Betti numbers change. * Second element of each pair is the value of Persistence Betti numbers at that point. **/ std::vector< std::pair< double , size_t > > compute_persistent_betti_numbers()const; /** - *This is a non optimal procedure that compute vector of distances from each point of diagram to its k-th nearest neighbor (k is a parameted of the program). The resulting vector is by default truncated to 10 + *This is a non optimal procedure that compute vector of distances from each point of diagram to its k-th nearest neighbor (k is a parameter of the program). The resulting vector is by default truncated to 10 *elements (this value can be changed by using the second parameter of the program). The points are returned in order from the ones which are farthest away from their k-th nearest neighbors. **/ std::vector< double > k_n_n( size_t k , size_t where_to_cut = 10 )const; @@ -188,12 +188,9 @@ public: std::cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '" << nameStr << "' in gnuplot to visualize." << std::endl; } - - - /** - * Retun numbr of points in the diagram. + * Return number of points in the diagram. **/ size_t size()const{return this->intervals.size();} @@ -207,25 +204,12 @@ public: } - - - - - - - - - - - - - //Implementations of functions for various concepts. /** - * This is a simple function projectig the persistence intervals to a real number. The function we use here is a sum of squared lendgths of intervals. It can be naturally interpreted as + * This is a simple function projecting the persistence intervals to a real number. The function we use here is a sum of squared lengths of intervals. It can be naturally interpreted as * sum of step function, where the step hight it equal to the length of the interval. - * At the moment this function is not tested, since it is quite likelly to be changed in the future. Given this, when using it, keep in mind that it - * will be most likelly changed in the next versions. + * At the moment this function is not tested, since it is quite likely to be changed in the future. Given this, when using it, keep in mind that it + * will be most likely changed in the next versions. **/ double project_to_R( int number_of_function )const; /** @@ -237,14 +221,14 @@ public: } /** - * Return a familly of vectors obtained from the persistence diagram. The i-th vector consist of the lenfth of i dominant persistence intervals. + * Return a family of vectors obtained from the persistence diagram. The i-th vector consist of the length of i dominant persistence intervals. **/ std::vector vectorize( int number_of_function )const { return this->length_of_dominant_intervals( number_of_function ); } /** - * This function return the number of functions that allows vectorization of a persisence diagram. It is required in a concept Vectorized_topological_data. + * This function return the number of functions that allows vectorization of a persistence diagram. It is required in a concept Vectorized_topological_data. **/ size_t number_of_vectorize_functions()const { @@ -252,19 +236,7 @@ public: } //end of implementation of functions needed for concepts. - //end of implementation of functions needed for concepts. - - - - - - - - - - - - + //For visualization use output from vectorize and build histograms. std::vector< std::pair< double,double > > output_for_visualization() @@ -289,37 +261,6 @@ protected: Persistence_intervals::Persistence_intervals( const char* filename , unsigned dimension ) { - //bool dbg = false; - //ifstream in; - //in.open( filename ); - - //if ( !in.good() ) - //{ - // throw("File with the persistence diagram do not exist, the program will now terminate.\n"); - //} - - //while ( true ) - //{ - // double first; - // double second; - // in >> first >> second; - - // if ( first > second ) - // { - // double buf = first; - // first = second; - // second = buf; - // } - - // if ( in.eof() )break; - // this->intervals.push_back( std::make_pair( first,second ) ); - // if ( dbg ) - // { - // std::cerr << "Adding interval [ " << first << " , " << second << " ]\n"; - // getchar(); - // } - //} - //in.close(); if ( dimension == std::numeric_limits::max() ) { this->intervals = read_persistence_intervals_in_one_dimension_from_file( filename ); @@ -490,7 +431,6 @@ std::vector< double > Persistence_intervals::characteristic_function_of_diagram( { result[pos] += ( (x_max - x_min)/(double)number_of_bins ) * ( this->intervals[i].second - this->intervals[i].first ); } - //cerr << "x_max : " << x_max << " x_min : " << x_min << " , number_of_bins : " << number_of_bins << " this->intervals[i].second : " << this->intervals[i].second << " this->intervals[i].first : " << this->intervals[i].first << endl; if ( dbg ) { std::cerr << "Result at this stage \n"; @@ -499,7 +439,6 @@ std::vector< double > Persistence_intervals::characteristic_function_of_diagram( std::cerr << result[aa] << " "; } std::cerr << std::endl; - //getchar(); } } return result; @@ -599,8 +538,7 @@ std::vector< double > Persistence_intervals::k_n_n( size_t k , size_t where_to_c { distancesFromI.push_back( compute_euclidean_distance( this->intervals[i] , this->intervals[j] ) ); } - //distances.push_back( distancesFromI ); - //also add a distance from this guy to daigonal: + //also add a distance from this guy to diagonal: double distanceToDiagonal = compute_euclidean_distance( this->intervals[i] , std::make_pair( 0.5*(this->intervals[i].first + this->intervals[i].second) , 0.5*(this->intervals[i].first + this->intervals[i].second) ) ); distances_from_diagonal[i] = distanceToDiagonal; @@ -694,7 +632,7 @@ double Persistence_intervals::project_to_R( int number_of_function )const } -}//namespace gudhi stat -}//namespace gudhi +} // namespace Persistence_representations +} // namespace gudhi -#endif +#endif // PERSISTENCE_INTERVALS_H_ 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 7ef711e9..0da58399 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h +++ b/src/Persistence_representations/include/gudhi/Persistence_intervals_with_distances.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef Persistence_intervals_WITH_DISTANCES_H_ -#define Persistence_intervals_WITH_DISTANCES_H_ +#ifndef PERSISTENCE_INTERVALS_WITH_DISTANCES_H_ +#define PERSISTENCE_INTERVALS_WITH_DISTANCES_H_ #include @@ -59,7 +59,7 @@ public: }; -}//namespace gudhi stat -}//namespace gudhi +} // namespace Persistence_representations +} // namespace gudhi -#endif +#endif // PERSISTENCE_INTERVALS_WITH_DISTANCES_H_ diff --git a/src/Persistence_representations/include/gudhi/Persistence_landscape.h b/src/Persistence_representations/include/gudhi/Persistence_landscape.h index 9a177b60..642bba84 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_landscape.h +++ b/src/Persistence_representations/include/gudhi/Persistence_landscape.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -21,8 +21,8 @@ */ -#ifndef Persistence_landscapes_H -#define Persistence_landscapes_H +#ifndef PERSISTENCE_LANDSCAPE_H_ +#define PERSISTENCE_LANDSCAPE_H_ //standard include #include @@ -48,7 +48,7 @@ namespace Persistence_representations -//predeclaration +// pre declaration class Persistence_landscape; template < typename operation > Persistence_landscape operation_on_pair_of_landscapes( const Persistence_landscape& land1 , const Persistence_landscape& land2 ); @@ -56,12 +56,25 @@ Persistence_landscape operation_on_pair_of_landscapes( const Persistence_landsca /** - * A clas implementing persistence landascpes data structures. For theroretical desciritpion, please consult a paper ''Statistical topological data analysis using persistence landscapes'' by Peter Bubenik. - * For details of algorithms, please consult ''A persistence landscapes toolbox for topological statistics'' by Peter Bubenik and Pawel Dlotko. - * Persistence landscapes allow vertorization, computations of distances, computations of projections to Real, computations of averages and scalar products. Therefore they implement suitable interfaces. - * It implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product - * Note that at the moment, due to roundoff errors during the construction of persistence landscapes, elements which are different by 0.000005 are considered the same. If the scale in your persistence diagrams - * is comparable to this value, please rescale them before use this code. + * \class Persistence_landscape Persistence_landscape.h gudhi/Persistence_landscape.h + * \brief A class implementing persistence landscapes data structures. + * + * \ingroup Persistence_representations + * + * \details + * For theoretical description, please consult Statistical topological data analysis using persistence + * landscapes\cite bubenik_landscapes_2015 , and for details of algorithms, + * A persistence landscapes toolbox for topological statistics\cite bubenik_dlotko_landscapes_2016. + * + * Persistence landscapes allow vectorization, computations of distances, computations of projections to Real, + * computations of averages and scalar products. Therefore they implement suitable interfaces. + * It implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, + * Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product + * + * Note that at the moment, due to rounding errors during the construction of persistence landscapes, elements which + * are different by 0.000005 are considered the same. If the scale in your persistence diagrams is comparable to this + * value, please rescale them before use this code. + * **/ class Persistence_landscape { @@ -169,7 +182,7 @@ public: } /** - * An operator * that allows multipilication of a landscape by a real number. + * An operator * that allows multiplication of a landscape by a real number. **/ friend Persistence_landscape operator*( const Persistence_landscape& first , double con ) { @@ -177,7 +190,7 @@ public: } /** - * An operator * that allows multipilication of a landscape by a real number (order of parameters swapped). + * An operator * that allows multiplication of a landscape by a real number (order of parameters swapped). **/ friend Persistence_landscape operator*( double con , const Persistence_landscape& first ) { @@ -297,7 +310,6 @@ public: *\private Computations of \f$L^{\infty}\f$ distance between two landscapes. **/ friend double compute_max_norm_distance_of_landscapes( const Persistence_landscape& first, const Persistence_landscape& second ); - //friend double compute_max_norm_distance_of_landscapes( const Persistence_landscape& first, const Persistence_landscape& second , unsigned& nrOfLand , double&x , double& y1, double& y2 ); /** @@ -308,7 +320,7 @@ public: /** - * Function to compute absolute value of a PL function. The representation of persistence landscapes allow to store general PL-function. When computing distance betwen two landscapes, we compute difference between + * Function to compute absolute value of a PL function. The representation of persistence landscapes allow to store general PL-function. When computing distance between two landscapes, we compute difference between * them. In this case, a general PL-function with negative value can appear as a result. Then in order to compute distance, we need to take its absolute value. This is the purpose of this procedure. **/ Persistence_landscape abs(); @@ -319,7 +331,7 @@ public: size_t size()const{return this->land.size(); } /** - * Computate maximal value of lambda-level landscape. + * Compute maximal value of lambda-level landscape. **/ double find_max( unsigned lambda )const; @@ -328,27 +340,13 @@ public: **/ friend double compute_inner_product( const Persistence_landscape& l1 , const Persistence_landscape& l2 ); - - - - - - - - - - - - - - //Implementations of functions for various concepts. /** * The number of projections to R is defined to the number of nonzero landscape functions. I-th projection is an integral of i-th landscape function over whole R. * This function is required by the Real_valued_topological_data concept. - * At the moment this function is not tested, since it is quite likelly to be changed in the future. Given this, when using it, keep in mind that it - * will be most likelly changed in the next versions. + * At the moment this function is not tested, since it is quite likely to be changed in the future. Given this, when using it, keep in mind that it + * will be most likely changed in the next versions. **/ double project_to_R( int number_of_function )const { @@ -382,7 +380,7 @@ public: return v; } /** - * This function return the number of functions that allows vectorization of persistence laandscape. It is required in a concept Vectorized_topological_data. + * This function return the number of functions that allows vectorization of persistence landscape. It is required in a concept Vectorized_topological_data. **/ size_t number_of_vectorize_functions()const { @@ -404,8 +402,8 @@ public: { nextLevelMerge[i] = to_average[i]; } - bool is_this_first_level = true;//in the loop, we will create dynamically a unmber of intermediate complexes. We have to clean that up, but we cannot erase the initial andscapes we have - //to average. In this case, we simply check if the nextLevelMerge are the input landscapes or the ones created in that loop by usig this extra variable. + bool is_this_first_level = true;//in the loop, we will create dynamically a number of intermediate complexes. We have to clean that up, but we cannot erase the initial landscapes we have + //to average. In this case, we simply check if the nextLevelMerge are the input landscapes or the ones created in that loop by using this extra variable. while ( nextLevelMerge.size() != 1 ) { @@ -446,7 +444,7 @@ public: /** * A function to compute distance between persistence landscape. - * The parameter of this functionis a Persistence_landscape. + * The parameter of this function is a Persistence_landscape. * This function is required in Topological_data_with_distances concept. * For max norm distance, set power to std::numeric_limits::max() **/ @@ -465,7 +463,7 @@ public: /** * A function to compute scalar product of persistence landscapes. - * The parameter of this functionis a Persistence_landscape. + * The parameter of this function is a Persistence_landscape. * This function is required in Topological_data_with_scalar_product concept. **/ double compute_scalar_product( const Persistence_landscape& second )const @@ -473,25 +471,6 @@ public: return compute_inner_product( (*this) , second ); } //end of implementation of functions needed for concepts. - - - // - // This procedure returns x-range of a given level persistence landscape. If a default value is used, the x-range - //of 0th level landscape is given (and this range contains the ranges of all other landscapes). - // - //std::pair< double , double > get_x_range( size_t level = 0 )const - //{ - // std::pair< double , double > result; - // if ( level < this->land.size() ) - // { - // result = std::make_pair( this->land[level][1].first , this->land[level][ this->land[level].size() - 2 ].first ); - // } - // else - // { - // result = std::make_pair( 0,0 ); - // } - // return result; - //} /** * This procedure returns y-range of a given level persistence landscape. If a default value is used, the y-range @@ -582,7 +561,6 @@ bool Persistence_landscape::operator == ( const Persistence_landscape& rhs )con { if ( !( almost_equal(this->land[level][i].first , rhs.land[level][i].first) && almost_equal(this->land[level][i].second , rhs.land[level][i].second) ) ) { - //std::cerr<< this->land[level][i].first << " , " << rhs.land[level][i].first << " and " << this->land[level][i].second << " , " << rhs.land[level][i].second << std::endl; if (operatorEqualDbg)std::cerr << "this->land[level][i] : " << this->land[level][i].first << " " << this->land[level][i].second << "\n"; if (operatorEqualDbg)std::cerr << "rhs.land[level][i] : " << rhs.land[level][i].first << " " << rhs.land[level][i].second << "\n"; if (operatorEqualDbg)std::cerr << "3\n"; @@ -768,7 +746,7 @@ double Persistence_landscape::compute_integral_of_landscape()const { for ( size_t nr = 2 ; nr != this->land[i].size()-1 ; ++nr ) { - //it suffices to compute every planar integral and then sum them ap for each lambda_n + //it suffices to compute every planar integral and then sum them up for each lambda_n result += 0.5*( this->land[i][nr].first - this->land[i][nr-1].first )*(this->land[i][nr].second + this->land[i][nr-1].second); } } @@ -780,7 +758,7 @@ double Persistence_landscape::compute_integral_of_a_level_of_a_landscape( size_t double result = 0; if ( level >= this->land.size() ) { - //this landscape function is constantly equal 0, so is the intergral. + //this landscape function is constantly equal 0, so is the integral. return result; } //also negative landscapes are assumed to be zero. @@ -788,7 +766,7 @@ double Persistence_landscape::compute_integral_of_a_level_of_a_landscape( size_t for ( size_t nr = 2 ; nr != this->land[ level ].size()-1 ; ++nr ) { - //it suffices to compute every planar integral and then sum them ap for each lambda_n + //it suffices to compute every planar integral and then sum them up for each lambda_n result += 0.5*( this->land[ level ][nr].first - this->land[ level ][nr-1].first )*(this->land[ level ][nr].second + this->land[ level ][nr-1].second); } @@ -826,7 +804,6 @@ double Persistence_landscape::compute_integral_of_landscape( double p )const std::cout << "result : " << result << std::endl; } } - //if (compute_integral_of_landscapeDbg) std::cin.ignore(); } return result; } @@ -953,7 +930,7 @@ Persistence_landscape Persistence_landscape::abs() for ( size_t i = 1 ; i != this->land[level].size() ; ++i ) { if ( AbsDbg ){std::cout << "this->land[" << level << "][" << i << "] : " << this->land[level][i].first << " " << this->land[level][i].second << std::endl;} - //if a line segment between this->land[level][i-1] and this->land[level][i] crosses the x-axis, then we have to add one landscape point t oresult + //if a line segment between this->land[level][i-1] and this->land[level][i] crosses the x-axis, then we have to add one landscape point t o result if ( (this->land[level][i-1].second)*(this->land[level][i].second) < 0 ) { double zero = find_zero_of_a_line_segment_between_those_two_points( this->land[level][i-1] , this->land[level][i] ); @@ -1025,7 +1002,7 @@ void Persistence_landscape::load_landscape_from_file( const char* filename ) this->land.clear(); - //this constructor reads persistence landscape form a file. This file have to be created by this software beforehead + //this constructor reads persistence landscape form a file. This file have to be created by this software before head std::ifstream in; in.open( filename ); if ( !in.good() ) @@ -1049,7 +1026,7 @@ void Persistence_landscape::load_landscape_from_file( const char* filename ) lineSS >> beginn; lineSS >> endd; landscapeAtThisLevel.push_back( std::make_pair( beginn , endd ) ); - if (dbg){std::cerr << "Reading a pont : " << beginn << " , " << endd << std::endl;} + if (dbg){std::cerr << "Reading a point : " << beginn << " , " << endd << std::endl;} } else { @@ -1117,7 +1094,6 @@ Persistence_landscape operation_on_pair_of_landscapes ( const Persistence_landsc std::cerr << "land2.land[" << i << "].size() : " << land2.land[i].size() << std::endl; std::cout << "land1.land[i][p].first : " << land1.land[i][p].first << "\n"; std::cout << "land2.land[i][q].first : " << land2.land[i][q].first << "\n"; - //getchar(); } if ( land1.land[i][p].first < land2.land[i][q].first ) @@ -1126,7 +1102,6 @@ Persistence_landscape operation_on_pair_of_landscapes ( const Persistence_landsc { std::cout << "first \n"; std::cout << " function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) : "<< function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) << "\n"; - //std::cout << "oper( " << land1.land[i][p].second <<"," << function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) << " : " << oper( land1.land[i][p].second , function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) ) << "\n"; } lambda_n.push_back( std::make_pair( @@ -1242,7 +1217,7 @@ double compute_maximal_distance_non_symmetric( const Persistence_landscape& pl1, } int p2Count = 0; - for ( size_t i = 1 ; i != pl1.land[level].size()-1 ; ++i ) //w tym przypadku nie rozwarzam punktow w nieskocznosci + for ( size_t i = 1 ; i != pl1.land[level].size()-1 ; ++i ) // In this case, I consider points at the infinity { while ( true ) { @@ -1488,11 +1463,8 @@ void Persistence_landscape::plot( const char* filename, double xRangeBegin , do std::cout << "Gnuplot script to visualize persistence diagram written to the file: " << nameStr << ". Type load '" << nameStr << "' in gnuplot to visualize." << std::endl; } +} // namespace Persistence_representations +} // namespace gudhi - -}//namespace gudhi stat -}//namespace gudhi - - -#endif +#endif // PERSISTENCE_LANDSCAPE_H_ diff --git a/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h b/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h index 5703163a..d663b543 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h +++ b/src/Persistence_representations/include/gudhi/Persistence_landscape_on_grid.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -21,8 +21,8 @@ * along with this program. If not, see . **/ -#ifndef Persistence_landscape_on_grid_H_ -#define Persistence_landscape_on_grid_H_ +#ifndef PERSISTENCE_LANDSCAPE_ON_GRID_H_ +#define PERSISTENCE_LANDSCAPE_ON_GRID_H_ //standard include @@ -50,16 +50,25 @@ namespace Gudhi namespace Persistence_representations { -//predeclaration +// pre declaration class Persistence_landscape_on_grid; template < typename operation > Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid( const Persistence_landscape_on_grid& land1 , const Persistence_landscape_on_grid& land2 ); /** - * A clas implementing persistence landascpes by approximating them on a collection of grid points. * Persistence landscapes on grid allow vertorization, computations of distances, computations - * of projections to Real, computations of averages and scalar products. Therefore they implement suitable interfaces. - * It implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product - * Note that at the moment, due to roundoff errors during the construction of persistence landscapes on a grid, elements which are different by 0.000005 are considered the same. If the scale in your persistence diagrams + * \class Persistence_landscape_on_grid Persistence_landscape_on_grid.h gudhi/Persistence_landscape_on_grid.h + * \brief A class implementing persistence landscapes by approximating them on a collection of grid points. + * + * \ingroup Persistence_representations + * + * \details + * Persistence landscapes on grid allows vectorization, computations of distances, computations of projections to Real, + * computations of averages and scalar products. Therefore they implement suitable interfaces. + * It implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, + * Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product + * + * Note that at the moment, due to rounding errors during the construction of persistence landscapes on a grid, + * elements which are different by 0.000005 are considered the same. If the scale in your persistence diagrams * is comparable to this value, please rescale them before use this code. **/ @@ -89,14 +98,14 @@ public: /** * 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. The additional parameters of this procedure are: ranges of grid, resoltion of a grid + * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameters of this procedure are: ranges of grid, resolution of a grid * number of landscape functions to be created and the dimension of intervals that are need to be read from a file (in case of Gudhi format files). **/ Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned number_of_levels_of_landscape , unsigned short dimension_ = 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. The additional parameters of this procedure are: ranges of grid, resoltion of a grid + * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameters of this procedure are: ranges of grid, resolution of a grid * and the dimension of intervals that are need to be read from a file (in case of Gudhi format files). **/ Persistence_landscape_on_grid(const char* filename , double grid_min_, double grid_max_ , size_t number_of_points_ , unsigned short dimension_ = std::numeric_limits::max() ); @@ -104,16 +113,16 @@ public: /** * 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. The additional parameter is the resoution of a grid and the number of landscape - * functions to be created. The remaning parameters are calculated based on data. + * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameter is the resolution of a grid and the number of landscape + * functions to be created. The remaining parameters are calculated based on data. **/ Persistence_landscape_on_grid(const char* filename , size_t number_of_points , unsigned number_of_levels_of_landscape , unsigned short dimension = 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. The additional parameter is the resoution of a grid. The last parameter is the dimension + * to be empty. Even if the points within a line are not ordered, they will be ordered while the input is read. The additional parameter is the resolution of a grid. The last parameter is the dimension * of a persistence to read from the file. If your file contains only persistence pair in a single dimension, please set it up to std::numeric_limits::max(). - * The remaning parameters are calculated based on data. + * The remaining parameters are calculated based on data. **/ Persistence_landscape_on_grid(const char* filename , size_t number_of_points , unsigned short dimension = std::numeric_limits::max() ); @@ -258,7 +267,7 @@ public: if ( dbg ) { std::cerr << "Increasing result by : " << value_to_add << std::endl; - std::cerr << "restult : " << result << std::endl; + std::cerr << "result : " << result << std::endl; getchar(); } previous_x = current_x; @@ -311,9 +320,9 @@ public: std::cerr << "This is a procedure compute_value_at_a_given_point \n"; std::cerr << "level : " << level << std::endl; std::cerr << "x : " << x << std::endl; - std::cerr << "psoition : " << position << std::endl; + std::cerr << "position : " << position << std::endl; } - //check if we are not exacly in the grid point: + //check if we are not exactly in the grid point: if ( almost_equal( position*dx+ this->grid_min , x) ) { if ( this->values_of_landscapes[position].size() < level ) @@ -389,7 +398,7 @@ public: } /** - * An operator * that allows multipilication of a landscape by a real number. + * An operator * that allows multiplication of a landscape by a real number. **/ friend Persistence_landscape_on_grid operator*( const Persistence_landscape_on_grid& first , double con ) { @@ -397,7 +406,7 @@ public: } /** - * An operator * that allows multipilication of a landscape by a real number (order of parameters swapped). + * An operator * that allows multiplication of a landscape by a real number (order of parameters swapped). **/ friend Persistence_landscape_on_grid operator*( double con , const Persistence_landscape_on_grid& first ) { @@ -413,7 +422,7 @@ public: } /** - * Operator +=. The second parameter is persistnece landwscape. + * Operator +=. The second parameter is persistence landscape. **/ Persistence_landscape_on_grid operator += ( const Persistence_landscape_on_grid& rhs ) { @@ -422,7 +431,7 @@ public: } /** - * Operator -=. The second parameter is persistnece landwscape. + * Operator -=. The second parameter is persistence landscape. **/ Persistence_landscape_on_grid operator -= ( const Persistence_landscape_on_grid& rhs ) { @@ -458,7 +467,7 @@ public: bool dbg = true; if ( this->values_of_landscapes.size() != rhs.values_of_landscapes.size() ) { - if (dbg) std::cerr << "values_of_landscapes of incompatable sizes\n"; + if (dbg) std::cerr << "values_of_landscapes of incompatible sizes\n"; return false; } if ( !almost_equal( this->grid_min , rhs.grid_min ) ) @@ -546,28 +555,6 @@ public: std::pair< double , double > get_x_range( size_t level = 0 )const { return std::make_pair( this->grid_min , this->grid_max ); - //std::pair< double , double > result; - //if ( level < this->land.size() ) - //{ - // double dx = (this->grid_max - this->grid_min)/(double)this->values_of_landscapes.size(); - // size_t first_nonzero = 0; - // while ( (first_nonzero != this->values_of_landscapes.size()) && (this->values_of_landscapes[level][first_nonzero] == 0) )++first_nonzero; - // - // if ( first_nonzero == 0 ) - // { - // return std::make_pair( 0,0 );//this landscape is empty. - // } - // - // size_t last_nonzero = 0; - // while ( (last_nonzero != 0) && (this->values_of_landscapes[level][last_nonzero] == 0) )--last_nonzero; - // - // result = std::make_pair( this->grid_min +first_nonzero*dx , this->grid_max - last_nonzero*dx ); - //} - //else - //{ - // result = std::make_pair( 0,0 ); - //} - //return result; } /** @@ -577,16 +564,6 @@ public: std::pair< double , double > get_y_range( size_t level = 0 )const { return this->compute_minimum_maximum(); - //std::pair< double , double > result; - //if ( level < this->land.size() ) - //{ - // result = this->compute_minimum_maximum() - //} - //else - //{ - // result = std::make_pair( 0,0 ); - //} - //return result; } /** @@ -629,13 +606,11 @@ public: * Computations of \f$L^{\infty}\f$ distance between two landscapes. **/ friend double compute_max_norm_distance_of_landscapes( const Persistence_landscape_on_grid& first, const Persistence_landscape_on_grid& second ); - //friend double compute_max_norm_distance_of_landscapes( const Persistence_landscape_on_grid& first, const Persistence_landscape_on_grid& second , unsigned& nrOfLand , double&x , double& y1, double& y2 ); - /** - * Function to compute absolute value of a PL function. The representation of persistence landscapes allow to store general PL-function. When computing distance betwen two landscapes, we compute difference between + * Function to compute absolute value of a PL function. The representation of persistence landscapes allow to store general PL-function. When computing distance between two landscapes, we compute difference between * them. In this case, a general PL-function with negative value can appear as a result. Then in order to compute distance, we need to take its absolute value. This is the purpose of this procedure. **/ void abs() @@ -655,7 +630,7 @@ public: size_t size()const{return this->number_of_nonzero_levels(); } /** - * Computate maximal value of lambda-level landscape. + * Compute maximal value of lambda-level landscape. **/ double find_max( unsigned lambda )const { @@ -742,14 +717,14 @@ public: } //now, to compute the inner product in this interval we need to compute the integral of (ax+b)(cx+d) = acx^2 + (ad+bc)x + bd in the interval from previous_x to current_x: - //The integal is ac/3*x^3 + (ac+bd)/2*x^2 + bd*x + //The integral is ac/3*x^3 + (ac+bd)/2*x^2 + bd*x double added_value = (a*c/3*current_x*current_x*current_x + (a*d+b*c)/2*current_x*current_x + b*d*current_x)- (a*c/3*previous_x*previous_x*previous_x + (a*d+b*c)/2*previous_x*previous_x + b*d*previous_x); if ( dbg ) { - std::cerr << "Value of the integral on the left end ie : " << previous_x << " is : " << a*c/3*previous_x*previous_x*previous_x + (a*d+b*c)/2*previous_x*previous_x + b*d*previous_x << std::endl; + std::cerr << "Value of the integral on the left end i.e. : " << previous_x << " is : " << a*c/3*previous_x*previous_x*previous_x + (a*d+b*c)/2*previous_x*previous_x + b*d*previous_x << std::endl; std::cerr << "Value of the integral on the right end i.e. : " << current_x << " is " << a*c/3*current_x*current_x*current_x + (a*d+b*c)/2*current_x*current_x + b*d*current_x << std::endl; } @@ -775,7 +750,7 @@ public: /** * Computations of \f$L^{p}\f$ distance between two landscapes on a grid. p is the parameter of the procedure. * FIXME: Note that, due to the grid representation, the method below may give non--accurate results in case when the landscape P and Q the difference of which we want to compute - * are interxsecting. This is a consequence of a general way they are computed. In the future, an integral of absolute value of a difference of P and Q will be given as a separated + * are intersecting. This is a consequence of a general way they are computed. In the future, an integral of absolute value of a difference of P and Q will be given as a separated * function to fix that inaccuracy. **/ friend double compute_distance_of_landscapes_on_grid( const Persistence_landscape_on_grid& first, const Persistence_landscape_on_grid& second , double p ) @@ -819,7 +794,7 @@ public: else { result = lan.compute_integral_of_landscape(); - if (dbg){std::cerr << "integral, wihtout power : " << result << std::endl;getchar();} + if (dbg){std::cerr << "integral, without power : " << result << std::endl;getchar();} } //(\int_{- \infty}^{+\infty}| first-second |^p)^(1/p) return pow( result , 1/(double)p ); @@ -830,45 +805,14 @@ public: return lan.compute_maximum(); } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //Functions that are needed for that class to implement the concept. /** * The number of projections to R is defined to the number of nonzero landscape functions. I-th projection is an integral of i-th landscape function over whole R. * This function is required by the Real_valued_topological_data concept. - * At the moment this function is not tested, since it is quite likelly to be changed in the future. Given this, when using it, keep in mind that it - * will be most likelly changed in the next versions. + * At the moment this function is not tested, since it is quite likely to be changed in the future. Given this, when using it, keep in mind that it + * will be most likely changed in the next versions. **/ double project_to_R( int number_of_function )const { @@ -884,8 +828,6 @@ public: } - - /** * This function produce a vector of doubles based on a landscape. It is required in a concept Vectorized_topological_data */ @@ -909,16 +851,13 @@ public: } /** - * This function return the number of functions that allows vectorization of persistence laandscape. It is required in a concept Vectorized_topological_data. + * This function return the number of functions that allows vectorization of persistence landscape. It is required in a concept Vectorized_topological_data. **/ size_t number_of_vectorize_functions()const { return number_of_functions_for_vectorization; } - - - /** * A function to compute averaged persistence landscape on a grid, based on vector of persistence landscapes on grid. @@ -932,7 +871,7 @@ public: this->values_of_landscapes .clear(); this->grid_min = this->grid_max = 0; - //if there is nothing to averate, then the average is a zero landscape. + //if there is nothing to average, then the average is a zero landscape. if ( to_average.size() == 0 )return; //now we need to check if the grids in all objects of to_average are the same: @@ -968,7 +907,7 @@ public: std::cerr << "We are considering the point : " << grid_point << " of the grid. In this point, there are at most : " << maximal_size_of_vector << " nonzero landscape functions \n"; } - //and compute an arythmetic average: + //and compute an arithmetic average: for ( size_t land_no = 0 ; land_no != to_average.size() ; ++land_no ) { //summing: @@ -989,7 +928,7 @@ public: /** * A function to compute distance between persistence landscape on a grid. - * The parameter of this functionis a Persistence_landscape_on_grid. + * The parameter of this function is a Persistence_landscape_on_grid. * This function is required in Topological_data_with_distances concept. * For max norm distance, set power to std::numeric_limits::max() **/ @@ -1007,7 +946,7 @@ public: /** * A function to compute scalar product of persistence landscape on a grid. - * The parameter of this functionis a Persistence_landscape_on_grid. + * The parameter of this function is a Persistence_landscape_on_grid. * This function is required in Topological_data_with_scalar_product concept. **/ double compute_scalar_product( const Persistence_landscape_on_grid& second ) @@ -1016,28 +955,9 @@ public: } //end of implementation of functions needed for concepts. - - - - - - - - - - - - - - - - - - - /** - * A function that returns values of landsapes. It can be used for vizualization + * A function that returns values of landscapes. It can be used for visualization **/ std::vector< std::vector< double > > output_for_visualization()const { @@ -1046,7 +966,7 @@ public: /** * function used to create a gnuplot script for visualization of landscapes. Over here we need to specify which landscapes do we want to plot. - * In addition, the user may specify the range (min and max) where landscape is plot. The fefault values for min and max are std::numeric_limits::max(). If the procedure detect those + * In addition, the user may specify the range (min and max) where landscape is plot. The default values for min and max are std::numeric_limits::max(). If the procedure detect those * values, it will determine the range so that the whole landscape is supported there. If at least one min or max value is different from std::numeric_limits::max(), then the values * provided by the user will be used. **/ @@ -1123,7 +1043,7 @@ void Persistence_landscape_on_grid::set_up_values_of_landscapes( const std::vect if ( grid_max_ <= grid_min_ ) { - throw "Wrong parameters of grid_min and grid_max given to the procedure. THe grid have negative, or zero size. The program will now terminate.\n"; + throw "Wrong parameters of grid_min and grid_max given to the procedure. The grid have negative, or zero size. The program will now terminate.\n"; } double dx = ( grid_max_ - grid_min_ )/(double)(number_of_points_); @@ -1174,7 +1094,7 @@ void Persistence_landscape_on_grid::set_up_values_of_landscapes( const std::vect if ( this->values_of_landscapes[i].size() == number_of_levels-1 ) { //this->values_of_landscapes[i].size() == number_of_levels - //in this case we need to create the heep. + //in this case we need to create the heap. std::make_heap (this->values_of_landscapes[i].begin(),this->values_of_landscapes[i].end()); } } @@ -1212,7 +1132,7 @@ void Persistence_landscape_on_grid::set_up_values_of_landscapes( const std::vect if ( this->values_of_landscapes[i].size() == number_of_levels-1 ) { //this->values_of_landscapes[i].size() == number_of_levels - //in this case we need to create the heep. + //in this case we need to create the heap. std::make_heap (this->values_of_landscapes[i].begin(),this->values_of_landscapes[i].end()); } } @@ -1225,7 +1145,7 @@ void Persistence_landscape_on_grid::set_up_values_of_landscapes( const std::vect if ( dbg ) { - std::cerr << "AAdding landscape value (going down) for a point : " << i << " equal : " << landscape_value << std::endl; + std::cerr << "Adding landscape value (going down) for a point : " << i << " equal : " << landscape_value << std::endl; } } landscape_value -= dx; @@ -1235,11 +1155,10 @@ void Persistence_landscape_on_grid::set_up_values_of_landscapes( const std::vect if ( number_of_levels != std::numeric_limits< unsigned >::max() ) { //in this case, vectors are used as heaps. And, since we want to have the smallest element at the top of - //each heap, we store mminus distances. To get if right at the end, we need to multiply each value + //each heap, we store minus distances. To get if right at the end, we need to multiply each value //in the heap by -1 to get real vector of distances. for ( size_t pt = 0 ; pt != this->values_of_landscapes.size() ; ++pt ) { - //std::cerr << this->values_of_landscapes[pt].size() <values_of_landscapes[pt].size() ; ++j ) { this->values_of_landscapes[pt][j] *= -1; @@ -1362,7 +1281,6 @@ void Persistence_landscape_on_grid::load_landscape_from_file( const char* filena //read a line of a file and convert it to a vector. std::vector< double > vv; std::getline(in, line); - //std::cerr << "Reading line : " << line << std::endl;getchar(); std::istringstream stream(line); while (stream >> number) { @@ -1485,7 +1403,7 @@ Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid ( const Pe result.grid_min = land1.grid_min; result.grid_max = land1.grid_max; - //now we perorm the operations: + //now we perform the operations: for ( size_t grid_point = 0 ; grid_point != land1.values_of_landscapes.size() ; ++grid_point ) { result.values_of_landscapes[grid_point] = std::vector< double >( std::max( land1.values_of_landscapes[grid_point].size() , land2.values_of_landscapes[grid_point].size() ) ); @@ -1555,9 +1473,7 @@ double compute_max_norm_distance_of_landscapes( const Persistence_landscape_on_g return result; } - - -}//namespace Gudhi_stat +}//namespace Persistence_representations }//namespace Gudhi -#endif +#endif // PERSISTENCE_LANDSCAPE_ON_GRID_H_ diff --git a/src/Persistence_representations/include/gudhi/Persistence_vectors.h b/src/Persistence_representations/include/gudhi/Persistence_vectors.h index 7fde3413..616ec50f 100644 --- a/src/Persistence_representations/include/gudhi/Persistence_vectors.h +++ b/src/Persistence_representations/include/gudhi/Persistence_vectors.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -21,8 +21,8 @@ */ -#ifndef Vector_distances_in_diagram_H -#define Vector_distances_in_diagram_H +#ifndef PERSISTENCE_VECTORS_H_ +#define PERSISTENCE_VECTORS_H_ #include #include @@ -42,32 +42,6 @@ namespace Gudhi namespace Persistence_representations { -/* -template -struct Euclidean_distance -{ - double operator() ( const std::pair< T,T >& f , const std::pair& s ) - { - return sqrt( (f.first-s.first)*(f.first-s.first) + (f.second-s.second)*(f.second-s.second) ); - } - double operator() ( const std::vector< T >& f , const std::vector < T >& s ) - { - if ( f.size() != s.size() ) - { - std::cerr << "Not compatible points dimensions in the procedure to compute Euclidean distance. The program will now terminate. \n"; - std::cout << f.size() << " , " << s.size() << std::endl; - throw "Not compatible points dimensions in the procedure to compute Euclidean distance. The program will now terminate. \n"; - } - double result = 0; - for ( size_t i = 0 ; i != f.size() ; ++i ) - { - result += ( f[i]-s[i] )*( f[i]-s[i] ); - } - return sqrt( result ); - } -}; -* */ - template struct Maximum_distance { @@ -79,16 +53,21 @@ struct Maximum_distance - /** -* This is an implementation of idea presented in the paper 'Stable Topological Signatures for Points on 3D Shapes' by -* M. Carriere, S. Y. Oudot and M. Ovsjanikov published in Computer Graphics Forum (proc. SGP 2015). -* The parameter of the class is the class that computes distance used to construct the vectors. The typical function is -* either Eucludean of maximum (Manhattan) distance. -* This class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product -* -**/ - + * \class Vector_distances_in_diagram Vector_distances_in_diagram.h gudhi/Vector_distances_in_diagram.h + * \brief A class implementing persistence vectors. + * + * \ingroup Persistence_representations + * + * \details + * This is an implementation of idea presented in the paper Stable Topological Signatures for Points on 3D + * Shapes \cite Carriere_Oudot_Ovsjanikov_top_signatures_3d .
+ * The parameter of the class is the class that computes distance used to construct the vectors. The typical function + * is either Euclidean of maximum (Manhattan) distance. + * + * This class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances, + * Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product + **/ template class Vector_distances_in_diagram { @@ -99,12 +78,12 @@ public: Vector_distances_in_diagram(){}; /** - * The constructor that takes as an input a multiset of persistence intervals (given as vector of birth-death pairs). The second parameter is the desiered length of the output vectors. + * The constructor that takes as an input a multiset of persistence intervals (given as vector of birth-death pairs). The second parameter is the desired length of the output vectors. **/ Vector_distances_in_diagram( const std::vector< std::pair< double , double > >& intervals , size_t where_to_cut ); /** - * The constructor taking as an input a file with birth-death pairs. The second parameter is the desiered length of the output vectors. + * The constructor taking as an input a file with birth-death pairs. The second parameter is the desired length of the output vectors. **/ Vector_distances_in_diagram( const char* filename , size_t where_to_cut , unsigned dimension = std::numeric_limits::max() ); @@ -155,7 +134,7 @@ public: void load_from_file( const char* filename ); /** - * Comparision operators: + * Comparison operators: **/ bool operator == ( const Vector_distances_in_diagram& second )const { @@ -172,14 +151,11 @@ public: return !( *this == second ); } - - - - //Implementations of functions for various concepts. + //Implementations of functions for various concepts. /** * Compute projection to real numbers of persistence vector. This function is required by the Real_valued_topological_data concept - * At the moment this function is not tested, since it is quite likelly to be changed in the future. Given this, when using it, keep in mind that it - * will be most likelly changed in the next versions. + * At the moment this function is not tested, since it is quite likely to be changed in the future. Given this, when using it, keep in mind that it + * will be most likely changed in the next versions. **/ double project_to_R( int number_of_function )const; /** @@ -195,7 +171,7 @@ public: **/ std::vector vectorize( int number_of_function )const; /** - * This function return the number of functions that allows vectorization of a persisence vector. It is required in a concept Vectorized_topological_data. + * This function return the number of functions that allows vectorization of a persistence vector. It is required in a concept Vectorized_topological_data. **/ size_t number_of_vectorize_functions()const { @@ -220,22 +196,6 @@ public: //end of implementation of functions needed for concepts. - - - - - - - - - - - - - - - - /** * For visualization use output from vectorize and build histograms. **/ @@ -246,7 +206,7 @@ public: /** - * Create a gnuplot script to vizualize the data structure. + * Create a gnuplot script to visualize the data structure. **/ void plot( const char* filename )const { @@ -264,7 +224,7 @@ public: } out <sorted_vector_of_distances[0] , 0); } - //arythmetic operations: + //arithmetic operations: template < typename Operation_type > friend Vector_distances_in_diagram operation_on_pair_of_vectors( const Vector_distances_in_diagram& first , const Vector_distances_in_diagram& second , Operation_type opertion ) { @@ -511,7 +471,6 @@ void Vector_distances_in_diagram::compute_sorted_vector_of_distances_via_heap double value = f( this->intervals[i] , std::make_pair( 0.5*(this->intervals[i].first+this->intervals[i].second) , 0.5*(this->intervals[i].first+this->intervals[i].second) ) ); if ( -value < heap.front() ) { - //std::cerr << "Replacing : " << heap.front() << " with : " << -value <::distance( const Vector_distances_in_diagr } else { - //nax morm + // max norm if ( result < fabs( this->sorted_vector_of_distances[i] - second_.sorted_vector_of_distances[i] ) )result = fabs( this->sorted_vector_of_distances[i] - second_.sorted_vector_of_distances[i] ); } if ( dbg ) @@ -767,12 +726,8 @@ double Vector_distances_in_diagram::compute_scalar_product( const Vector_dist return result; } - - - - -}//namespace Gudhi_stat +}//namespace Persistence_representations }//namespace Gudhi -#endif // Vector_distances_in_diagram_H +#endif // PERSISTENCE_VECTORS_H_ diff --git a/src/Persistence_representations/include/gudhi/common_persistence_representations.h b/src/Persistence_representations/include/gudhi/common_persistence_representations.h index f223079a..f571ca4f 100644 --- a/src/Persistence_representations/include/gudhi/common_persistence_representations.h +++ b/src/Persistence_representations/include/gudhi/common_persistence_representations.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -20,15 +20,15 @@ * along with this program. If not, see . */ -#ifndef common_gudhi_stat_H -#define common_gudhi_stat_H +#ifndef COMMON_PERSISTENCE_REPRESENTATIONS_H_ +#define COMMON_PERSISTENCE_REPRESENTATIONS_H_ namespace Gudhi { namespace Persistence_representations { - //this file contain an implementation of some common procedures used in Gudhi_stat. + //this file contain an implementation of some common procedures used in Persistence_representations. //double epsi = std::numeric_limits::epsilon(); double epsi = 0.000005; @@ -38,8 +38,8 @@ double epsi = 0.000005; /** - * A procedure used to compare doubles. Typically gien two doubles A and B, comparing A == B is not good idea. In this case, we use the procedure almostEqual with the epsi defined at - * the top of the file. Setting up the epsi give the user a tolerance on what should be consider equal. + * A procedure used to compare doubles. Typically given two doubles A and B, comparing A == B is not good idea. In this case, we use the procedure almostEqual with the epsi defined at + * the top of the file. Setting up the epsi gives the user a tolerance on what should be consider equal. **/ inline bool almost_equal( double a , double b ) { @@ -78,7 +78,7 @@ std::pair compute_parameters_of_a_line( std::pair //landscapes /** - * This procedure given two points which lies on the opposide sides of x axis, compute x for which the line connecting those two points crosses x axis. + * This procedure given two points which lies on the opposite sides of x axis, compute x for which the line connecting those two points crosses x axis. **/ double find_zero_of_a_line_segment_between_those_two_points ( std::pair p1, std::pair p2 ) { @@ -86,7 +86,7 @@ double find_zero_of_a_line_segment_between_those_two_points ( std::pair 0 ) { std::ostringstream errMessage; - errMessage <<"In function find_zero_of_a_line_segment_between_those_two_points the agguments are: (" << p1.first << "," << p1.second << ") and (" << p2.first << "," << p2.second << "). There is no zero in line between those two points. Program terminated."; + errMessage <<"In function find_zero_of_a_line_segment_between_those_two_points the arguments are: (" << p1.first << "," << p1.second << ") and (" << p2.first << "," << p2.second << "). There is no zero in line between those two points. Program terminated."; std::string errMessageStr = errMessage.str(); const char* err = errMessageStr.c_str(); throw(err); @@ -94,8 +94,6 @@ double find_zero_of_a_line_segment_between_those_two_points ( std::pair f, std::pair s ) @@ -135,7 +133,7 @@ bool compare_points_sorting( std::pair f, std::pair p1, std::pair p2 , double x ) { @@ -148,7 +146,7 @@ double function_value ( std::pair p1, std::pair p2 -}//namespace Gudhi_stat -}//namespace Gudhi +} // namespace Persistence_representations +} // namespace Gudhi -#endif +#endif // COMMON_PERSISTENCE_REPRESENTATIONS_H_ 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 058c77a4..a4884314 100644 --- a/src/Persistence_representations/include/gudhi/read_persistence_from_file.h +++ b/src/Persistence_representations/include/gudhi/read_persistence_from_file.h @@ -4,7 +4,7 @@ * * Author(s): Pawel Dlotko * - * Copyright (C) 2015 INRIA (France) + * Copyright (C) 2017 INRIA (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 @@ -21,8 +21,8 @@ */ -#ifndef Read_Persitence_From_File_H -#define Read_Persitence_From_File_H +#ifndef READ_PERSISTENCE_FROM_FILE_H_ +#define READ_PERSISTENCE_FROM_FILE_H_ #include #include @@ -36,86 +36,6 @@ namespace Gudhi { namespace Persistence_representations { - - - -/** - * This procedure reads names of files which are stored in a file. -**/ -std::vector< std::string > readFileNames( const char* filenameWithFilenames ) -{ - bool dbg = false; - - std::ifstream in(filenameWithFilenames); - if ( !in.good() ) - { - std::cerr << "The file : " << filenameWithFilenames << " do not exist. The program will now terminate \n"; - throw "The file from which you are trying to read do not exist. The program will now terminate \n"; - } - - std::vector< std::string > result; - std::string line; - while (!in.eof()) - { - getline(in,line); - line.erase( std::remove_if( line.begin(), line.end(), ::isspace) , line.end() ); - - if (dbg){std::cerr << "line : " << line << std::endl;} - - if ( (line.length() == 0) || (line[0] == '#') ) - { - //in this case we have a file name. First we should remove all the white spaces. - if ( dbg ){std::cerr << "This is a line with comment, it will be ignored n";} - } - else - { - result.push_back( line ); - if (dbg){std::cerr << "Line after removing white spaces : " << line << std::endl;} - } - } - in.close(); - - return result; -}//readFileNames - - - -std::vector< std::vector< double > > read_numbers_from_file_line_by_line( const char* filename ) -{ - bool dbg = false; - std::ifstream in(filename); - if ( !in.good() ) - { - std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n"; - throw "The file from which you are trying to read the persistence landscape do not exist. The program will now terminate \n"; - } - - std::vector< std::vector< double > > result; - double number; - - - std::string line; - while ( in.good() ) - { - std::getline(in,line); - std::stringstream ss(line); - - if ( dbg )std::cerr << "\n Reading line : " << line << std::endl; - - std::vector< double > this_line; - while ( ss.good() ) - { - ss >> number; - this_line.push_back( number ); - if ( dbg )std::cerr << number << " "; - } - if ( this_line.size() && in.good() ) result.push_back( this_line ); - } - in.close(); - - return result; -}//read_numbers_from_file_line_by_line - /** * Universal procedure to read files with persistence. It ignores the lines starting from # (treat them as comments). @@ -123,7 +43,7 @@ std::vector< std::vector< double > > read_numbers_from_file_line_by_line( const * that each other line in the file, which is not a comment, have the same number of numerical entries (2, 3 or 4). * If there are two numerical entries per line, then the function assume that they are birth/death coordinates. * If there are three numerical entries per line, then the function assume that they are: dimension and birth/death coordinates. - * If there are four numerical entries per line, then the function assume that they are: thc characteristic of a filed over which + * If there are four numerical entries per line, then the function assume that they are: the characteristic of a filed over which * persistence was computed, dimension and birth/death coordinates. * The 'inf' string can appear only as a last element of a line. * The procedure returns vector of persistence pairs. @@ -162,7 +82,7 @@ std::vector > read_persistence_intervals_in_one_dimensi if ( line_copy.find("inf") != std::string::npos ) { size_t np = line_copy.find("inf"); - //replace symbols 'inf' in line_copy with whilespaces: + //replace symbols 'inf' in line_copy with white spaces: line_copy[np] = ' '; line_copy[np+1] = ' '; line_copy[np+2] = ' '; @@ -194,7 +114,7 @@ std::vector > read_persistence_intervals_in_one_dimensi { std::cerr << "This line: " << line << " contains infinite interval. \n"; } - //first we substitute inf by whitespaces: + //first we substitute inf by white spaces: size_t np = line.find("inf"); line[np] = ' '; line[np+1] = ' '; @@ -288,13 +208,9 @@ std::vector > read_persistence_intervals_in_one_dimensi if ( dbg )std::cerr << "End of reading \n"; return barcode; -}//read_persistence_intervals_in_one_dimension_from_file +} // read_persistence_intervals_in_one_dimension_from_file -}//namespace Gudhi_stat -}//namespace Gudhi +} // namespace Persistence_representations +} // namespace Gudhi - - - -#endif - +#endif // READ_PERSISTENCE_FROM_FILE_H_ diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp index d3e6f322..27a7836f 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/compute_distance_of_persistence_heat_maps.cpp @@ -34,8 +34,8 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program compute dsitance of persistence heat maps stored in a file (the file needs to be created beforehand). \n"; - std::cout << "The first parameter of a program is an interger p. The program compute L^p distance of the two heat maps. For L^infty distance choose p = -1. \n"; + std::cout << "This program compute distance of persistence heat maps stored in a file (the file needs to be created beforehand). \n"; + std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the two heat maps. For L^infty distance choose p = -1. \n"; std::cout << "The remaining parameters of this programs are names of files with persistence heat maps.\n"; if ( argc < 3 ) @@ -76,7 +76,7 @@ int main( int argc , char** argv ) distance[i] = v; } - //and now we can compute the distnaces: + //and now we can compute the distances: for ( size_t i = 0 ; i != filenames.size() ; ++i ) { for ( size_t j = i ; j != filenames.size() ; ++j ) @@ -106,6 +106,3 @@ int main( int argc , char** argv ) - - - diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp index aa887c9c..f755e9a6 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_arctan_of_their_persistence.cpp @@ -36,10 +36,10 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are weighted by the arcus tangens of their persistence.\n"; + std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are weighted by the arc tangential of their persistence.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; - std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number of pixels \n"; std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp index aa13d786..732b3768 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_distance_from_diagonal.cpp @@ -38,7 +38,7 @@ int main( int argc , char** argv ) std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are weighted by the distance of a center from the diagonal.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; - std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number of pixels \n"; std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; @@ -62,8 +62,6 @@ int main( int argc , char** argv ) dimension = (unsigned)dim; } - //std::cout << "Parameters of the program : size_of_grid : " << size_of_grid << ", min_ : " << min_ << ", max_ : " << max_ << ", stdiv: " << stdiv << ", dim : " << dim << std::endl; - std::vector< const char* > filenames; for ( int i = 6 ; i != argc ; ++i ) { diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp index 46258329..58406d08 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_p_h_m_weighted_by_squared_diag_distance.cpp @@ -38,7 +38,7 @@ int main( int argc , char** argv ) std::cout << "This program creates persistence heat map of diagrams provided as an input. The Gaussian kernels are weighted by the square of distance of a center from the diagonal.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; - std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number of pixels \n"; std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp index cac81495..90b50b0b 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_persistence_heat_maps.cpp @@ -39,7 +39,7 @@ int main( int argc , char** argv ) std::cout << "This program creates persistence heat map of diagrams provided as an input.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; - std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number of pixels \n"; std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp index 6aab42f7..6a07bf19 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/create_pssk.cpp @@ -37,7 +37,7 @@ int main( int argc , char** argv ) std::cout << "This program creates PSSK of diagrams provided as an input.\n"; std::cout << "The first parameter of a program is an integer, a size of a grid.\n"; std::cout << "The second and third parameters are min and max of the grid. If you want those numbers to be computed based on the data, set them both to -1 \n"; - std::cerr << "The fourth parameter is an integer, the standard deviation of a gaussian kernel expressed in a number of pixels \n"; + std::cerr << "The fourth parameter is an integer, the standard deviation of a Gaussian kernel expressed in a number of pixels \n"; std::cout << "The fifth parameter of this program is a dimension of persistence that will be used in creation of the persistence heat maps."; std::cout << "If our input files contain persistence pairs of various dimension, as a fifth parameter of the procedure please provide the dimension of persistence you want to use."; std::cout << "If in your file there are only birth-death pairs of the same dimension, set the first parameter to -1." << std::endl; diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp b/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp index 5a4776ff..7aedfbb1 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp +++ b/src/Persistence_representations/utilities/persistence_heat_maps/plot_persistence_heat_map.cpp @@ -34,7 +34,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). Please call the code with the name of a landsape file \n"; + std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). Please call the code with the name of a landscape file \n"; Persistence_heat_maps l; l.load_from_file( argv[1] ); l.plot( argv[1] ); diff --git a/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp b/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp index 19e49bbb..fe4e709f 100644 --- a/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp +++ b/src/Persistence_representations/utilities/persistence_intervals/compute_bottleneck_distance.cpp @@ -34,7 +34,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program compute the bottleneck distance of persistence diarams stored in a files. \n"; + std::cout << "This program compute the bottleneck distance of persistence diagrams stored in a files. \n"; std::cout << "The first parameter of the program is the dimension of persistence to be used to construct persistence landscapes. If your file contains "; std::cout << "the information about dimension of persistence pairs, please provide here the dimension of persistence pairs you want to use. If your input files consist only "; std::cout << "of birth-death pairs, please set this first parameter to -1 \n"; diff --git a/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp b/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp index b2cbac70..6e2598fa 100644 --- a/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp +++ b/src/Persistence_representations/utilities/persistence_intervals/plot_histogram_of_intervals_lengths.cpp @@ -71,7 +71,7 @@ int main( int argc , char** argv ) out << histogram[i] << std::endl; } out << std::endl; - std::cout << "To vizualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; + std::cout << "To visualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; out.close(); return 0; } diff --git a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp index e20f85c0..5b36e0ce 100644 --- a/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp +++ b/src/Persistence_representations/utilities/persistence_intervals/plot_persistence_Betti_numbers.cpp @@ -89,12 +89,7 @@ int main( int argc , char** argv ) out << std::endl; out.close(); - //for ( size_t i = 0 ; i != pbns.size() ; ++i ) - //{ - // std::cout << pbns[i].first << " " << pbns[i].second << std::endl; - //} - - std::cout << "To vizualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; + std::cout << "To visualize, open gnuplot and type: load \'" << gnuplot_script.str().c_str() << "\'" << std::endl; return 0; } diff --git a/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp index 85954cb2..ef969ed0 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp +++ b/src/Persistence_representations/utilities/persistence_landscapes/compute_distance_of_landscapes.cpp @@ -34,7 +34,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { std::cout << "This program compute distance of persistence landscapes stored in a file (the file needs to be created beforehand). \n"; - std::cout << "The first parameter of a program is an interger p. The program compute L^p distance of the given landscapes. For L^infty distance choose p = -1. \n"; + std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the given landscapes. For L^infty distance choose p = -1. \n"; std::cout << "The remaining parameters of this programs are names of files with persistence landscapes."; if ( argc < 3 ) diff --git a/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp b/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp index b79a689d..670f0364 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp +++ b/src/Persistence_representations/utilities/persistence_landscapes/plot_landscapes.cpp @@ -33,7 +33,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). Please call the code with the name of a landsape file \n"; + std::cout << "This program plot persistence landscape stored in a file (the file needs to be created beforehand). Please call the code with the name of a landscape file \n"; Persistence_landscape l; l.load_landscape_from_file( argv[1] ); diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp index 4ecbd548..3065b52c 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp +++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/compute_distance_of_landscapes_on_grid.cpp @@ -33,8 +33,8 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program compute dsitance of persistence landscapes on grid stored in a file (the file needs to be created beforehand). \n"; - std::cout << "The first parameter of a program is an interger p. The program compute L^p distance of the the landscapes on grid. For L^infty distance choose p = -1. \n"; + std::cout << "This program compute distance of persistence landscapes on grid stored in a file (the file needs to be created beforehand). \n"; + std::cout << "The first parameter of a program is an integer p. The program compute L^p distance of the landscapes on grid. For L^infty distance choose p = -1. \n"; std::cout << "The remaining parameters of this programs are names of files with persistence landscapes on grid.\n"; if ( argc < 3 ) @@ -106,5 +106,3 @@ int main( int argc , char** argv ) - - diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp index 700b2f1f..b4fa3046 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp +++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/plot_landscapes_on_grid.cpp @@ -33,7 +33,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { - std::cout << "This program plot persistence landscape on grid stored in a file (the file needs to be created beforehand). Please call the code with the name of a landsape on grid file \n"; + std::cout << "This program plot persistence landscape on grid stored in a file (the file needs to be created beforehand). Please call the code with the name of a landscape on grid file \n"; if ( argc == 1 ) { std::cout << "Wrong parameters of a program call, the program will now terminate \n"; diff --git a/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp index 39e24cd7..5c0d3328 100644 --- a/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp +++ b/src/Persistence_representations/utilities/persistence_vectors/compute_distance_of_persistence_vectors.cpp @@ -34,7 +34,7 @@ using namespace Gudhi::Persistence_representations; int main( int argc , char** argv ) { std::cout << "This program compute distance of persistence vectors stored in a file (the file needs to be created beforehand). \n"; - std::cout << "The first parameter of a program is an interger p. The program compute l^p distance of the vectors. For l^infty distance choose p = -1. \n"; + std::cout << "The first parameter of a program is an integer p. The program compute l^p distance of the vectors. For l^infty distance choose p = -1. \n"; std::cout << "The remaining parameters of this programs are names of files with persistence vectors.\n"; if ( argc < 3 ) @@ -60,7 +60,6 @@ int main( int argc , char** argv ) vectors.reserve( filenames.size() ); for ( size_t file_no = 0 ; file_no != filenames.size() ; ++file_no ) { - //cerr << filenames[file_no] << endl; Vector_distances_in_diagram< Euclidean_distance > l; l.load_from_file( filenames[file_no] ); vectors.push_back( l ); diff --git a/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp b/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp index 634bcb13..d7a22e58 100644 --- a/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp +++ b/src/Persistence_representations/utilities/persistence_vectors/create_persistence_vectors.cpp @@ -52,8 +52,7 @@ int main( int argc , char** argv ) for ( size_t i = 0 ; i != filenames.size() ; ++i ) { - std::cerr << "Creatign persistence vectors based on a file : " << filenames[i] << std::endl; - //std::vector< std::pair< double , double > > persistence_pairs = read_gudhi_persistence_file_in_one_dimension( filenames[i] , size_t dimension = 0 ) + std::cerr << "Creating persistence vectors based on a file : " << filenames[i] << std::endl; Vector_distances_in_diagram< Euclidean_distance > l( filenames[i] , dimension ); std::stringstream ss; ss << filenames[i] << ".vect"; diff --git a/src/cmake/modules/GUDHI_user_version_target.txt b/src/cmake/modules/GUDHI_user_version_target.txt index 8b7cf0e2..3172f6b1 100644 --- a/src/cmake/modules/GUDHI_user_version_target.txt +++ b/src/cmake/modules/GUDHI_user_version_target.txt @@ -47,7 +47,7 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) add_custom_command(TARGET user_version PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/GudhUI ${GUDHI_USER_VERSION_DIR}/GudhUI) - set(GUDHI_MODULES "common;Alpha_complex;Bitmap_cubical_complex;Bottleneck_distance;Contraction;Gudhi_stat;Hasse_complex;Persistent_cohomology;Rips_complex;Simplex_tree;Skeleton_blocker;Spatial_searching;Subsampling;Tangential_complex;Witness_complex") + set(GUDHI_MODULES "common;Alpha_complex;Bitmap_cubical_complex;Bottleneck_distance;Contraction;Hasse_complex;Persistence_representations;Persistent_cohomology;Rips_complex;Simplex_tree;Skeleton_blocker;Spatial_searching;Subsampling;Tangential_complex;Witness_complex") set(GUDHI_DIRECTORIES "doc;example;concept;utilities") set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/gudhi_patches") diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index d1cb691c..6986a6b5 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -212,19 +212,20 @@ - \subsection Gudhi_stat_sublibrary Gudhi statistical sublibrary - \image html "average_landscape.png" "Gudhi statistical sublibrary" + \subsection PersistenceRepresentationsToolbox Persistence representations + \image html "average_landscape.png" "Persistence representations" diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index f6e2ab5a..f683136b 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -48,6 +48,11 @@ class Euclidean_distance { } return std::sqrt(dist); } + template< typename T > + T operator() ( const std::pair< T,T >& f , const std::pair< T,T >& s ) + { + return sqrt( (f.first-s.first)*(f.first-s.first) + (f.second-s.second)*(f.second-s.second) ); + } }; } // namespace Gudhi -- cgit v1.2.3 From 3d4c842d34f4d6c52ba6c39836f57d702d6a6ff3 Mon Sep 17 00:00:00 2001 From: mcarrier Date: Tue, 7 Nov 2017 10:30:08 +0000 Subject: git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2840 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9037e52ab98b2b9c699c104aa4da45bf6d74cfc7 --- CMakeLists.txt | 3 +-- src/CMakeLists.txt | 1 + src/Nerve_GIC/doc/Intro_graph_induced_complex.h | 4 ++-- src/Nerve_GIC/include/gudhi/GIC.h | 2 +- src/common/doc/main_page.h | 10 +++++----- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index da6f5709..ef129cd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ endif() # Add your new module in the list, order is not important include(GUDHI_modules) -include_directories(src/Nerve_GIC/include/) add_gudhi_module(common) add_gudhi_module(Alpha_complex) @@ -49,8 +48,8 @@ add_gudhi_module(Spatial_searching) add_gudhi_module(Subsampling) add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) +add_gudhi_module(Nerve_GIC) add_subdirectory(src/Nerve_GIC/example) -add_subdirectory(src/Nerve_GIC/test) message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9961fcf9..a2617020 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,6 +24,7 @@ add_gudhi_module(Spatial_searching) add_gudhi_module(Subsampling) add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) +add_gudhi_module(Nerve_GIC) message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") diff --git a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h index 2a869009..cb9ba554 100644 --- a/src/Nerve_GIC/doc/Intro_graph_induced_complex.h +++ b/src/Nerve_GIC/doc/Intro_graph_induced_complex.h @@ -2,9 +2,9 @@ * (Geometric Understanding in Higher Dimensions) is a generic C++ * library for computational topology. * - * Author(s): Clément Maria, Pawel Dlotko, Vincent Rouvreau + * Author(s): Mathieu Carriere * - * Copyright (C) 2016 INRIA + * Copyright (C) 2017 INRIA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/Nerve_GIC/include/gudhi/GIC.h b/src/Nerve_GIC/include/gudhi/GIC.h index fc615828..2520042d 100644 --- a/src/Nerve_GIC/include/gudhi/GIC.h +++ b/src/Nerve_GIC/include/gudhi/GIC.h @@ -700,7 +700,7 @@ class Cover_complex { * @result cover_back(c) vector of IDs of data points. * */ - std::vector subpopulation(Cover_t c){ + const std::vector & subpopulation(Cover_t c){ return cover_back[c]; } diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index d48294a5..34bf6c22 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -93,8 +93,8 @@
Author: Pawel Dlotko
- Introduced in: GUDHI 2.0.0
+ Introduced in: GUDHI 2.1.0
Copyright: GPL v3
- This is a statistical library for gudhi. It contain implementation of various representations of persistence diagrams; diagrams themselves, persistence landscapes (rigorous and grid version), - persistence heath maps, vectors and others. It implements basic functionalities which are neccessary to use persistence in statistics and machine learning. - User manual: \ref Gudhi_stat + It contain implementation of various representations of persistence diagrams; diagrams themselves, persistence + landscapes (rigorous and grid version), persistence heath maps, vectors and others. It implements basic + functionalities which are neccessary to use persistence in statistics and machine learning.
+ User manual: \ref Persistence_representations
- \subsection GICDataStructure Nerves and Graph Induced Complexes - \image html "gic_complex.png" "Graph Induced Complex of a point cloud." + \subsection CoverComplexDataStructure Cover Complexes: Nerves and Graph Induced Complexes + \image html "gicvisu.jpg" "Graph Induced Complex of a point cloud."
@@ -103,11 +103,11 @@ Copyright: GPL v3
- Nerves and Graph Induced Complexes are simplicial complexes that provably contain + Nerves and Graph Induced Complexes are cover complexes, i.e. simplicial complexes that provably contain topological information about the input data. They can be computed with a cover of the - data, that often comes from the preimage of a family of intervals covering the image + data, that comes i.e. from the preimage of a family of intervals covering the image of a scalar-valued function defined on the data.
- User manual: \ref graph_induced_complex - Reference manual: Gudhi::graph_induced_complex::Graph_induced_complex + User manual: \ref cover_complex - Reference manual: Gudhi::cover_complex::Cover_complex
-- cgit v1.2.3 From a81f82e1751846495c5f02fb1486ae5b574d8232 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 16 Nov 2017 16:03:27 +0000 Subject: Fix compilation git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/Nerve_GIC@2896 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 338feabf060d18464fce006487c190e7dc36fef9 --- CMakeLists.txt | 1 - src/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index ef129cd1..c2aa93c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,6 @@ add_gudhi_module(Subsampling) add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) -add_subdirectory(src/Nerve_GIC/example) message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a2617020..5c25eab5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -69,7 +69,6 @@ foreach(GUDHI_MODULE ${GUDHI_MODULES}) endif() endforeach() endforeach() -add_subdirectory(example/Nerve_GIC) add_subdirectory(GudhUI) -- cgit v1.2.3 From 56618be4e28a6a149aaa0fef944d8fde719f7844 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 16 Feb 2018 08:04:07 +0000 Subject: Add Cech complex. Do not compile yet. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cechcomplex_vincent@3250 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: bef87ed8038444685b964175ea65860300917380 --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/Cech_complex/doc/Intro_cech_complex.h | 0 src/Cech_complex/example/CMakeLists.txt | 14 + .../example/cech_complex_step_by_step.cpp | 179 +++++++ .../example_one_skeleton_cech_from_points.cpp | 74 +++ .../include/Miniball/Miniball.COPYRIGHT | 4 + src/Cech_complex/include/Miniball/Miniball.README | 23 + src/Cech_complex/include/Miniball/Miniball.hpp | 515 +++++++++++++++++++++ src/Cech_complex/include/gudhi/Cech_complex.h | 126 +++++ .../include/gudhi/Cech_complex_blocker.h | 85 ++++ src/cmake/modules/GUDHI_user_version_target.cmake | 4 +- 12 files changed, 1024 insertions(+), 2 deletions(-) create mode 100644 src/Cech_complex/doc/Intro_cech_complex.h create mode 100644 src/Cech_complex/example/CMakeLists.txt create mode 100644 src/Cech_complex/example/cech_complex_step_by_step.cpp create mode 100644 src/Cech_complex/example/example_one_skeleton_cech_from_points.cpp create mode 100644 src/Cech_complex/include/Miniball/Miniball.COPYRIGHT create mode 100644 src/Cech_complex/include/Miniball/Miniball.README create mode 100644 src/Cech_complex/include/Miniball/Miniball.hpp create mode 100644 src/Cech_complex/include/gudhi/Cech_complex.h create mode 100644 src/Cech_complex/include/gudhi/Cech_complex_blocker.h (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index 10373f75..3d8ff6c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ add_gudhi_module(Alpha_complex) add_gudhi_module(Bitmap_cubical_complex) add_gudhi_module(Bottleneck_distance) add_gudhi_module(Contraction) +add_gudhi_module(Cech_complex) add_gudhi_module(Hasse_complex) add_gudhi_module(Persistence_representations) add_gudhi_module(Persistent_cohomology) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94587044..7cccb19f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ add_gudhi_module(common) add_gudhi_module(Alpha_complex) add_gudhi_module(Bitmap_cubical_complex) add_gudhi_module(Bottleneck_distance) +add_gudhi_module(Cech_complex) add_gudhi_module(Contraction) add_gudhi_module(Hasse_complex) add_gudhi_module(Persistence_representations) diff --git a/src/Cech_complex/doc/Intro_cech_complex.h b/src/Cech_complex/doc/Intro_cech_complex.h new file mode 100644 index 00000000..e69de29b diff --git a/src/Cech_complex/example/CMakeLists.txt b/src/Cech_complex/example/CMakeLists.txt new file mode 100644 index 00000000..8097871f --- /dev/null +++ b/src/Cech_complex/example/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.6) +project(Cech_complex_examples) + +add_executable ( Cech_complex_example_step_by_step cech_complex_step_by_step.cpp ) +target_link_libraries(Cech_complex_example_step_by_step ${Boost_PROGRAM_OPTIONS_LIBRARY}) +if (TBB_FOUND) + target_link_libraries(Cech_complex_example_step_by_step ${TBB_LIBRARIES}) +endif() + +add_executable ( Cech_complex_example_one_skeleton_from_points example_one_skeleton_cech_from_points.cpp) +if (TBB_FOUND) + target_link_libraries(Cech_complex_example_one_skeleton_from_points ${TBB_LIBRARIES}) +endif() +add_test(NAME Cech_complex_example_one_skeleton_from_points COMMAND $) diff --git a/src/Cech_complex/example/cech_complex_step_by_step.cpp b/src/Cech_complex/example/cech_complex_step_by_step.cpp new file mode 100644 index 00000000..e71086b6 --- /dev/null +++ b/src/Cech_complex/example/cech_complex_step_by_step.cpp @@ -0,0 +1,179 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2018 Inria + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include // infinity +#include // for pair +#include + +// ---------------------------------------------------------------------------- +// rips_persistence_step_by_step is an example of each step that is required to +// build a Rips over a Simplex_tree. Please refer to rips_persistence to see +// how to do the same thing with the Rips_complex wrapper for less detailed +// steps. +// ---------------------------------------------------------------------------- + +// Types definition +using Simplex_tree = Gudhi::Simplex_tree<>; +using Simplex_handle = Simplex_tree::Simplex_handle; +using Filtration_value = Simplex_tree::Filtration_value; +using Point = std::vector; +using Points_off_reader = Gudhi::Points_off_reader; +using Proximity_graph = Gudhi::Proximity_graph; + +class Cech_blocker { + private: + using Point_cloud = std::vector; + using Point_iterator = Point_cloud::const_iterator; + using Coordinate_iterator = Point::const_iterator; + using Min_sphere = Miniball::Miniball >; + public: + bool operator()(Simplex_handle sh) { + std::vector points; + for (auto vertex : simplex_tree_.simplex_vertex_range(sh)) { + points.push_back(point_cloud_[vertex]); +#ifdef DEBUG_TRACES + std::cout << "#(" << vertex << ")#"; +#endif // DEBUG_TRACES + } + Min_sphere ms(dimension_, points.begin(),points.end()); + Filtration_value radius = std::sqrt(ms.squared_radius()); +#ifdef DEBUG_TRACES + std::cout << "radius = " << radius << " - " << (radius > threshold_) << std::endl; +#endif // DEBUG_TRACES + simplex_tree_.assign_filtration(sh, radius); + return (radius > threshold_); + } + Cech_blocker(Simplex_tree& simplex_tree, Filtration_value threshold, const std::vector& point_cloud) + : simplex_tree_(simplex_tree), + threshold_(threshold), + point_cloud_(point_cloud) { + dimension_ = point_cloud_[0].size(); + } + private: + Simplex_tree simplex_tree_; + Filtration_value threshold_; + std::vector point_cloud_; + int dimension_; +}; + + +void program_options(int argc, char * argv[] + , std::string & off_file_points + , Filtration_value & threshold + , int & dim_max); + + +int main(int argc, char * argv[]) { + std::string off_file_points; + Filtration_value threshold; + int dim_max; + + program_options(argc, argv, off_file_points, threshold, dim_max); + + // Extract the points from the file filepoints + Points_off_reader off_reader(off_file_points); + + // Compute the proximity graph of the points + Proximity_graph prox_graph = Gudhi::compute_proximity_graph(off_reader.get_point_cloud(), + threshold, + Gudhi::Euclidean_distance()); + + // Construct the Rips complex in a Simplex Tree + Simplex_tree st; + // insert the proximity graph in the simplex tree + st.insert_graph(prox_graph); + // expand the graph until dimension dim_max + st.expansion_with_blockers(dim_max, Cech_blocker(st, threshold, off_reader.get_point_cloud())); + + std::cout << "The complex contains " << st.num_simplices() << " simplices \n"; + std::cout << " and has dimension " << st.dimension() << " \n"; + + // Sort the simplices in the order of the filtration + st.initialize_filtration(); + +#if DEBUG_TRACES + std::cout << "********************************************************************\n"; + // Display the Simplex_tree - Can not be done in the middle of 2 inserts + std::cout << "* The complex contains " << st.num_simplices() << " simplices - dimension=" << st.dimension() << "\n"; + std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n"; + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << " " << "[" << st.filtration(f_simplex) << "] "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << static_cast(vertex) << " "; + } + std::cout << std::endl; + } +#endif // DEBUG_TRACES + + return 0; +} + +void program_options(int argc, char * argv[] + , std::string & off_file_points + , Filtration_value & threshold + , int & dim_max) { + namespace po = boost::program_options; + po::options_description hidden("Hidden options"); + hidden.add_options() + ("input-file", po::value(&off_file_points), + "Name of an OFF file containing a point set.\n"); + + po::options_description visible("Allowed options", 100); + visible.add_options() + ("help,h", "produce help message") + ("max-edge-length,r", + po::value(&threshold)->default_value(std::numeric_limits::infinity()), + "Maximal length 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."); + + po::positional_options_description pos; + pos.add("input-file", 1); + + po::options_description all; + all.add(visible).add(hidden); + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv). + options(all).positional(pos).run(), vm); + po::notify(vm); + + if (vm.count("help") || !vm.count("input-file")) { + std::cout << std::endl; + std::cout << "Construct a Cech complex defined on a set of input points.\n \n"; + + std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl << std::endl; + std::cout << visible << std::endl; + std::abort(); + } +} diff --git a/src/Cech_complex/example/example_one_skeleton_cech_from_points.cpp b/src/Cech_complex/example/example_one_skeleton_cech_from_points.cpp new file mode 100644 index 00000000..9b03616c --- /dev/null +++ b/src/Cech_complex/example/example_one_skeleton_cech_from_points.cpp @@ -0,0 +1,74 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2018 Inria + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include // for std::numeric_limits + +int main() { + // Type definitions + using Point_cloud = std::vector>; + using Simplex_tree = Gudhi::Simplex_tree; + using Filtration_value = Simplex_tree::Filtration_value; + using Cech_complex = Gudhi::cech_complex::Cech_complex; + + Point_cloud points; + points.push_back({1.0, 1.0}); + points.push_back({7.0, 0.0}); + points.push_back({4.0, 6.0}); + points.push_back({9.0, 6.0}); + points.push_back({0.0, 14.0}); + points.push_back({2.0, 19.0}); + points.push_back({9.0, 17.0}); + + // ---------------------------------------------------------------------------- + // Init of a Rips complex from points + // ---------------------------------------------------------------------------- + Filtration_value threshold = 12.0; + Cech_complex cech_complex_from_points(points, threshold, Gudhi::Euclidean_distance()); + + Simplex_tree stree; + cech_complex_from_points.create_complex(stree, 2); + // ---------------------------------------------------------------------------- + // Display information about the one skeleton Rips complex + // ---------------------------------------------------------------------------- + std::cout << "Cech complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; + + std::cout << "Iterator on Cech complex simplices in the filtration order, with [filtration value]:" << + std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + std::cout << " ( "; + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; + } + std::cout << ") -> " << "[" << stree.filtration(f_simplex) << "] "; + std::cout << std::endl; + } + return 0; +} diff --git a/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT b/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT new file mode 100644 index 00000000..dbe4c553 --- /dev/null +++ b/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT @@ -0,0 +1,4 @@ +The miniball software is available under the GNU General Public License (GPLv3 - https://www.gnu.org/copyleft/gpl.html). +If your intended use is not compliant with this license, please buy a commercial license (EUR 500 - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/license.html). +You need a license if the software that you develop using Miniball V3.0 is not open source. + diff --git a/src/Cech_complex/include/Miniball/Miniball.README b/src/Cech_complex/include/Miniball/Miniball.README new file mode 100644 index 00000000..86a96f08 --- /dev/null +++ b/src/Cech_complex/include/Miniball/Miniball.README @@ -0,0 +1,23 @@ +https://people.inf.ethz.ch/gaertner/subdir/software/miniball.html + +Smallest Enclosing Balls of Points - Fast and Robust in C++. +(high-quality software for smallest enclosing balls of balls is available in the computational geometry algorithms library CGAL) + + +This is the miniball software (V3.0) for computing smallest enclosing balls of points in arbitrary dimensions. It consists of a C++ header file Miniball.hpp (around 500 lines of code) and two example programs miniball_example.cpp and miniball_example_containers.cpp that demonstrate the usage. The first example stores the coordinates of the input points in a two-dimensional array, the second example uses a list of vectors to show how generic containers can be used. + +Credits: Aditya Gupta and Alexandros Konstantinakis-Karmis have significantly contributed to this version of the software. + +Changes - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/changes.txt - from previous versions. + +The theory - https://people.inf.ethz.ch/gaertner/subdir/texts/own_work/esa99_final.pdf - behind the miniball software (Proc. 7th Annual European Symposium on Algorithms (ESA), Lecture Notes in Computer Science 1643, Springer-Verlag, pp.325-338, 1999). + +Main Features: + + Very fast in low dimensions. 1 million points in 5-space are processed within 0.05 seconds on any recent machine. + + High numerical stability. Almost all input degeneracies (cospherical points, multiple points, points very close together) are routinely handled. + + Easily integrates into your code. You can freely choose the coordinate type of your points and the container to store the points. If you still need to adapt the code, the header is small and readable and contains documentation for all major methods. + + diff --git a/src/Cech_complex/include/Miniball/Miniball.hpp b/src/Cech_complex/include/Miniball/Miniball.hpp new file mode 100644 index 00000000..cb76c534 --- /dev/null +++ b/src/Cech_complex/include/Miniball/Miniball.hpp @@ -0,0 +1,515 @@ +// Copright (C) 1999-2013, Bernd Gaertner +// $Rev: 3581 $ +// +// 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 . +// +// Contact: +// -------- +// Bernd Gaertner +// Institute of Theoretical Computer Science +// ETH Zuerich +// CAB G31.1 +// CH-8092 Zuerich, Switzerland +// http://www.inf.ethz.ch/personal/gaertner + +#include +#include +#include +#include +#include + +namespace Miniball { + + // Global Functions + // ================ + template + inline NT mb_sqr (NT r) {return r*r;} + + // Functors + // ======== + + // functor to map a point iterator to the corresponding coordinate iterator; + // generic version for points whose coordinate containers have begin() + template < typename Pit_, typename Cit_ > + struct CoordAccessor { + typedef Pit_ Pit; + typedef Cit_ Cit; + inline Cit operator() (Pit it) const { return (*it).begin(); } + }; + + // partial specialization for points whose coordinate containers are arrays + template < typename Pit_, typename Cit_ > + struct CoordAccessor { + typedef Pit_ Pit; + typedef Cit_* Cit; + inline Cit operator() (Pit it) const { return *it; } + }; + + // Class Declaration + // ================= + + template + class Miniball { + private: + // types + // The iterator type to go through the input points + typedef typename CoordAccessor::Pit Pit; + // The iterator type to go through the coordinates of a single point. + typedef typename CoordAccessor::Cit Cit; + // The coordinate type + typedef typename std::iterator_traits::value_type NT; + // The iterator to go through the support points + typedef typename std::list::iterator Sit; + + // data members... + const int d; // dimension + Pit points_begin; + Pit points_end; + CoordAccessor coord_accessor; + double time; + const NT nt0; // NT(0) + + //...for the algorithms + std::list L; + Sit support_end; + int fsize; // number of forced points + int ssize; // number of support points + + // ...for the ball updates + NT* current_c; + NT current_sqr_r; + NT** c; + NT* sqr_r; + + // helper arrays + NT* q0; + NT* z; + NT* f; + NT** v; + NT** a; + + public: + // The iterator type to go through the support points + typedef typename std::list::const_iterator SupportPointIterator; + + // PRE: [begin, end) is a nonempty range + // POST: computes the smallest enclosing ball of the points in the range + // [begin, end); the functor a maps a point iterator to an iterator + // through the d coordinates of the point + Miniball (int d_, Pit begin, Pit end, CoordAccessor ca = CoordAccessor()); + + // POST: returns a pointer to the first element of an array that holds + // the d coordinates of the center of the computed ball + const NT* center () const; + + // POST: returns the squared radius of the computed ball + NT squared_radius () const; + + // POST: returns the number of support points of the computed ball; + // the support points form a minimal set with the same smallest + // enclosing ball as the input set; in particular, the support + // points are on the boundary of the computed ball, and their + // number is at most d+1 + int nr_support_points () const; + + // POST: returns an iterator to the first support point + SupportPointIterator support_points_begin () const; + + // POST: returns a past-the-end iterator for the range of support points + SupportPointIterator support_points_end () const; + + // POST: returns the maximum excess of any input point w.r.t. the computed + // ball, divided by the squared radius of the computed ball. The + // excess of a point is the difference between its squared distance + // from the center and the squared radius; Ideally, the return value + // is 0. subopt is set to the absolute value of the most negative + // coefficient in the affine combination of the support points that + // yields the center. Ideally, this is a convex combination, and there + // is no negative coefficient in which case subopt is set to 0. + NT relative_error (NT& subopt) const; + + // POST: return true if the relative error is at most tol, and the + // suboptimality is 0; the default tolerance is 10 times the + // coordinate type's machine epsilon + bool is_valid (NT tol = NT(10) * std::numeric_limits::epsilon()) const; + + // POST: returns the time in seconds taken by the constructor call for + // computing the smallest enclosing ball + double get_time() const; + + // POST: deletes dynamically allocated arrays + ~Miniball(); + + private: + void mtf_mb (Sit n); + void mtf_move_to_front (Sit j); + void pivot_mb (Pit n); + void pivot_move_to_front (Pit j); + NT excess (Pit pit) const; + void pop (); + bool push (Pit pit); + NT suboptimality () const; + void create_arrays(); + void delete_arrays(); + }; + + // Class Definition + // ================ + template + Miniball::Miniball (int d_, Pit begin, Pit end, + CoordAccessor ca) + : d (d_), + points_begin (begin), + points_end (end), + coord_accessor (ca), + time (clock()), + nt0 (NT(0)), + L(), + support_end (L.begin()), + fsize(0), + ssize(0), + current_c (NULL), + current_sqr_r (NT(-1)), + c (NULL), + sqr_r (NULL), + q0 (NULL), + z (NULL), + f (NULL), + v (NULL), + a (NULL) + { + assert (points_begin != points_end); + create_arrays(); + + // set initial center + for (int j=0; j + Miniball::~Miniball() + { + delete_arrays(); + } + + template + void Miniball::create_arrays() + { + c = new NT*[d+1]; + v = new NT*[d+1]; + a = new NT*[d+1]; + for (int i=0; i + void Miniball::delete_arrays() + { + delete[] f; + delete[] z; + delete[] q0; + delete[] sqr_r; + for (int i=0; i + const typename Miniball::NT* + Miniball::center () const + { + return current_c; + } + + template + typename Miniball::NT + Miniball::squared_radius () const + { + return current_sqr_r; + } + + template + int Miniball::nr_support_points () const + { + assert (ssize < d+2); + return ssize; + } + + template + typename Miniball::SupportPointIterator + Miniball::support_points_begin () const + { + return L.begin(); + } + + template + typename Miniball::SupportPointIterator + Miniball::support_points_end () const + { + return support_end; + } + + template + typename Miniball::NT + Miniball::relative_error (NT& subopt) const + { + NT e, max_e = nt0; + // compute maximum absolute excess of support points + for (SupportPointIterator it = support_points_begin(); + it != support_points_end(); ++it) { + e = excess (*it); + if (e < nt0) e = -e; + if (e > max_e) { + max_e = e; + } + } + // compute maximum excess of any point + for (Pit i = points_begin; i != points_end; ++i) + if ((e = excess (i)) > max_e) + max_e = e; + + subopt = suboptimality(); + assert (current_sqr_r > nt0 || max_e == nt0); + return (current_sqr_r == nt0 ? nt0 : max_e / current_sqr_r); + } + + template + bool Miniball::is_valid (NT tol) const + { + NT suboptimality; + return ( (relative_error (suboptimality) <= tol) && (suboptimality == 0) ); + } + + template + double Miniball::get_time() const + { + return time; + } + + template + void Miniball::mtf_mb (Sit n) + { + // Algorithm 1: mtf_mb (L_{n-1}, B), where L_{n-1} = [L.begin, n) + // B: the set of forced points, defining the current ball + // S: the superset of support points computed by the algorithm + // -------------------------------------------------------------- + // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, + // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf + + // PRE: B = S + assert (fsize == ssize); + + support_end = L.begin(); + if ((fsize) == d+1) return; + + // incremental construction + for (Sit i = L.begin(); i != n;) + { + // INV: (support_end - L.begin() == |S|-|B|) + assert (std::distance (L.begin(), support_end) == ssize - fsize); + + Sit j = i++; + if (excess(*j) > nt0) + if (push(*j)) { // B := B + p_i + mtf_mb (j); // mtf_mb (L_{i-1}, B + p_i) + pop(); // B := B - p_i + mtf_move_to_front(j); + } + } + // POST: the range [L.begin(), support_end) stores the set S\B + } + + template + void Miniball::mtf_move_to_front (Sit j) + { + if (support_end == j) + support_end++; + L.splice (L.begin(), L, j); + } + + template + void Miniball::pivot_mb (Pit n) + { + // Algorithm 2: pivot_mb (L_{n-1}), where L_{n-1} = [L.begin, n) + // -------------------------------------------------------------- + // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, + // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf + NT old_sqr_r; + const NT* c; + Pit pivot, k; + NT e, max_e, sqr_r; + Cit p; + do { + old_sqr_r = current_sqr_r; + sqr_r = current_sqr_r; + + pivot = points_begin; + max_e = nt0; + for (k = points_begin; k != n; ++k) { + p = coord_accessor(k); + e = -sqr_r; + c = current_c; + for (int j=0; j(*p++-*c++); + if (e > max_e) { + max_e = e; + pivot = k; + } + } + + if (max_e > nt0) { + // check if the pivot is already contained in the support set + if (std::find(L.begin(), support_end, pivot) == support_end) { + assert (fsize == 0); + if (push (pivot)) { + mtf_mb(support_end); + pop(); + pivot_move_to_front(pivot); + } + } + } + } while (old_sqr_r < current_sqr_r); + } + + template + void Miniball::pivot_move_to_front (Pit j) + { + L.push_front(j); + if (std::distance(L.begin(), support_end) == d+2) + support_end--; + } + + template + inline typename Miniball::NT + Miniball::excess (Pit pit) const + { + Cit p = coord_accessor(pit); + NT e = -current_sqr_r; + NT* c = current_c; + for (int k=0; k(*p++-*c++); + } + return e; + } + + template + void Miniball::pop () + { + --fsize; + } + + template + bool Miniball::push (Pit pit) + { + int i, j; + NT eps = mb_sqr(std::numeric_limits::epsilon()); + + Cit cit = coord_accessor(pit); + Cit p = cit; + + if (fsize==0) { + for (i=0; i(v[fsize][j]); + z[fsize]*=2; + + // reject push if z_fsize too small + if (z[fsize](*p++-c[fsize-1][i]); + f[fsize]=e/z[fsize]; + + for (i=0; i + typename Miniball::NT + Miniball::suboptimality () const + { + NT* l = new NT[d+1]; + NT min_l = nt0; + l[0] = NT(1); + for (int i=ssize-1; i>0; --i) { + l[i] = f[i]; + for (int k=ssize-1; k>i; --k) + l[i]-=a[k][i]*l[k]; + if (l[i] < min_l) min_l = l[i]; + l[0] -= l[i]; + } + if (l[0] < min_l) min_l = l[0]; + delete[] l; + if (min_l < nt0) + return -min_l; + return nt0; + } + +} // end Namespace Miniball diff --git a/src/Cech_complex/include/gudhi/Cech_complex.h b/src/Cech_complex/include/gudhi/Cech_complex.h new file mode 100644 index 00000000..3a0d828a --- /dev/null +++ b/src/Cech_complex/include/gudhi/Cech_complex.h @@ -0,0 +1,126 @@ +/* This file is part of the Gudhi Library. The Gudhi library + * (Geometric Understanding in Higher Dimensions) is a generic C++ + * library for computational topology. + * + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2018 Inria + * + * 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 CECH_COMPLEX_H_ +#define CECH_COMPLEX_H_ + +#include // for Gudhi::Proximity_graph +#include // for GUDHI_CHECK +#include // for Gudhi::cech_complex::Cech_blocker + +#include +#include +#include +#include // for std::size + +namespace Gudhi { + +namespace cech_complex { + +/** + * \class Cech_complex + * \brief Cech complex data structure. + * + * \ingroup Cech_complex + * + * \details + * The data structure is a one skeleton graph, or Rips graph, containing edges when the edge length is less or equal + * to a given threshold. Edge length is computed from a user given point cloud with a given distance function, or a + * distance matrix. + * + * \tparam Filtration_value is the type used to store the filtration values of the simplicial complex. + */ +template +class Cech_complex { + private: + using Vertex_handle = typename SimplicialComplexForCechComplex::Vertex_handle; + using Filtration_value = typename SimplicialComplexForCechComplex::Filtration_value; + using Proximity_graph = Gudhi::Proximity_graph; + + public: + /** \brief Cech_complex constructor from a list of points. + * + * @param[in] points Range of points. + * @param[in] threshold Rips value. + * @param[in] distance distance function that returns a `Filtration_value` from 2 given points. + * + * \tparam ForwardPointRange must be a range for which `std::begin` and `std::end` return input iterators on a + * point. + * + * \tparam Distance furnishes `operator()(const Point& p1, const Point& p2)`, where + * `Point` is a point from the `ForwardPointRange`, and that returns a `Filtration_value`. + */ + template + Cech_complex(const ForwardPointRange& points, Filtration_value threshold, Distance distance) + : threshold_(threshold), + point_cloud_(points) { + GUDHI_CHECK(std::size(points) > 0, + std::invalid_argument("Cech_complex::create_complex - point cloud is empty")); + dimension_ = points[0].size(); + cech_skeleton_graph_ = Gudhi::compute_proximity_graph(point_cloud_, threshold_, distance); + } + + /** \brief Initializes the simplicial complex from the Rips graph and expands it until a given maximal + * dimension. + * + * @param[in] complex SimplicialComplexForCech to be created. + * @param[in] dim_max graph expansion for Rips until this given maximal dimension. + * @exception std::invalid_argument In debug mode, if `complex.num_vertices()` does not return 0. + * + */ + void create_complex(SimplicialComplexForCechComplex& complex, int dim_max) { + GUDHI_CHECK(complex.num_vertices() == 0, + std::invalid_argument("Cech_complex::create_complex - simplicial complex is not empty")); + + // insert the proximity graph in the simplicial complex + complex.insert_graph(cech_skeleton_graph_); + // expand the graph until dimension dim_max + complex.expansion_with_blockers(dim_max, + Cech_blocker(complex, this)); + } + + Filtration_value threshold() const { + return threshold_; + } + + std::size_t dimension() const { + return dimension_; + } + + auto point(std::size_t vertex) const -> decltype(point_cloud_.begin() + vertex) { + GUDHI_CHECK((point_cloud_.begin() + vertex) < point_cloud_.end(), + std::invalid_argument("Cech_complex::point - simplicial complex is not empty")); + return (point_cloud_.begin() + vertex); + } + + private: + Proximity_graph cech_skeleton_graph_; + Filtration_value threshold_; + ForwardPointRange point_cloud_; + std::size_t dimension_; +}; + +} // namespace cech_complex + +} // namespace Gudhi + +#endif // CECH_COMPLEX_H_ diff --git a/src/Cech_complex/include/gudhi/Cech_complex_blocker.h b/src/Cech_complex/include/gudhi/Cech_complex_blocker.h new file mode 100644 index 00000000..647bf0b7 --- /dev/null +++ b/src/Cech_complex/include/gudhi/Cech_complex_blocker.h @@ -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): Vincent Rouvreau + * + * Copyright (C) 2018 Inria + * + * 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 CECH_COMPLEX_BLOCKER_H_ +#define CECH_COMPLEX_BLOCKER_H_ + +#include +#include + +#include + +#include +#include +#include // for std::sqrt + +namespace Gudhi { + +namespace cech_complex { + +// Just declaring Cech_complex class because used and not yet defined. +template +class Cech_complex; + +template +class Cech_blocker { + private: + using Point = std::vector; + using Point_cloud = std::vector; + using Point_iterator = Point_cloud::const_iterator; + using Coordinate_iterator = Point::const_iterator; + using Min_sphere = Miniball::Miniball>; + using Simplex_handle = typename SimplicialComplexForCech::Simplex_handle; + using Filtration_value = typename SimplicialComplexForCech::Filtration_value; + using Cech_complex = Gudhi::cech_complex::Cech_complex; + + public: + bool operator()(Simplex_handle sh) { + Point_cloud points; + for (auto vertex : simplicial_complex_.simplex_vertex_range(sh)) { + points.push_back(cc_ptr_->point(vertex)); +#ifdef DEBUG_TRACES + std::cout << "#(" << vertex << ")#"; +#endif // DEBUG_TRACES + } + Min_sphere ms(cc_ptr_->dimension(), points.begin(),points.end()); + Filtration_value radius = std::sqrt(ms.squared_radius()); +#ifdef DEBUG_TRACES + std::cout << "radius = " << radius << " - " << (radius > cc_ptr_->threshold()) << std::endl; +#endif // DEBUG_TRACES + simplicial_complex_.assign_filtration(sh, radius); + return (radius > cc_ptr_->threshold()); + } + Cech_blocker(SimplicialComplexForCech& simplicial_complex, Cech_complex* cc_ptr) + : simplicial_complex_(simplicial_complex), + cc_ptr_(cc_ptr) { + } + private: + SimplicialComplexForCech simplicial_complex_; + Cech_complex* cc_ptr_; +}; + +} // namespace cech_complex + +} // namespace Gudhi + +#endif // CECH_COMPLEX_BLOCKER_H_ diff --git a/src/cmake/modules/GUDHI_user_version_target.cmake b/src/cmake/modules/GUDHI_user_version_target.cmake index 4abc2574..87141380 100644 --- a/src/cmake/modules/GUDHI_user_version_target.cmake +++ b/src/cmake/modules/GUDHI_user_version_target.cmake @@ -49,9 +49,9 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) set(GUDHI_DIRECTORIES "doc;example;concept;utilities") if (NOT CGAL_VERSION VERSION_GREATER 4.11.0) - set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/gudhi_patches") + set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/Miniball;include/gudhi_patches") else () - set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi") + set(GUDHI_INCLUDE_DIRECTORIES "include/gudhi;include/Miniball") endif () foreach(GUDHI_MODULE ${GUDHI_MODULES_FULL_LIST}) -- cgit v1.2.3 From 76658daa8112d622579a9fac7718f3f94f728862 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 5 Mar 2018 16:03:59 +0000 Subject: Install Miniball with gudhi for Cech to compile git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cechcomplex_vincent@3265 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 35309d8ef71455028fd4abeeba03ece2b0d0461f --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7cccb19f..ff7acafc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,4 +105,5 @@ install(FILES # install the include file on "make install" install(DIRECTORY include/gudhi DESTINATION include) +install(DIRECTORY include/Miniball DESTINATION include) #--------------------------------------------------------------------------------------- -- cgit v1.2.3 From 0d0ca116e7fef77cc950b7e85380495661311d91 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 22 Mar 2018 08:36:00 +0000 Subject: Move Miniball in gudhi git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cechcomplex_vincent@3302 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 736e5c33a9593e4dfb5b19ddc745ab9852d71b40 --- src/CMakeLists.txt | 1 - .../benchmark/cech_complex_benchmark.cpp | 5 +- src/Cech_complex/example/CMakeLists.txt | 2 + .../example/cech_complex_step_by_step.cpp | 4 +- .../include/Miniball/Miniball.COPYRIGHT | 4 - src/Cech_complex/include/Miniball/Miniball.README | 23 - src/Cech_complex/include/Miniball/Miniball.hpp | 520 -------------------- src/Cech_complex/include/gudhi/Miniball.COPYRIGHT | 4 + src/Cech_complex/include/gudhi/Miniball.README | 23 + src/Cech_complex/include/gudhi/Miniball.hpp | 523 +++++++++++++++++++++ src/Cech_complex/test/test_cech_complex.cpp | 5 +- src/common/include/gudhi/distance_functions.h | 2 +- 12 files changed, 559 insertions(+), 557 deletions(-) delete mode 100644 src/Cech_complex/include/Miniball/Miniball.COPYRIGHT delete mode 100644 src/Cech_complex/include/Miniball/Miniball.README delete mode 100644 src/Cech_complex/include/Miniball/Miniball.hpp create mode 100644 src/Cech_complex/include/gudhi/Miniball.COPYRIGHT create mode 100644 src/Cech_complex/include/gudhi/Miniball.README create mode 100644 src/Cech_complex/include/gudhi/Miniball.hpp (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff7acafc..7cccb19f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,5 +105,4 @@ install(FILES # install the include file on "make install" install(DIRECTORY include/gudhi DESTINATION include) -install(DIRECTORY include/Miniball DESTINATION include) #--------------------------------------------------------------------------------------- diff --git a/src/Cech_complex/benchmark/cech_complex_benchmark.cpp b/src/Cech_complex/benchmark/cech_complex_benchmark.cpp index 83ef9dca..6ba52419 100644 --- a/src/Cech_complex/benchmark/cech_complex_benchmark.cpp +++ b/src/Cech_complex/benchmark/cech_complex_benchmark.cpp @@ -27,8 +27,7 @@ #include #include #include - -#include +#include #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations @@ -57,7 +56,7 @@ class Radius_distance { using Point_cloud = std::vector; using Point_iterator = typename Point_cloud::const_iterator; using Coordinate_iterator = typename Point::const_iterator; - using Min_sphere = typename Miniball::Miniball>; + using Min_sphere = typename Gudhi::Miniball::Miniball>; Point_cloud point_cloud; point_cloud.push_back(p1); diff --git a/src/Cech_complex/example/CMakeLists.txt b/src/Cech_complex/example/CMakeLists.txt index ac32ff95..ab391215 100644 --- a/src/Cech_complex/example/CMakeLists.txt +++ b/src/Cech_complex/example/CMakeLists.txt @@ -6,6 +6,8 @@ target_link_libraries(Cech_complex_example_step_by_step ${Boost_PROGRAM_OPTIONS_ if (TBB_FOUND) target_link_libraries(Cech_complex_example_step_by_step ${TBB_LIBRARIES}) endif() +add_test(NAME Cech_complex_utility_from_rips_on_tore_3D COMMAND $ + "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" "-r" "0.25" "-d" "3") add_executable ( Cech_complex_example_from_points cech_complex_example_from_points.cpp) if (TBB_FOUND) diff --git a/src/Cech_complex/example/cech_complex_step_by_step.cpp b/src/Cech_complex/example/cech_complex_step_by_step.cpp index 8705a3e5..0e7c4bbd 100644 --- a/src/Cech_complex/example/cech_complex_step_by_step.cpp +++ b/src/Cech_complex/example/cech_complex_step_by_step.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include @@ -55,7 +55,7 @@ class Cech_blocker { using Point_cloud = std::vector; using Point_iterator = Point_cloud::const_iterator; using Coordinate_iterator = Point::const_iterator; - using Min_sphere = Miniball::Miniball >; + using Min_sphere = Gudhi::Miniball::Miniball >; public: bool operator()(Simplex_handle sh) { std::vector points; diff --git a/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT b/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT deleted file mode 100644 index dbe4c553..00000000 --- a/src/Cech_complex/include/Miniball/Miniball.COPYRIGHT +++ /dev/null @@ -1,4 +0,0 @@ -The miniball software is available under the GNU General Public License (GPLv3 - https://www.gnu.org/copyleft/gpl.html). -If your intended use is not compliant with this license, please buy a commercial license (EUR 500 - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/license.html). -You need a license if the software that you develop using Miniball V3.0 is not open source. - diff --git a/src/Cech_complex/include/Miniball/Miniball.README b/src/Cech_complex/include/Miniball/Miniball.README deleted file mode 100644 index 86a96f08..00000000 --- a/src/Cech_complex/include/Miniball/Miniball.README +++ /dev/null @@ -1,23 +0,0 @@ -https://people.inf.ethz.ch/gaertner/subdir/software/miniball.html - -Smallest Enclosing Balls of Points - Fast and Robust in C++. -(high-quality software for smallest enclosing balls of balls is available in the computational geometry algorithms library CGAL) - - -This is the miniball software (V3.0) for computing smallest enclosing balls of points in arbitrary dimensions. It consists of a C++ header file Miniball.hpp (around 500 lines of code) and two example programs miniball_example.cpp and miniball_example_containers.cpp that demonstrate the usage. The first example stores the coordinates of the input points in a two-dimensional array, the second example uses a list of vectors to show how generic containers can be used. - -Credits: Aditya Gupta and Alexandros Konstantinakis-Karmis have significantly contributed to this version of the software. - -Changes - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/changes.txt - from previous versions. - -The theory - https://people.inf.ethz.ch/gaertner/subdir/texts/own_work/esa99_final.pdf - behind the miniball software (Proc. 7th Annual European Symposium on Algorithms (ESA), Lecture Notes in Computer Science 1643, Springer-Verlag, pp.325-338, 1999). - -Main Features: - - Very fast in low dimensions. 1 million points in 5-space are processed within 0.05 seconds on any recent machine. - - High numerical stability. Almost all input degeneracies (cospherical points, multiple points, points very close together) are routinely handled. - - Easily integrates into your code. You can freely choose the coordinate type of your points and the container to store the points. If you still need to adapt the code, the header is small and readable and contains documentation for all major methods. - - diff --git a/src/Cech_complex/include/Miniball/Miniball.hpp b/src/Cech_complex/include/Miniball/Miniball.hpp deleted file mode 100644 index a42d62a7..00000000 --- a/src/Cech_complex/include/Miniball/Miniball.hpp +++ /dev/null @@ -1,520 +0,0 @@ -// Copright (C) 1999-2013, Bernd Gaertner -// $Rev: 3581 $ -// -// 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 . -// -// Contact: -// -------- -// Bernd Gaertner -// Institute of Theoretical Computer Science -// ETH Zuerich -// CAB G31.1 -// CH-8092 Zuerich, Switzerland -// http://www.inf.ethz.ch/personal/gaertner - -#ifndef MINIBALL_HPP_ -#define MINIBALL_HPP_ - -#include -#include -#include -#include -#include - -namespace Miniball { - - // Global Functions - // ================ - template - inline NT mb_sqr (NT r) {return r*r;} - - // Functors - // ======== - - // functor to map a point iterator to the corresponding coordinate iterator; - // generic version for points whose coordinate containers have begin() - template < typename Pit_, typename Cit_ > - struct CoordAccessor { - typedef Pit_ Pit; - typedef Cit_ Cit; - inline Cit operator() (Pit it) const { return (*it).begin(); } - }; - - // partial specialization for points whose coordinate containers are arrays - template < typename Pit_, typename Cit_ > - struct CoordAccessor { - typedef Pit_ Pit; - typedef Cit_* Cit; - inline Cit operator() (Pit it) const { return *it; } - }; - - // Class Declaration - // ================= - - template - class Miniball { - private: - // types - // The iterator type to go through the input points - typedef typename CoordAccessor::Pit Pit; - // The iterator type to go through the coordinates of a single point. - typedef typename CoordAccessor::Cit Cit; - // The coordinate type - typedef typename std::iterator_traits::value_type NT; - // The iterator to go through the support points - typedef typename std::list::iterator Sit; - - // data members... - const int d; // dimension - Pit points_begin; - Pit points_end; - CoordAccessor coord_accessor; - double time; - const NT nt0; // NT(0) - - //...for the algorithms - std::list L; - Sit support_end; - int fsize; // number of forced points - int ssize; // number of support points - - // ...for the ball updates - NT* current_c; - NT current_sqr_r; - NT** c; - NT* sqr_r; - - // helper arrays - NT* q0; - NT* z; - NT* f; - NT** v; - NT** a; - - public: - // The iterator type to go through the support points - typedef typename std::list::const_iterator SupportPointIterator; - - // PRE: [begin, end) is a nonempty range - // POST: computes the smallest enclosing ball of the points in the range - // [begin, end); the functor a maps a point iterator to an iterator - // through the d coordinates of the point - Miniball (int d_, Pit begin, Pit end, CoordAccessor ca = CoordAccessor()); - - // POST: returns a pointer to the first element of an array that holds - // the d coordinates of the center of the computed ball - const NT* center () const; - - // POST: returns the squared radius of the computed ball - NT squared_radius () const; - - // POST: returns the number of support points of the computed ball; - // the support points form a minimal set with the same smallest - // enclosing ball as the input set; in particular, the support - // points are on the boundary of the computed ball, and their - // number is at most d+1 - int nr_support_points () const; - - // POST: returns an iterator to the first support point - SupportPointIterator support_points_begin () const; - - // POST: returns a past-the-end iterator for the range of support points - SupportPointIterator support_points_end () const; - - // POST: returns the maximum excess of any input point w.r.t. the computed - // ball, divided by the squared radius of the computed ball. The - // excess of a point is the difference between its squared distance - // from the center and the squared radius; Ideally, the return value - // is 0. subopt is set to the absolute value of the most negative - // coefficient in the affine combination of the support points that - // yields the center. Ideally, this is a convex combination, and there - // is no negative coefficient in which case subopt is set to 0. - NT relative_error (NT& subopt) const; - - // POST: return true if the relative error is at most tol, and the - // suboptimality is 0; the default tolerance is 10 times the - // coordinate type's machine epsilon - bool is_valid (NT tol = NT(10) * std::numeric_limits::epsilon()) const; - - // POST: returns the time in seconds taken by the constructor call for - // computing the smallest enclosing ball - double get_time() const; - - // POST: deletes dynamically allocated arrays - ~Miniball(); - - private: - void mtf_mb (Sit n); - void mtf_move_to_front (Sit j); - void pivot_mb (Pit n); - void pivot_move_to_front (Pit j); - NT excess (Pit pit) const; - void pop (); - bool push (Pit pit); - NT suboptimality () const; - void create_arrays(); - void delete_arrays(); - }; - - // Class Definition - // ================ - template - Miniball::Miniball (int d_, Pit begin, Pit end, - CoordAccessor ca) - : d (d_), - points_begin (begin), - points_end (end), - coord_accessor (ca), - time (clock()), - nt0 (NT(0)), - L(), - support_end (L.begin()), - fsize(0), - ssize(0), - current_c (NULL), - current_sqr_r (NT(-1)), - c (NULL), - sqr_r (NULL), - q0 (NULL), - z (NULL), - f (NULL), - v (NULL), - a (NULL) - { - assert (points_begin != points_end); - create_arrays(); - - // set initial center - for (int j=0; j - Miniball::~Miniball() - { - delete_arrays(); - } - - template - void Miniball::create_arrays() - { - c = new NT*[d+1]; - v = new NT*[d+1]; - a = new NT*[d+1]; - for (int i=0; i - void Miniball::delete_arrays() - { - delete[] f; - delete[] z; - delete[] q0; - delete[] sqr_r; - for (int i=0; i - const typename Miniball::NT* - Miniball::center () const - { - return current_c; - } - - template - typename Miniball::NT - Miniball::squared_radius () const - { - return current_sqr_r; - } - - template - int Miniball::nr_support_points () const - { - assert (ssize < d+2); - return ssize; - } - - template - typename Miniball::SupportPointIterator - Miniball::support_points_begin () const - { - return L.begin(); - } - - template - typename Miniball::SupportPointIterator - Miniball::support_points_end () const - { - return support_end; - } - - template - typename Miniball::NT - Miniball::relative_error (NT& subopt) const - { - NT e, max_e = nt0; - // compute maximum absolute excess of support points - for (SupportPointIterator it = support_points_begin(); - it != support_points_end(); ++it) { - e = excess (*it); - if (e < nt0) e = -e; - if (e > max_e) { - max_e = e; - } - } - // compute maximum excess of any point - for (Pit i = points_begin; i != points_end; ++i) - if ((e = excess (i)) > max_e) - max_e = e; - - subopt = suboptimality(); - assert (current_sqr_r > nt0 || max_e == nt0); - return (current_sqr_r == nt0 ? nt0 : max_e / current_sqr_r); - } - - template - bool Miniball::is_valid (NT tol) const - { - NT suboptimality; - return ( (relative_error (suboptimality) <= tol) && (suboptimality == 0) ); - } - - template - double Miniball::get_time() const - { - return time; - } - - template - void Miniball::mtf_mb (Sit n) - { - // Algorithm 1: mtf_mb (L_{n-1}, B), where L_{n-1} = [L.begin, n) - // B: the set of forced points, defining the current ball - // S: the superset of support points computed by the algorithm - // -------------------------------------------------------------- - // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, - // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf - - // PRE: B = S - assert (fsize == ssize); - - support_end = L.begin(); - if ((fsize) == d+1) return; - - // incremental construction - for (Sit i = L.begin(); i != n;) - { - // INV: (support_end - L.begin() == |S|-|B|) - assert (std::distance (L.begin(), support_end) == ssize - fsize); - - Sit j = i++; - if (excess(*j) > nt0) - if (push(*j)) { // B := B + p_i - mtf_mb (j); // mtf_mb (L_{i-1}, B + p_i) - pop(); // B := B - p_i - mtf_move_to_front(j); - } - } - // POST: the range [L.begin(), support_end) stores the set S\B - } - - template - void Miniball::mtf_move_to_front (Sit j) - { - if (support_end == j) - support_end++; - L.splice (L.begin(), L, j); - } - - template - void Miniball::pivot_mb (Pit n) - { - // Algorithm 2: pivot_mb (L_{n-1}), where L_{n-1} = [L.begin, n) - // -------------------------------------------------------------- - // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, - // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf - NT old_sqr_r; - const NT* c; - Pit pivot, k; - NT e, max_e, sqr_r; - Cit p; - do { - old_sqr_r = current_sqr_r; - sqr_r = current_sqr_r; - - pivot = points_begin; - max_e = nt0; - for (k = points_begin; k != n; ++k) { - p = coord_accessor(k); - e = -sqr_r; - c = current_c; - for (int j=0; j(*p++-*c++); - if (e > max_e) { - max_e = e; - pivot = k; - } - } - - if (max_e > nt0) { - // check if the pivot is already contained in the support set - if (std::find(L.begin(), support_end, pivot) == support_end) { - assert (fsize == 0); - if (push (pivot)) { - mtf_mb(support_end); - pop(); - pivot_move_to_front(pivot); - } - } - } - } while (old_sqr_r < current_sqr_r); - } - - template - void Miniball::pivot_move_to_front (Pit j) - { - L.push_front(j); - if (std::distance(L.begin(), support_end) == d+2) - support_end--; - } - - template - inline typename Miniball::NT - Miniball::excess (Pit pit) const - { - Cit p = coord_accessor(pit); - NT e = -current_sqr_r; - NT* c = current_c; - for (int k=0; k(*p++-*c++); - } - return e; - } - - template - void Miniball::pop () - { - --fsize; - } - - template - bool Miniball::push (Pit pit) - { - int i, j; - NT eps = mb_sqr(std::numeric_limits::epsilon()); - - Cit cit = coord_accessor(pit); - Cit p = cit; - - if (fsize==0) { - for (i=0; i(v[fsize][j]); - z[fsize]*=2; - - // reject push if z_fsize too small - if (z[fsize](*p++-c[fsize-1][i]); - f[fsize]=e/z[fsize]; - - for (i=0; i - typename Miniball::NT - Miniball::suboptimality () const - { - NT* l = new NT[d+1]; - NT min_l = nt0; - l[0] = NT(1); - for (int i=ssize-1; i>0; --i) { - l[i] = f[i]; - for (int k=ssize-1; k>i; --k) - l[i]-=a[k][i]*l[k]; - if (l[i] < min_l) min_l = l[i]; - l[0] -= l[i]; - } - if (l[0] < min_l) min_l = l[0]; - delete[] l; - if (min_l < nt0) - return -min_l; - return nt0; - } - -} // end Namespace Miniball - -#endif // MINIBALL_HPP_ diff --git a/src/Cech_complex/include/gudhi/Miniball.COPYRIGHT b/src/Cech_complex/include/gudhi/Miniball.COPYRIGHT new file mode 100644 index 00000000..dbe4c553 --- /dev/null +++ b/src/Cech_complex/include/gudhi/Miniball.COPYRIGHT @@ -0,0 +1,4 @@ +The miniball software is available under the GNU General Public License (GPLv3 - https://www.gnu.org/copyleft/gpl.html). +If your intended use is not compliant with this license, please buy a commercial license (EUR 500 - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/license.html). +You need a license if the software that you develop using Miniball V3.0 is not open source. + diff --git a/src/Cech_complex/include/gudhi/Miniball.README b/src/Cech_complex/include/gudhi/Miniball.README new file mode 100644 index 00000000..86a96f08 --- /dev/null +++ b/src/Cech_complex/include/gudhi/Miniball.README @@ -0,0 +1,23 @@ +https://people.inf.ethz.ch/gaertner/subdir/software/miniball.html + +Smallest Enclosing Balls of Points - Fast and Robust in C++. +(high-quality software for smallest enclosing balls of balls is available in the computational geometry algorithms library CGAL) + + +This is the miniball software (V3.0) for computing smallest enclosing balls of points in arbitrary dimensions. It consists of a C++ header file Miniball.hpp (around 500 lines of code) and two example programs miniball_example.cpp and miniball_example_containers.cpp that demonstrate the usage. The first example stores the coordinates of the input points in a two-dimensional array, the second example uses a list of vectors to show how generic containers can be used. + +Credits: Aditya Gupta and Alexandros Konstantinakis-Karmis have significantly contributed to this version of the software. + +Changes - https://people.inf.ethz.ch/gaertner/subdir/software/miniball/changes.txt - from previous versions. + +The theory - https://people.inf.ethz.ch/gaertner/subdir/texts/own_work/esa99_final.pdf - behind the miniball software (Proc. 7th Annual European Symposium on Algorithms (ESA), Lecture Notes in Computer Science 1643, Springer-Verlag, pp.325-338, 1999). + +Main Features: + + Very fast in low dimensions. 1 million points in 5-space are processed within 0.05 seconds on any recent machine. + + High numerical stability. Almost all input degeneracies (cospherical points, multiple points, points very close together) are routinely handled. + + Easily integrates into your code. You can freely choose the coordinate type of your points and the container to store the points. If you still need to adapt the code, the header is small and readable and contains documentation for all major methods. + + diff --git a/src/Cech_complex/include/gudhi/Miniball.hpp b/src/Cech_complex/include/gudhi/Miniball.hpp new file mode 100644 index 00000000..ce6cbb5b --- /dev/null +++ b/src/Cech_complex/include/gudhi/Miniball.hpp @@ -0,0 +1,523 @@ +// Copright (C) 1999-2013, Bernd Gaertner +// $Rev: 3581 $ +// +// 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 . +// +// Contact: +// -------- +// Bernd Gaertner +// Institute of Theoretical Computer Science +// ETH Zuerich +// CAB G31.1 +// CH-8092 Zuerich, Switzerland +// http://www.inf.ethz.ch/personal/gaertner + +#ifndef MINIBALL_HPP_ +#define MINIBALL_HPP_ + +#include +#include +#include +#include +#include + +namespace Gudhi { + +namespace Miniball { + + // Global Functions + // ================ + template + inline NT mb_sqr (NT r) {return r*r;} + + // Functors + // ======== + + // functor to map a point iterator to the corresponding coordinate iterator; + // generic version for points whose coordinate containers have begin() + template < typename Pit_, typename Cit_ > + struct CoordAccessor { + typedef Pit_ Pit; + typedef Cit_ Cit; + inline Cit operator() (Pit it) const { return (*it).begin(); } + }; + + // partial specialization for points whose coordinate containers are arrays + template < typename Pit_, typename Cit_ > + struct CoordAccessor { + typedef Pit_ Pit; + typedef Cit_* Cit; + inline Cit operator() (Pit it) const { return *it; } + }; + + // Class Declaration + // ================= + + template + class Miniball { + private: + // types + // The iterator type to go through the input points + typedef typename CoordAccessor::Pit Pit; + // The iterator type to go through the coordinates of a single point. + typedef typename CoordAccessor::Cit Cit; + // The coordinate type + typedef typename std::iterator_traits::value_type NT; + // The iterator to go through the support points + typedef typename std::list::iterator Sit; + + // data members... + const int d; // dimension + Pit points_begin; + Pit points_end; + CoordAccessor coord_accessor; + double time; + const NT nt0; // NT(0) + + //...for the algorithms + std::list L; + Sit support_end; + int fsize; // number of forced points + int ssize; // number of support points + + // ...for the ball updates + NT* current_c; + NT current_sqr_r; + NT** c; + NT* sqr_r; + + // helper arrays + NT* q0; + NT* z; + NT* f; + NT** v; + NT** a; + + public: + // The iterator type to go through the support points + typedef typename std::list::const_iterator SupportPointIterator; + + // PRE: [begin, end) is a nonempty range + // POST: computes the smallest enclosing ball of the points in the range + // [begin, end); the functor a maps a point iterator to an iterator + // through the d coordinates of the point + Miniball (int d_, Pit begin, Pit end, CoordAccessor ca = CoordAccessor()); + + // POST: returns a pointer to the first element of an array that holds + // the d coordinates of the center of the computed ball + const NT* center () const; + + // POST: returns the squared radius of the computed ball + NT squared_radius () const; + + // POST: returns the number of support points of the computed ball; + // the support points form a minimal set with the same smallest + // enclosing ball as the input set; in particular, the support + // points are on the boundary of the computed ball, and their + // number is at most d+1 + int nr_support_points () const; + + // POST: returns an iterator to the first support point + SupportPointIterator support_points_begin () const; + + // POST: returns a past-the-end iterator for the range of support points + SupportPointIterator support_points_end () const; + + // POST: returns the maximum excess of any input point w.r.t. the computed + // ball, divided by the squared radius of the computed ball. The + // excess of a point is the difference between its squared distance + // from the center and the squared radius; Ideally, the return value + // is 0. subopt is set to the absolute value of the most negative + // coefficient in the affine combination of the support points that + // yields the center. Ideally, this is a convex combination, and there + // is no negative coefficient in which case subopt is set to 0. + NT relative_error (NT& subopt) const; + + // POST: return true if the relative error is at most tol, and the + // suboptimality is 0; the default tolerance is 10 times the + // coordinate type's machine epsilon + bool is_valid (NT tol = NT(10) * std::numeric_limits::epsilon()) const; + + // POST: returns the time in seconds taken by the constructor call for + // computing the smallest enclosing ball + double get_time() const; + + // POST: deletes dynamically allocated arrays + ~Miniball(); + + private: + void mtf_mb (Sit n); + void mtf_move_to_front (Sit j); + void pivot_mb (Pit n); + void pivot_move_to_front (Pit j); + NT excess (Pit pit) const; + void pop (); + bool push (Pit pit); + NT suboptimality () const; + void create_arrays(); + void delete_arrays(); + }; + + // Class Definition + // ================ + template + Miniball::Miniball (int d_, Pit begin, Pit end, + CoordAccessor ca) + : d (d_), + points_begin (begin), + points_end (end), + coord_accessor (ca), + time (clock()), + nt0 (NT(0)), + L(), + support_end (L.begin()), + fsize(0), + ssize(0), + current_c (NULL), + current_sqr_r (NT(-1)), + c (NULL), + sqr_r (NULL), + q0 (NULL), + z (NULL), + f (NULL), + v (NULL), + a (NULL) + { + assert (points_begin != points_end); + create_arrays(); + + // set initial center + for (int j=0; j + Miniball::~Miniball() + { + delete_arrays(); + } + + template + void Miniball::create_arrays() + { + c = new NT*[d+1]; + v = new NT*[d+1]; + a = new NT*[d+1]; + for (int i=0; i + void Miniball::delete_arrays() + { + delete[] f; + delete[] z; + delete[] q0; + delete[] sqr_r; + for (int i=0; i + const typename Miniball::NT* + Miniball::center () const + { + return current_c; + } + + template + typename Miniball::NT + Miniball::squared_radius () const + { + return current_sqr_r; + } + + template + int Miniball::nr_support_points () const + { + assert (ssize < d+2); + return ssize; + } + + template + typename Miniball::SupportPointIterator + Miniball::support_points_begin () const + { + return L.begin(); + } + + template + typename Miniball::SupportPointIterator + Miniball::support_points_end () const + { + return support_end; + } + + template + typename Miniball::NT + Miniball::relative_error (NT& subopt) const + { + NT e, max_e = nt0; + // compute maximum absolute excess of support points + for (SupportPointIterator it = support_points_begin(); + it != support_points_end(); ++it) { + e = excess (*it); + if (e < nt0) e = -e; + if (e > max_e) { + max_e = e; + } + } + // compute maximum excess of any point + for (Pit i = points_begin; i != points_end; ++i) + if ((e = excess (i)) > max_e) + max_e = e; + + subopt = suboptimality(); + assert (current_sqr_r > nt0 || max_e == nt0); + return (current_sqr_r == nt0 ? nt0 : max_e / current_sqr_r); + } + + template + bool Miniball::is_valid (NT tol) const + { + NT suboptimality; + return ( (relative_error (suboptimality) <= tol) && (suboptimality == 0) ); + } + + template + double Miniball::get_time() const + { + return time; + } + + template + void Miniball::mtf_mb (Sit n) + { + // Algorithm 1: mtf_mb (L_{n-1}, B), where L_{n-1} = [L.begin, n) + // B: the set of forced points, defining the current ball + // S: the superset of support points computed by the algorithm + // -------------------------------------------------------------- + // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, + // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf + + // PRE: B = S + assert (fsize == ssize); + + support_end = L.begin(); + if ((fsize) == d+1) return; + + // incremental construction + for (Sit i = L.begin(); i != n;) + { + // INV: (support_end - L.begin() == |S|-|B|) + assert (std::distance (L.begin(), support_end) == ssize - fsize); + + Sit j = i++; + if (excess(*j) > nt0) + if (push(*j)) { // B := B + p_i + mtf_mb (j); // mtf_mb (L_{i-1}, B + p_i) + pop(); // B := B - p_i + mtf_move_to_front(j); + } + } + // POST: the range [L.begin(), support_end) stores the set S\B + } + + template + void Miniball::mtf_move_to_front (Sit j) + { + if (support_end == j) + support_end++; + L.splice (L.begin(), L, j); + } + + template + void Miniball::pivot_mb (Pit n) + { + // Algorithm 2: pivot_mb (L_{n-1}), where L_{n-1} = [L.begin, n) + // -------------------------------------------------------------- + // from B. Gaertner, Fast and Robust Smallest Enclosing Balls, ESA 1999, + // http://www.inf.ethz.ch/personal/gaertner/texts/own_work/esa99_final.pdf + NT old_sqr_r; + const NT* c; + Pit pivot, k; + NT e, max_e, sqr_r; + Cit p; + do { + old_sqr_r = current_sqr_r; + sqr_r = current_sqr_r; + + pivot = points_begin; + max_e = nt0; + for (k = points_begin; k != n; ++k) { + p = coord_accessor(k); + e = -sqr_r; + c = current_c; + for (int j=0; j(*p++-*c++); + if (e > max_e) { + max_e = e; + pivot = k; + } + } + + if (max_e > nt0) { + // check if the pivot is already contained in the support set + if (std::find(L.begin(), support_end, pivot) == support_end) { + assert (fsize == 0); + if (push (pivot)) { + mtf_mb(support_end); + pop(); + pivot_move_to_front(pivot); + } + } + } + } while (old_sqr_r < current_sqr_r); + } + + template + void Miniball::pivot_move_to_front (Pit j) + { + L.push_front(j); + if (std::distance(L.begin(), support_end) == d+2) + support_end--; + } + + template + inline typename Miniball::NT + Miniball::excess (Pit pit) const + { + Cit p = coord_accessor(pit); + NT e = -current_sqr_r; + NT* c = current_c; + for (int k=0; k(*p++-*c++); + } + return e; + } + + template + void Miniball::pop () + { + --fsize; + } + + template + bool Miniball::push (Pit pit) + { + int i, j; + NT eps = mb_sqr(std::numeric_limits::epsilon()); + + Cit cit = coord_accessor(pit); + Cit p = cit; + + if (fsize==0) { + for (i=0; i(v[fsize][j]); + z[fsize]*=2; + + // reject push if z_fsize too small + if (z[fsize](*p++-c[fsize-1][i]); + f[fsize]=e/z[fsize]; + + for (i=0; i + typename Miniball::NT + Miniball::suboptimality () const + { + NT* l = new NT[d+1]; + NT min_l = nt0; + l[0] = NT(1); + for (int i=ssize-1; i>0; --i) { + l[i] = f[i]; + for (int k=ssize-1; k>i; --k) + l[i]-=a[k][i]*l[k]; + if (l[i] < min_l) min_l = l[i]; + l[0] -= l[i]; + } + if (l[0] < min_l) min_l = l[0]; + delete[] l; + if (min_l < nt0) + return -min_l; + return nt0; + } +} // namespace Miniball + +} // namespace Gudhi + +#endif // MINIBALL_HPP_ diff --git a/src/Cech_complex/test/test_cech_complex.cpp b/src/Cech_complex/test/test_cech_complex.cpp index 8cbfe431..4aa85057 100644 --- a/src/Cech_complex/test/test_cech_complex.cpp +++ b/src/Cech_complex/test/test_cech_complex.cpp @@ -36,8 +36,7 @@ #include #include #include - -#include +#include // Type definitions using Simplex_tree = Gudhi::Simplex_tree<>; @@ -49,7 +48,7 @@ using Cech_complex = Gudhi::cech_complex::Cech_complex>; +using Min_sphere = Gudhi::Miniball::Miniball>; BOOST_AUTO_TEST_CASE(Cech_complex_for_documentation) { // ---------------------------------------------------------------------------- diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index 7749b98e..93956a69 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -25,7 +25,7 @@ #include -#include +#include #include -- cgit v1.2.3 From 00a3424bd68ced3e2d159acf8b2e73f515a3d88b Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 15 May 2018 19:55:31 +0000 Subject: CMake minimal version is now 3.1 Compilation flags are now externalized in cmake/modules Add NO_POLICY_SCOPE for GUDHI_third_parties to fix warnings Try to fix CGAL 4.12 that is no more setting CGAL_LIBRARIES git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cmake_v3_vincent@3445 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 0ac7613f016e28cc634606f76e85ecaf5bacb2d4 --- CMakeLists.txt | 29 ++++------------ src/Alpha_complex/example/CMakeLists.txt | 1 - src/Alpha_complex/test/CMakeLists.txt | 1 - src/Alpha_complex/utilities/CMakeLists.txt | 1 - src/Bitmap_cubical_complex/example/CMakeLists.txt | 1 - src/Bitmap_cubical_complex/test/CMakeLists.txt | 1 - .../utilities/CMakeLists.txt | 1 - src/Bottleneck_distance/benchmark/CMakeLists.txt | 1 - src/Bottleneck_distance/example/CMakeLists.txt | 1 - src/Bottleneck_distance/test/CMakeLists.txt | 1 - src/Bottleneck_distance/utilities/CMakeLists.txt | 1 - src/CMakeLists.txt | 39 ++++++---------------- src/Contraction/example/CMakeLists.txt | 1 - src/GudhUI/CMakeLists.txt | 3 +- src/Nerve_GIC/example/CMakeLists.txt | 7 ++-- src/Nerve_GIC/test/CMakeLists.txt | 1 - src/Nerve_GIC/utilities/CMakeLists.txt | 1 - .../example/CMakeLists.txt | 1 - .../test/CMakeLists.txt | 1 - .../utilities/persistence_heat_maps/CMakeLists.txt | 1 - .../utilities/persistence_intervals/CMakeLists.txt | 1 - .../persistence_landscapes/CMakeLists.txt | 1 - .../persistence_landscapes_on_grid/CMakeLists.txt | 1 - .../utilities/persistence_vectors/CMakeLists.txt | 1 - src/Persistent_cohomology/benchmark/CMakeLists.txt | 2 -- src/Persistent_cohomology/example/CMakeLists.txt | 1 - src/Persistent_cohomology/test/CMakeLists.txt | 1 - src/Rips_complex/example/CMakeLists.txt | 1 - src/Rips_complex/test/CMakeLists.txt | 1 - src/Rips_complex/utilities/CMakeLists.txt | 1 - src/Simplex_tree/example/CMakeLists.txt | 1 - src/Simplex_tree/test/CMakeLists.txt | 1 - src/Skeleton_blocker/example/CMakeLists.txt | 1 - src/Skeleton_blocker/test/CMakeLists.txt | 1 - src/Spatial_searching/example/CMakeLists.txt | 1 - src/Spatial_searching/test/CMakeLists.txt | 1 - src/Subsampling/example/CMakeLists.txt | 1 - src/Subsampling/test/CMakeLists.txt | 1 - src/Tangential_complex/benchmark/CMakeLists.txt | 1 - src/Tangential_complex/example/CMakeLists.txt | 1 - src/Tangential_complex/test/CMakeLists.txt | 1 - src/Witness_complex/example/CMakeLists.txt | 1 - src/Witness_complex/test/CMakeLists.txt | 1 - src/Witness_complex/utilities/CMakeLists.txt | 1 - src/cmake/modules/GUDHI_compilation_flags.cmake | 36 ++++++++++++++++++++ src/common/example/CMakeLists.txt | 1 - src/common/test/CMakeLists.txt | 1 - src/common/utilities/CMakeLists.txt | 1 - src/cython/CMakeLists.txt | 6 ++-- 49 files changed, 60 insertions(+), 104 deletions(-) create mode 100644 src/cmake/modules/GUDHI_compilation_flags.cmake (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index 10373f75..08291b54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,35 +1,18 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.1) + project(GUDHIdev) include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") -enable_testing() - -# This variable is used by Cython CMakeLists.txt to know its path +# This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path set(GUDHI_CYTHON_PATH "src/cython") -# For third parties libraries management - To be done last as CGAL updates CMAKE_MODULE_PATH -include(GUDHI_third_party_libraries) - -if(MSVC) - # Turn off some VC++ warnings - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") -endif() -if(CMAKE_BUILD_TYPE MATCHES Debug) - message("++ Debug compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") -else() - message("++ Release compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") -endif() +# For third parties libraries management - To be done last as CGAL updates CMAKE_MODULE_PATH +include(GUDHI_third_party_libraries NO_POLICY_SCOPE) -if (DEBUG_TRACES) - # For programs to be more verbose - message(STATUS "DEBUG_TRACES are activated") - add_definitions(-DDEBUG_TRACES) -endif() +include(GUDHI_compilation_flags) # Add your new module in the list, order is not important include(GUDHI_modules) diff --git a/src/Alpha_complex/example/CMakeLists.txt b/src/Alpha_complex/example/CMakeLists.txt index 5bf553e9..2fc62452 100644 --- a/src/Alpha_complex/example/CMakeLists.txt +++ b/src/Alpha_complex/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Alpha_complex_examples) # need CGAL 4.7 diff --git a/src/Alpha_complex/test/CMakeLists.txt b/src/Alpha_complex/test/CMakeLists.txt index 9e0b3b3c..9255d3db 100644 --- a/src/Alpha_complex/test/CMakeLists.txt +++ b/src/Alpha_complex/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Alpha_complex_tests) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) diff --git a/src/Alpha_complex/utilities/CMakeLists.txt b/src/Alpha_complex/utilities/CMakeLists.txt index a2dfac20..7ace6064 100644 --- a/src/Alpha_complex/utilities/CMakeLists.txt +++ b/src/Alpha_complex/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Alpha_complex_utilities) if(CGAL_FOUND) diff --git a/src/Bitmap_cubical_complex/example/CMakeLists.txt b/src/Bitmap_cubical_complex/example/CMakeLists.txt index 99304aa4..dc659f2d 100644 --- a/src/Bitmap_cubical_complex/example/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bitmap_cubical_complex_examples) add_executable ( Random_bitmap_cubical_complex Random_bitmap_cubical_complex.cpp ) diff --git a/src/Bitmap_cubical_complex/test/CMakeLists.txt b/src/Bitmap_cubical_complex/test/CMakeLists.txt index 02b026f2..8b43632a 100644 --- a/src/Bitmap_cubical_complex/test/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bitmap_cubical_complex_tests) include(GUDHI_test_coverage) diff --git a/src/Bitmap_cubical_complex/utilities/CMakeLists.txt b/src/Bitmap_cubical_complex/utilities/CMakeLists.txt index 676a730a..416db67f 100644 --- a/src/Bitmap_cubical_complex/utilities/CMakeLists.txt +++ b/src/Bitmap_cubical_complex/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bitmap_cubical_complex_utilities) add_executable ( cubical_complex_persistence cubical_complex_persistence.cpp ) diff --git a/src/Bottleneck_distance/benchmark/CMakeLists.txt b/src/Bottleneck_distance/benchmark/CMakeLists.txt index 20a4e47b..3105a1d5 100644 --- a/src/Bottleneck_distance/benchmark/CMakeLists.txt +++ b/src/Bottleneck_distance/benchmark/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bottleneck_distance_benchmark) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) diff --git a/src/Bottleneck_distance/example/CMakeLists.txt b/src/Bottleneck_distance/example/CMakeLists.txt index 6095d6eb..c6f10127 100644 --- a/src/Bottleneck_distance/example/CMakeLists.txt +++ b/src/Bottleneck_distance/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bottleneck_distance_examples) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) diff --git a/src/Bottleneck_distance/test/CMakeLists.txt b/src/Bottleneck_distance/test/CMakeLists.txt index 2676b82c..bb739280 100644 --- a/src/Bottleneck_distance/test/CMakeLists.txt +++ b/src/Bottleneck_distance/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bottleneck_distance_tests) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) diff --git a/src/Bottleneck_distance/utilities/CMakeLists.txt b/src/Bottleneck_distance/utilities/CMakeLists.txt index d19e3b1c..2f35885c 100644 --- a/src/Bottleneck_distance/utilities/CMakeLists.txt +++ b/src/Bottleneck_distance/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Bottleneck_distance_utilities) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94587044..5d543018 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,19 @@ -cmake_minimum_required(VERSION 2.6) -project(GUDHI) +cmake_minimum_required(VERSION 3.1) -include("CMakeGUDHIVersion.txt") +project(GUDHI) -enable_testing() +include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") +# This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path +set(GUDHI_CYTHON_PATH "cython") + +# For third parties libraries management - To be done last as CGAL updates CMAKE_MODULE_PATH +include(GUDHI_third_party_libraries NO_POLICY_SCOPE) + +include(GUDHI_compilation_flags) + # Add your new module in the list, order is not important include(GUDHI_modules) @@ -33,30 +40,6 @@ message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") set(GUDHI_USER_VERSION_DIR ${CMAKE_SOURCE_DIR}) include(GUDHI_doxygen_target) -# This variable is used by Cython CMakeLists.txt to know its path -set(GUDHI_CYTHON_PATH "cython") -# For third parties libraries management - To be done last as CGAL updates CMAKE_MODULE_PATH -include(GUDHI_third_party_libraries) - -if(MSVC) - # Turn off some VC++ warnings - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic") -endif() - -if(CMAKE_BUILD_TYPE MATCHES Debug) - message("++ Debug compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") -else() - message("++ Release compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") -endif() - -if (DEBUG_TRACES) - message(STATUS "DEBUG_TRACES are activated") - # For programs to be more verbose - add_definitions(-DDEBUG_TRACES) -endif() - #--------------------------------------------------------------------------------------- # Gudhi compilation part include_directories(include) diff --git a/src/Contraction/example/CMakeLists.txt b/src/Contraction/example/CMakeLists.txt index a92d1685..582b7ab8 100644 --- a/src/Contraction/example/CMakeLists.txt +++ b/src/Contraction/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Contraction_examples) add_executable(RipsContraction Rips_contraction.cpp) diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt index 2503a03e..b357b8f7 100644 --- a/src/GudhUI/CMakeLists.txt +++ b/src/GudhUI/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.8) project(GudhUI) # Need to find OpenGL first as find_package(Qt5) tries to #include"GL/gl.h" on some platforms @@ -38,4 +37,4 @@ if (OPENGL_FOUND) install(TARGETS GudhUI DESTINATION bin) endif() -endif(OPENGL_FOUND) \ No newline at end of file +endif(OPENGL_FOUND) diff --git a/src/Nerve_GIC/example/CMakeLists.txt b/src/Nerve_GIC/example/CMakeLists.txt index 542c6af4..fdecf86e 100644 --- a/src/Nerve_GIC/example/CMakeLists.txt +++ b/src/Nerve_GIC/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Nerve_GIC_examples) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) @@ -17,11 +16,11 @@ if (NOT CGAL_VERSION VERSION_LESS 4.8.1) file(COPY "${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) add_test(NAME Nerve_GIC_example_CoordGIC COMMAND $ - "tore3D_1307.off" "0") + "${CMAKE_CURRENT_BINARY_DIR}/tore3D_1307.off" "0") add_test(NAME Nerve_GIC_example_FuncGIC COMMAND $ - "lucky_cat.off" - "lucky_cat_PCA1") + "${CMAKE_CURRENT_BINARY_DIR}/lucky_cat.off" + "${CMAKE_CURRENT_BINARY_DIR}/lucky_cat_PCA1") install(TARGETS CoordGIC DESTINATION bin) install(TARGETS FuncGIC DESTINATION bin) diff --git a/src/Nerve_GIC/test/CMakeLists.txt b/src/Nerve_GIC/test/CMakeLists.txt index c35cdff7..99263ea0 100644 --- a/src/Nerve_GIC/test/CMakeLists.txt +++ b/src/Nerve_GIC/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Graph_induced_complex_tests) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) diff --git a/src/Nerve_GIC/utilities/CMakeLists.txt b/src/Nerve_GIC/utilities/CMakeLists.txt index 7a838a8c..215f9dfd 100644 --- a/src/Nerve_GIC/utilities/CMakeLists.txt +++ b/src/Nerve_GIC/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Nerve_GIC_examples) if (NOT CGAL_VERSION VERSION_LESS 4.8.1) diff --git a/src/Persistence_representations/example/CMakeLists.txt b/src/Persistence_representations/example/CMakeLists.txt index 54d719ac..33558df3 100644 --- a/src/Persistence_representations/example/CMakeLists.txt +++ b/src/Persistence_representations/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_example) add_executable ( Persistence_representations_example_landscape_on_grid persistence_landscape_on_grid.cpp ) diff --git a/src/Persistence_representations/test/CMakeLists.txt b/src/Persistence_representations/test/CMakeLists.txt index 335a71ef..5e2b6910 100644 --- a/src/Persistence_representations/test/CMakeLists.txt +++ b/src/Persistence_representations/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_test) include(GUDHI_test_coverage) diff --git a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt index 386e9fa5..89ef232f 100644 --- a/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_heat_maps/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_heat_maps_utilities) add_persistence_representation_creation_utility(create_pssk "10" "-1" "-1" "4" "-1") diff --git a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt index 875ff45e..649b72cb 100644 --- a/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_intervals/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_intervals_utilities) diff --git a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt index d7087ed8..6b24d032 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_landscapes/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_landscapes_utilities) add_persistence_representation_creation_utility(create_landscapes "-1") diff --git a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt index c5ea4bbf..36f3196b 100644 --- a/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_landscapes_on_grid/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_representations_lanscapes_on_grid_utilities) # Need to set grid min and max for further average, distance and scalar_product diff --git a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt index a401c955..bc982094 100644 --- a/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt +++ b/src/Persistence_representations/utilities/persistence_vectors/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistence_vectors_utilities) add_persistence_representation_creation_utility(create_persistence_vectors "-1") diff --git a/src/Persistent_cohomology/benchmark/CMakeLists.txt b/src/Persistent_cohomology/benchmark/CMakeLists.txt index 8b135ba1..2bb3b0c7 100644 --- a/src/Persistent_cohomology/benchmark/CMakeLists.txt +++ b/src/Persistent_cohomology/benchmark/CMakeLists.txt @@ -1,6 +1,4 @@ -cmake_minimum_required(VERSION 2.6) project(Persistent_cohomology_benchmark) - if(GMP_FOUND) if(GMPXX_FOUND) diff --git a/src/Persistent_cohomology/example/CMakeLists.txt b/src/Persistent_cohomology/example/CMakeLists.txt index 18e2913b..0f731519 100644 --- a/src/Persistent_cohomology/example/CMakeLists.txt +++ b/src/Persistent_cohomology/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistent_cohomology_examples) add_executable(plain_homology plain_homology.cpp) diff --git a/src/Persistent_cohomology/test/CMakeLists.txt b/src/Persistent_cohomology/test/CMakeLists.txt index 45f53eb9..f8baf861 100644 --- a/src/Persistent_cohomology/test/CMakeLists.txt +++ b/src/Persistent_cohomology/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Persistent_cohomology_tests) include(GUDHI_test_coverage) diff --git a/src/Rips_complex/example/CMakeLists.txt b/src/Rips_complex/example/CMakeLists.txt index af86636b..e7772bdb 100644 --- a/src/Rips_complex/example/CMakeLists.txt +++ b/src/Rips_complex/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Rips_complex_examples) # Point cloud diff --git a/src/Rips_complex/test/CMakeLists.txt b/src/Rips_complex/test/CMakeLists.txt index 3da9c90d..745d953c 100644 --- a/src/Rips_complex/test/CMakeLists.txt +++ b/src/Rips_complex/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Rips_complex_tests) include(GUDHI_test_coverage) diff --git a/src/Rips_complex/utilities/CMakeLists.txt b/src/Rips_complex/utilities/CMakeLists.txt index deb73ff0..4b565628 100644 --- a/src/Rips_complex/utilities/CMakeLists.txt +++ b/src/Rips_complex/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Rips_complex_utilities) add_executable(rips_distance_matrix_persistence rips_distance_matrix_persistence.cpp) diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt index b33b2d05..857e8518 100644 --- a/src/Simplex_tree/example/CMakeLists.txt +++ b/src/Simplex_tree/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Simplex_tree_examples) add_executable ( Simplex_tree_example_from_cliques_of_graph simplex_tree_from_cliques_of_graph.cpp ) diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt index 8684ad2a..c63d8532 100644 --- a/src/Simplex_tree/test/CMakeLists.txt +++ b/src/Simplex_tree/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Simplex_tree_tests) include(GUDHI_test_coverage) diff --git a/src/Skeleton_blocker/example/CMakeLists.txt b/src/Skeleton_blocker/example/CMakeLists.txt index de70f089..0e5d2f11 100644 --- a/src/Skeleton_blocker/example/CMakeLists.txt +++ b/src/Skeleton_blocker/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Skeleton_blocker_examples) add_executable(Skeleton_blocker_example_from_simplices Skeleton_blocker_from_simplices.cpp) diff --git a/src/Skeleton_blocker/test/CMakeLists.txt b/src/Skeleton_blocker/test/CMakeLists.txt index 4a363294..19c65871 100644 --- a/src/Skeleton_blocker/test/CMakeLists.txt +++ b/src/Skeleton_blocker/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Skeleton_blocker_tests) include(GUDHI_test_coverage) diff --git a/src/Spatial_searching/example/CMakeLists.txt b/src/Spatial_searching/example/CMakeLists.txt index 4cf3d863..0f799987 100644 --- a/src/Spatial_searching/example/CMakeLists.txt +++ b/src/Spatial_searching/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Spatial_searching_examples) if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Spatial_searching/test/CMakeLists.txt b/src/Spatial_searching/test/CMakeLists.txt index b9da7b4e..b60ab1e3 100644 --- a/src/Spatial_searching/test/CMakeLists.txt +++ b/src/Spatial_searching/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Spatial_searching_tests) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Subsampling/example/CMakeLists.txt b/src/Subsampling/example/CMakeLists.txt index 34400b1e..f26d107f 100644 --- a/src/Subsampling/example/CMakeLists.txt +++ b/src/Subsampling/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Subsampling_examples) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Subsampling/test/CMakeLists.txt b/src/Subsampling/test/CMakeLists.txt index dbf97db3..924f0925 100644 --- a/src/Subsampling/test/CMakeLists.txt +++ b/src/Subsampling/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Subsampling_tests) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Tangential_complex/benchmark/CMakeLists.txt b/src/Tangential_complex/benchmark/CMakeLists.txt index 8729e394..f136ab27 100644 --- a/src/Tangential_complex/benchmark/CMakeLists.txt +++ b/src/Tangential_complex/benchmark/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Tangential_complex_benchmark) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Tangential_complex/example/CMakeLists.txt b/src/Tangential_complex/example/CMakeLists.txt index 16d1339d..af0dac51 100644 --- a/src/Tangential_complex/example/CMakeLists.txt +++ b/src/Tangential_complex/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Tangential_complex_examples) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Tangential_complex/test/CMakeLists.txt b/src/Tangential_complex/test/CMakeLists.txt index 1948c8f6..902f19af 100644 --- a/src/Tangential_complex/test/CMakeLists.txt +++ b/src/Tangential_complex/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Tangential_complex_tests) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) diff --git a/src/Witness_complex/example/CMakeLists.txt b/src/Witness_complex/example/CMakeLists.txt index a8231392..3d838c0d 100644 --- a/src/Witness_complex/example/CMakeLists.txt +++ b/src/Witness_complex/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Witness_complex_examples) add_executable ( Witness_complex_example_nearest_landmark_table example_nearest_landmark_table.cpp ) diff --git a/src/Witness_complex/test/CMakeLists.txt b/src/Witness_complex/test/CMakeLists.txt index 0b523eaf..58ac60c5 100644 --- a/src/Witness_complex/test/CMakeLists.txt +++ b/src/Witness_complex/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Witness_complex_tests) include(GUDHI_test_coverage) diff --git a/src/Witness_complex/utilities/CMakeLists.txt b/src/Witness_complex/utilities/CMakeLists.txt index 125a41ff..ce5e29f2 100644 --- a/src/Witness_complex/utilities/CMakeLists.txt +++ b/src/Witness_complex/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Witness_complex_utilities) # CGAL and Eigen3 are required for Euclidean version of Witness diff --git a/src/cmake/modules/GUDHI_compilation_flags.cmake b/src/cmake/modules/GUDHI_compilation_flags.cmake new file mode 100644 index 00000000..614d3812 --- /dev/null +++ b/src/cmake/modules/GUDHI_compilation_flags.cmake @@ -0,0 +1,36 @@ +# This files manage compilation flags required by GUDHI + +include(TestCXXAcceptsFlag) + +# add a compiler flag only if it is accepted +macro(add_cxx_compiler_flag _flag) + string(REPLACE "-" "_" _flag_var ${_flag}) + check_cxx_accepts_flag("${_flag}" CXX_COMPILER_${_flag_var}_OK) + if(CXX_COMPILER_${_flag_var}_OK) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}") + endif() +endmacro() + +set (CMAKE_CXX_STANDARD 11) + +enable_testing() + +if(MSVC) + # Turn off some VC++ warnings + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4668 /wd4311 /wd4800 /wd4820 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") +endif() + +add_cxx_compiler_flag("-Wall") +add_cxx_compiler_flag("-pedantic") + +if(CMAKE_BUILD_TYPE MATCHES Debug) + message("++ Debug compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}") +else() + message("++ Release compilation flags are: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") +endif() + +if (DEBUG_TRACES) + # For programs to be more verbose + message(STATUS "DEBUG_TRACES are activated") + add_definitions(-DDEBUG_TRACES) +endif() diff --git a/src/common/example/CMakeLists.txt b/src/common/example/CMakeLists.txt index 1273c699..04015cdc 100644 --- a/src/common/example/CMakeLists.txt +++ b/src/common/example/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Common_examples) add_executable ( vector_double_off_reader example_vector_double_points_off_reader.cpp ) diff --git a/src/common/test/CMakeLists.txt b/src/common/test/CMakeLists.txt index de3e765a..0b49fa1e 100644 --- a/src/common/test/CMakeLists.txt +++ b/src/common/test/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(Common_tests) include(GUDHI_test_coverage) diff --git a/src/common/utilities/CMakeLists.txt b/src/common/utilities/CMakeLists.txt index b3e4b436..7f1d1cd7 100644 --- a/src/common/utilities/CMakeLists.txt +++ b/src/common/utilities/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) project(off_file_from_shape_generator) if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index b19cc550..2c21d158 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.8) project(Cython) include(CheckCXXSourceCompiles) @@ -100,12 +99,13 @@ if(CYTHON_FOUND) add_gudhi_cython_lib(${Boost_THREAD_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") endif() - + message("*** ${CGAL_HEADER_ONLY}") # Add CGAL compilation args if(CGAL_HEADER_ONLY) set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") else(CGAL_HEADER_ONLY) - add_gudhi_cython_lib(${CGAL_LIBRARIES}) + message("*** ${CGAL_LIBRARY}") + add_gudhi_cython_lib(${CGAL_LIBRARY}) set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") # If CGAL is not header only, CGAL library may link with boost system, add_gudhi_cython_lib(${Boost_SYSTEM_LIBRARY}) -- cgit v1.2.3 From bbf184b036c0b740b3fb0a95f5ce53dfa6151b52 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 13 Aug 2018 14:18:44 +0000 Subject: Modify GUDHIConfig.cmake in order to have : Order is : 1. user defined GUDHI_INCLUDE_DIRS 2. ${CMAKE_SOURCE_DIR}/include => Where the 'cmake' has been done 3. ${CMAKE_INSTALL_PREFIX}/include => Where the 'make install' has been performed git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@3775 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 506357257ce261cb2778e357ca902401da4838e7 --- src/CMakeLists.txt | 2 +- src/GUDHIConfig.cmake.in | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c60346d5..6c446104 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,7 +71,7 @@ export(PACKAGE GUDHI) message("++ make install will install ${PROJECT_NAME} in the following directory : ${CMAKE_INSTALL_PREFIX}") # Create the GUDHIConfig.cmake and GUDHIConfigVersion files -set(CONF_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include") +set(CONF_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/include;${CMAKE_INSTALL_PREFIX}/include") configure_file(GUDHIConfig.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfig.cmake" @ONLY) configure_file(GUDHIConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/GUDHIConfigVersion.cmake" @ONLY) diff --git a/src/GUDHIConfig.cmake.in b/src/GUDHIConfig.cmake.in index 02b540dc..8d82f235 100644 --- a/src/GUDHIConfig.cmake.in +++ b/src/GUDHIConfig.cmake.in @@ -1,7 +1,12 @@ # - Config file for the GUDHI package # It defines the following variables # GUDHI_INCLUDE_DIRS - include directories for GUDHI +# +# Order is : +# 1. user defined GUDHI_INCLUDE_DIRS +# 2. ${CMAKE_SOURCE_DIR}/include => Where the 'cmake' has been done +# 3. ${CMAKE_INSTALL_PREFIX}/include => Where the 'make install' has been performed # Compute paths -set(GUDHI_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") +set(GUDHI_INCLUDE_DIRS "${GUDHI_INCLUDE_DIRS};@CONF_INCLUDE_DIRS@") -- cgit v1.2.3 From d95c0d8f3d28067527116a2c1eac06f5bf083995 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 28 Sep 2018 09:00:25 +0000 Subject: https://gitlab.inria.fr/GUDHI/gudhi-devel/issues/32 - [Cmake - Qt5] CMake outputs an error when Qt5 is not installed Modify/add cmake messages for missing modules git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/cmake_missing_modules_clarification_vincent@3912 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 37e1035f7c27ce994e05386801d72959696de7d4 --- CMakeLists.txt | 12 +- src/CMakeLists.txt | 12 +- src/GudhUI/CMakeLists.txt | 81 ++- src/cmake/modules/GUDHI_doxygen_target.cmake | 8 +- src/cmake/modules/GUDHI_modules.cmake | 5 +- .../modules/GUDHI_third_party_libraries.cmake | 4 +- src/cython/CMakeLists.txt | 681 +++++++++++---------- 7 files changed, 434 insertions(+), 369 deletions(-) (limited to 'src/CMakeLists.txt') diff --git a/CMakeLists.txt b/CMakeLists.txt index afacede9..d61df992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,10 @@ include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/cmake/modules/") +# Reset cache +set(GUDHI_MODULES "" CACHE INTERNAL "GUDHI_MODULES") +set(GUDHI_MISSING_MODULES "" CACHE INTERNAL "GUDHI_MISSING_MODULES") + # This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path set(GUDHI_CYTHON_PATH "src/cython") @@ -37,8 +41,6 @@ add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) -message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") - # Include module CMake subdirectories # GUDHI_SUB_DIRECTORIES is managed in CMAKE_MODULE_PATH/GUDHI_modules.cmake foreach(GUDHI_MODULE ${GUDHI_MODULES}) @@ -54,9 +56,15 @@ add_subdirectory(src/GudhUI) if (WITH_GUDHI_PYTHON) # specific for cython module add_subdirectory(${GUDHI_CYTHON_PATH}) +else() + message("++ Python module will not be compiled because WITH_GUDHI_PYTHON is set to OFF") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python") endif() # For "make user_version" - Requires GUDHI_modules to be performed include(GUDHI_user_version_target) # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set - Done in GUDHI_user_version_target for dev version include(GUDHI_doxygen_target) + +message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") +message("++ GUDHI_MISSING_MODULES list is:\"${GUDHI_MISSING_MODULES}\"") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c446104..b40d506a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,9 @@ include(CMakeGUDHIVersion.txt) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") +set(GUDHI_MODULES "" CACHE INTERNAL "GUDHI_MODULES") +set(GUDHI_MISSING_MODULES "" CACHE INTERNAL "GUDHI_MISSING_MODULES") + # This variable is used by Cython CMakeLists.txt and by GUDHI_third_party_libraries to know its path set(GUDHI_CYTHON_PATH "cython") @@ -35,8 +38,6 @@ add_gudhi_module(Tangential_complex) add_gudhi_module(Witness_complex) add_gudhi_module(Nerve_GIC) -message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") - # For "make doxygen" - Requires GUDHI_USER_VERSION_DIR to be set set(GUDHI_USER_VERSION_DIR ${CMAKE_SOURCE_DIR}) include(GUDHI_doxygen_target) @@ -60,7 +61,14 @@ add_subdirectory(GudhUI) if (WITH_GUDHI_PYTHON) # specific for cython module add_subdirectory(${GUDHI_CYTHON_PATH}) +else() + message("++ Python module will not be compiled because WITH_GUDHI_PYTHON is set to OFF") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python") endif() + +message("++ GUDHI_MODULES list is:\"${GUDHI_MODULES}\"") +message("++ GUDHI_MISSING_MODULES list is:\"${GUDHI_MISSING_MODULES}\"") + #--------------------------------------------------------------------------------------- #--------------------------------------------------------------------------------------- diff --git a/src/GudhUI/CMakeLists.txt b/src/GudhUI/CMakeLists.txt index b357b8f7..0945e758 100644 --- a/src/GudhUI/CMakeLists.txt +++ b/src/GudhUI/CMakeLists.txt @@ -1,40 +1,55 @@ project(GudhUI) # Need to find OpenGL first as find_package(Qt5) tries to #include"GL/gl.h" on some platforms -find_package(OpenGL) +find_package(OpenGL QUIET) if (OPENGL_FOUND) - find_package(Qt5 COMPONENTS Widgets Xml OpenGL) - find_package(QGLViewer) - - if ( CGAL_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0) - - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTOUIC ON) - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - SET(Boost_USE_STATIC_LIBS ON) - SET(Boost_USE_MULTITHREAD OFF) - include_directories (${QGLVIEWER_INCLUDE_DIR}) - - add_executable ( GudhUI - gui/gudhui.cpp - gui/MainWindow.cpp - gui/Menu_k_nearest_neighbors.cpp - gui/Menu_uniform_neighbors.cpp - gui/Menu_edge_contraction.cpp - gui/Menu_persistence.cpp - view/Viewer_instructor.cpp - view/Viewer.cpp - ) - target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL ) - target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} ) - target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) - if (TBB_FOUND) - target_link_libraries( GudhUI ${TBB_LIBRARIES}) + find_package(Qt5 COMPONENTS Widgets Xml OpenGL QUIET) + if (Qt5_FOUND) + find_package(QGLViewer QUIET) + if ( QGLVIEWER_FOUND) + + if ( CGAL_FOUND AND NOT CGAL_VERSION VERSION_EQUAL 4.8.0) + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTOUIC ON) + set(CMAKE_INCLUDE_CURRENT_DIR ON) + + SET(Boost_USE_STATIC_LIBS ON) + SET(Boost_USE_MULTITHREAD OFF) + include_directories (${QGLVIEWER_INCLUDE_DIR}) + + add_executable ( GudhUI + gui/gudhui.cpp + gui/MainWindow.cpp + gui/Menu_k_nearest_neighbors.cpp + gui/Menu_uniform_neighbors.cpp + gui/Menu_edge_contraction.cpp + gui/Menu_persistence.cpp + view/Viewer_instructor.cpp + view/Viewer.cpp + ) + target_link_libraries( GudhUI Qt5::Widgets Qt5::Xml Qt5::OpenGL ) + target_link_libraries( GudhUI ${QGLVIEWER_LIBRARIES} ) + target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) + if (TBB_FOUND) + target_link_libraries( GudhUI ${TBB_LIBRARIES}) + endif() + + install(TARGETS GudhUI DESTINATION bin) + set(GUDHI_MODULES ${GUDHI_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MODULES") + else() + message("++ GudhUI will not be compiled because CGAL < 4.8.0 or not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif() + else() + message("++ GudhUI will not be compiled because QGLViewer is not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() - - install(TARGETS GudhUI DESTINATION bin) - + else() + message("++ GudhUI will not be compiled because Qt5 COMPONENTS Widgets Xml OpenGL are not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() -endif(OPENGL_FOUND) +else() + message("++ GudhUI will not be compiled because OpenGL is not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "GudhUI" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif() diff --git a/src/cmake/modules/GUDHI_doxygen_target.cmake b/src/cmake/modules/GUDHI_doxygen_target.cmake index 9e10e566..7a84c4e0 100644 --- a/src/cmake/modules/GUDHI_doxygen_target.cmake +++ b/src/cmake/modules/GUDHI_doxygen_target.cmake @@ -1,7 +1,7 @@ # add a target to generate API documentation with Doxygen -find_package(Doxygen) +find_package(Doxygen QUIET) if(DOXYGEN_FOUND) - # configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) + set(GUDHI_MODULES ${GUDHI_MODULES} "cpp-documentation" CACHE INTERNAL "GUDHI_MODULES") # starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated if(TARGET Doxygen::doxygen) @@ -16,4 +16,6 @@ if(DOXYGEN_FOUND) # In dev version, doxygen target depends on user_version target. Not existing in user version add_dependencies(doxygen user_version) endif() -endif(DOXYGEN_FOUND) +else() + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "cpp-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif() diff --git a/src/cmake/modules/GUDHI_modules.cmake b/src/cmake/modules/GUDHI_modules.cmake index f95d0c34..aab1dd08 100644 --- a/src/cmake/modules/GUDHI_modules.cmake +++ b/src/cmake/modules/GUDHI_modules.cmake @@ -1,11 +1,12 @@ # A function to add a new module in GUDHI -set(GUDHI_MODULES "") set(GUDHI_MODULES_FULL_LIST "") function(add_gudhi_module file_path) option("WITH_MODULE_GUDHI_${file_path}" "Activate/desactivate ${file_path} compilation and installation" ON) if (WITH_MODULE_GUDHI_${file_path}) - set(GUDHI_MODULES ${GUDHI_MODULES} ${file_path} PARENT_SCOPE) + set(GUDHI_MODULES ${GUDHI_MODULES} ${file_path} CACHE INTERNAL "GUDHI_MODULES") + else() + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} ${file_path} CACHE INTERNAL "GUDHI_MISSING_MODULES") endif() # Required by user_version set(GUDHI_MODULES_FULL_LIST ${GUDHI_MODULES_FULL_LIST} ${file_path} PARENT_SCOPE) diff --git a/src/cmake/modules/GUDHI_third_party_libraries.cmake b/src/cmake/modules/GUDHI_third_party_libraries.cmake index f03c2177..122754d5 100644 --- a/src/cmake/modules/GUDHI_third_party_libraries.cmake +++ b/src/cmake/modules/GUDHI_third_party_libraries.cmake @@ -21,11 +21,11 @@ endif() # A fix would be to use https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html # or even better https://cmake.org/cmake/help/v3.1/variable/CMAKE_CXX_STANDARD.html # but it implies to use cmake version 3.1 at least. -find_package(CGAL) +find_package(CGAL QUIET) # Only CGAL versions > 4.4 supports what Gudhi uses from CGAL if (CGAL_VERSION VERSION_LESS 4.4.0) - message("CGAL version ${CGAL_VERSION} is considered too old to be used by Gudhi.") + message("++ CGAL version ${CGAL_VERSION} is considered too old to be used by Gudhi.") unset(CGAL_FOUND) endif() if(CGAL_FOUND) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt index 09ea28f1..8fcd6cbf 100644 --- a/src/cython/CMakeLists.txt +++ b/src/cython/CMakeLists.txt @@ -31,375 +31,406 @@ function( add_gudhi_debug_info DEBUG_INFO ) set(GUDHI_CYTHON_DEBUG_INFO "${GUDHI_CYTHON_DEBUG_INFO} \"${DEBUG_INFO}\\n\" \\\n" PARENT_SCOPE) endfunction( add_gudhi_debug_info ) - -if(CYTHON_FOUND) - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}off_reader;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}simplex_tree;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}rips_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}cubical_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}periodic_cubical_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}reader_utils;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}witness_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}strong_witness_complex;") - - add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") - add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") - if(PYTEST_FOUND) - add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}") - endif() - if(MATPLOTLIB_FOUND) - add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}") - endif() - if(NUMPY_FOUND) - add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}") - endif() - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) +if(PYTHONINTERP_FOUND) + if(CYTHON_FOUND) + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}off_reader;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}simplex_tree;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}rips_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}cubical_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}periodic_cubical_complex;") set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") - endif() + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}reader_utils;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}witness_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}strong_witness_complex;") + + add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") + add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") + if(PYTEST_FOUND) + add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}") + endif() + if(MATPLOTLIB_FOUND) + add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}") + endif() + if(NUMPY_FOUND) + add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}") + endif() + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MODULES}persistence_graphical_tools;") + endif() - message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ") - - # Gudhi and CGAL compilation option - if(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") - else(MSVC) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") - endif(MSVC) - if(CMAKE_COMPILER_IS_GNUCXX) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") - endif(CMAKE_COMPILER_IS_GNUCXX) - if (CMAKE_CXX_COMPILER_ID MATCHES Intel) - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") - endif(CMAKE_CXX_COMPILER_ID MATCHES Intel) - if (DEBUG_TRACES) - # For programs to be more verbose - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") - endif() + message("++ ${PYTHON_EXECUTABLE} v.${PYTHON_VERSION_STRING} - Cython is ${CYTHON_VERSION} - Sphinx is ${SPHINX_PATH}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ") + + # Gudhi and CGAL compilation option + if(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'/fp:strict', ") + else(MSVC) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") + endif(MSVC) + if(CMAKE_COMPILER_IS_GNUCXX) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-frounding-math', ") + endif(CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_ID MATCHES Intel) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-fp-model strict', ") + endif(CMAKE_CXX_COMPILER_ID MATCHES Intel) + if (DEBUG_TRACES) + # For programs to be more verbose + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DDEBUG_TRACES', ") + endif() - if (EIGEN3_FOUND) - add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}") - # No problem, even if no CGAL found - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") - endif (EIGEN3_FOUND) - - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}bottleneck_distance;") - set(GUDHI_CYTHON_NERVE_GIC "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/nerve_gic.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}nerve_gic;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}bottleneck_distance;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}nerve_gic;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}subsampling;") - set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}tangential_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}subsampling;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}tangential_complex;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}alpha_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}alpha_complex;") - endif () - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX - "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_witness_complex;") - set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_strong_witness_complex;") - else() - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_witness_complex;") - set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_strong_witness_complex;") - endif () - - add_gudhi_debug_info("Installed modules are: ${GUDHI_CYTHON_MODULES}") - if(GUDHI_CYTHON_MISSING_MODULES) - add_gudhi_debug_info("Missing modules are: ${GUDHI_CYTHON_MISSING_MODULES}") - endif() + if (EIGEN3_FOUND) + add_gudhi_debug_info("Eigen3 version ${EIGEN3_VERSION}") + # No problem, even if no CGAL found + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") + endif (EIGEN3_FOUND) + + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + set(GUDHI_CYTHON_BOTTLENECK_DISTANCE "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/bottleneck_distance.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}bottleneck_distance;") + set(GUDHI_CYTHON_NERVE_GIC "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/nerve_gic.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}nerve_gic;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}bottleneck_distance;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}nerve_gic;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set(GUDHI_CYTHON_SUBSAMPLING "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/subsampling.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}subsampling;") + set(GUDHI_CYTHON_TANGENTIAL_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/tangential_complex.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}tangential_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}subsampling;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}tangential_complex;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + set(GUDHI_CYTHON_ALPHA_COMPLEX "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/alpha_complex.pyx'") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}alpha_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}alpha_complex;") + endif () + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + set(GUDHI_CYTHON_EUCLIDEAN_WITNESS_COMPLEX + "include '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_witness_complex.pyx'\ninclude '${CMAKE_CURRENT_SOURCE_DIR}/cython/euclidean_strong_witness_complex.pyx'\n") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_witness_complex;") + set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}euclidean_strong_witness_complex;") + else() + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_witness_complex;") + set(GUDHI_CYTHON_MISSING_MODULES "${GUDHI_CYTHON_MISSING_MODULES}euclidean_strong_witness_complex;") + endif () - if(CGAL_FOUND) - can_cgal_use_cxx11_thread_local() - if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") - else() - add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") - endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + add_gudhi_debug_info("Installed modules are: ${GUDHI_CYTHON_MODULES}") + if(GUDHI_CYTHON_MISSING_MODULES) + add_gudhi_debug_info("Missing modules are: ${GUDHI_CYTHON_MISSING_MODULES}") endif() - # Add CGAL compilation args - if(CGAL_HEADER_ONLY) - add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") - else(CGAL_HEADER_ONLY) - add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") - add_gudhi_cython_lib("${CGAL_LIBRARY}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") - # If CGAL is not header only, CGAL library may link with boost system, + + if(CGAL_FOUND) + can_cgal_use_cxx11_thread_local() + if (NOT CGAL_CAN_USE_CXX11_THREAD_LOCAL_RESULT) + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_THREAD_LIBRARY_RELEASE}") + endif() + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + endif() + # Add CGAL compilation args + if(CGAL_HEADER_ONLY) + add_gudhi_debug_info("CGAL header only version ${CGAL_VERSION}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_HEADER_ONLY', ") + else(CGAL_HEADER_ONLY) + add_gudhi_debug_info("CGAL version ${CGAL_VERSION}") + add_gudhi_cython_lib("${CGAL_LIBRARY}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") + # If CGAL is not header only, CGAL library may link with boost system, + if(CMAKE_BUILD_TYPE MATCHES Debug) + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + else() + add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + endif() + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") + endif(CGAL_HEADER_ONLY) + # GMP and GMPXX are not required, but if present, CGAL will link with them. + if(GMP_FOUND) + add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + add_gudhi_cython_lib("${GMP_LIBRARIES}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") + if(GMPXX_FOUND) + add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") + add_gudhi_cython_lib("${GMPXX_LIBRARIES}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") + endif(GMPXX_FOUND) + endif(GMP_FOUND) + endif(CGAL_FOUND) + + # Specific for Mac + if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.12', ") + set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.12', ") + endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + + # Loop on INCLUDE_DIRECTORIES PROPERTY + get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") + endforeach() + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") + + if (TBB_FOUND AND WITH_GUDHI_USE_TBB) + add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_DEBUG}") + add_gudhi_cython_lib("${TBB_DEBUG_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_DEBUG_LIBRARY}") else() - add_gudhi_cython_lib("${Boost_SYSTEM_LIBRARY_RELEASE}") + add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") + add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${Boost_LIBRARY_DIRS}', ") - endif(CGAL_HEADER_ONLY) - # GMP and GMPXX are not required, but if present, CGAL will link with them. - if(GMP_FOUND) - add_gudhi_debug_info("GMP_LIBRARIES = ${GMP_LIBRARIES}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") - add_gudhi_cython_lib("${GMP_LIBRARIES}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") - if(GMPXX_FOUND) - add_gudhi_debug_info("GMPXX_LIBRARIES = ${GMPXX_LIBRARIES}") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") - add_gudhi_cython_lib("${GMPXX_LIBRARIES}") - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") - endif(GMPXX_FOUND) - endif(GMP_FOUND) - endif(CGAL_FOUND) - - # Specific for Mac - if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-mmacosx-version-min=10.12', ") - set(GUDHI_CYTHON_EXTRA_LINK_ARGS "${GUDHI_CYTHON_EXTRA_LINK_ARGS}'-mmacosx-version-min=10.12', ") - endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - # Loop on INCLUDE_DIRECTORIES PROPERTY - get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) - foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") - endforeach() - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/include', ") - - if (TBB_FOUND AND WITH_GUDHI_USE_TBB) - add_gudhi_debug_info("TBB version ${TBB_INTERFACE_VERSION} found and used") - set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DGUDHI_USE_TBB', ") - if(CMAKE_BUILD_TYPE MATCHES Debug) - add_gudhi_cython_lib("${TBB_DEBUG_LIBRARY}") - add_gudhi_cython_lib("${TBB_MALLOC_DEBUG_LIBRARY}") - else() - add_gudhi_cython_lib("${TBB_RELEASE_LIBRARY}") - add_gudhi_cython_lib("${TBB_MALLOC_RELEASE_LIBRARY}") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") endif() - set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${TBB_LIBRARY_DIRS}', ") - set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${TBB_INCLUDE_DIRS}', ") - endif() - if(UNIX) - set( GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}") - endif(UNIX) - - # Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention - configure_file(setup.py.in "${CMAKE_CURRENT_BINARY_DIR}/setup.py" @ONLY) - # Generate gudhi.pyx - Gudhi cython file - configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) - - add_custom_command( - OUTPUT gudhi.so - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/setup.py" "build_ext" "--inplace") - - add_custom_target(cython ALL DEPENDS gudhi.so - COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") - - # For installation purpose - # TODO(VR) : files matching pattern mechanism is copying all cython directory - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DESTINATION "${PYTHON_SITE_PACKAGES}/" FILES_MATCHING - PATTERN "*.so" - PATTERN "*.dylib" - PATTERN "*.pyd") - - # Test examples - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - # Bottleneck and Alpha - add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" - -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + if(UNIX) + set( GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}") + endif(UNIX) + + # Generate setup.py file to cythonize Gudhi - This file must be named setup.py by convention + configure_file(setup.py.in "${CMAKE_CURRENT_BINARY_DIR}/setup.py" @ONLY) + # Generate gudhi.pyx - Gudhi cython file + configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + + add_custom_command( + OUTPUT gudhi.so + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_BINARY_DIR}/setup.py" "build_ext" "--inplace") + + add_custom_target(cython ALL DEPENDS gudhi.so + COMMENT "Do not forget to add ${CMAKE_CURRENT_BINARY_DIR}/ to your PYTHONPATH before using examples or tests") + + # For installation purpose + # TODO(VR) : files matching pattern mechanism is copying all cython directory + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DESTINATION "${PYTHON_SITE_PACKAGES}/" FILES_MATCHING + PATTERN "*.so" + PATTERN "*.dylib" + PATTERN "*.pyd") + + # Test examples + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + # Bottleneck and Alpha + add_test(NAME alpha_rips_persistence_bottleneck_distance_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_rips_persistence_bottleneck_distance.py" + -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -t 0.15 -d 3) + + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + # Tangential + add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" + --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + + add_gudhi_py_test(test_tangential_complex) + + # Witness complex AND Subsampling + add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + + add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + endif() - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - # Tangential - add_test(NAME tangential_complex_plain_homology_from_off_file_example_py_test + # Subsampling + add_gudhi_py_test(test_subsampling) + + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_VERSION VERSION_LESS 4.8.1) + # Bottleneck + add_test(NAME bottleneck_basic_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/tangential_complex_plain_homology_from_off_file_example.py" - --no-diagram -i 2 -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/bottleneck_basic_example.py") - add_gudhi_py_test(test_tangential_complex) + add_gudhi_py_test(test_bottleneck_distance) - # Witness complex AND Subsampling - add_test(NAME euclidean_strong_witness_complex_diagram_persistence_from_off_file_example_py_test + # Cover complex + file(COPY ${CMAKE_SOURCE_DIR}/data/points/human.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) + add_test(NAME cover_complex_nerve_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/nerve_of_a_covering.py" + -f human.off -c 2 -r 10 -g 0.3) - add_test(NAME euclidean_witness_complex_diagram_persistence_from_off_file_example_py_test + add_test(NAME cover_complex_coordinate_gic_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 1.0 -n 20 -d 2) - endif() + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/coordinate_graph_induced_complex.py" + -f human.off -c 0 -v) - # Subsampling - add_gudhi_py_test(test_subsampling) + add_test(NAME cover_complex_functional_gic_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/functional_graph_induced_complex.py" + -o lucky_cat.off + -f lucky_cat_PCA1 -v) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - if (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Bottleneck - add_test(NAME bottleneck_basic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/bottleneck_basic_example.py") + add_test(NAME cover_complex_voronoi_gic_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/voronoi_graph_induced_complex.py" + -f human.off -n 700 -v) - add_gudhi_py_test(test_bottleneck_distance) + add_gudhi_py_test(test_cover_complex) + endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) - # Cover complex - file(COPY ${CMAKE_SOURCE_DIR}/data/points/human.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat.off DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - file(COPY ${CMAKE_SOURCE_DIR}/data/points/COIL_database/lucky_cat_PCA1 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) - add_test(NAME cover_complex_nerve_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/nerve_of_a_covering.py" - -f human.off -c 2 -r 10 -g 0.3) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + # Alpha + add_test(NAME alpha_complex_from_points_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") - add_test(NAME cover_complex_coordinate_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/coordinate_graph_induced_complex.py" - -f human.off -c 0 -v) + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) + endif() - add_test(NAME cover_complex_functional_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/functional_graph_induced_complex.py" - -o lucky_cat.off - -f lucky_cat_PCA1 -v) + add_gudhi_py_test(test_alpha_complex) - add_test(NAME cover_complex_voronoi_gic_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/voronoi_graph_induced_complex.py" - -f human.off -n 700 -v) + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - add_gudhi_py_test(test_cover_complex) - endif (NOT CGAL_VERSION VERSION_LESS 4.8.1) + if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + # Euclidean witness + add_gudhi_py_test(test_euclidean_witness_complex) - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) - # Alpha - add_test(NAME alpha_complex_from_points_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_from_points_example.py") + endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME alpha_complex_diagram_persistence_from_off_file_example_py_test + # Cubical + add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/alpha_complex_diagram_persistence_from_off_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -a 0.6) - endif() - - add_gudhi_py_test(test_alpha_complex) + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" + --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.7.0) + if(NUMPY_FOUND) + add_test(NAME random_cubical_complex_persistence_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py" + 10 10 10) + endif() - if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) - # Euclidean witness - add_gudhi_py_test(test_euclidean_witness_complex) + add_gudhi_py_test(test_cubical_complex) - endif (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.6.0) + # Rips + if(MATPLOTLIB_FOUND AND NUMPY_FOUND) + add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) - # Cubical - add_test(NAME periodic_cubical_complex_barcode_persistence_from_perseus_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py" - --no-barcode -f ${CMAKE_SOURCE_DIR}/data/bitmap/CubicalTwoSphere.txt) + add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py + --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) + endif() - if(NUMPY_FOUND) - add_test(NAME random_cubical_complex_persistence_example_py_test + add_test(NAME rips_complex_from_points_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/random_cubical_complex_persistence_example.py" - 10 10 10) - endif() + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_from_points_example.py) - add_gudhi_py_test(test_cubical_complex) + add_gudhi_py_test(test_rips_complex) - # Rips - if(MATPLOTLIB_FOUND AND NUMPY_FOUND) - add_test(NAME rips_complex_diagram_persistence_from_distance_matrix_file_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py" - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3) - - add_test(NAME rips_complex_diagram_persistence_from_off_file_example_py_test + # Simplex tree + add_test(NAME simplex_tree_example_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_diagram_persistence_from_off_file_example.py - --no-diagram -f ${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off -e 0.25 -d 3) - endif() - - add_test(NAME rips_complex_from_points_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/rips_complex_from_points_example.py) - - add_gudhi_py_test(test_rips_complex) - - # Simplex tree - add_test(NAME simplex_tree_example_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/simplex_tree_example.py) - - add_gudhi_py_test(test_simplex_tree) + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/simplex_tree_example.py) - # Witness - add_test(NAME witness_complex_from_nearest_landmark_table_py_test - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/witness_complex_from_nearest_landmark_table.py) + add_gudhi_py_test(test_simplex_tree) - add_gudhi_py_test(test_witness_complex) - - # Reader utils - add_gudhi_py_test(test_reader_utils) - - # Documentation generation is available through sphinx - requires all modules - if(SPHINX_PATH AND MATPLOTLIB_FOUND AND NUMPY_FOUND AND NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) - set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") - # User warning - Sphinx is a static pages generator, and configured to work fine with user_version - # Images and biblio warnings because not found on developper version - if (GUDHI_CYTHON_PATH STREQUAL "src/cython") - set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") - endif() - # sphinx target requires gudhi.so, because conf.py reads gudhi version from it - add_custom_target(sphinx - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" - COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) - - add_test(NAME sphinx_py_test + # Witness + add_test(NAME witness_complex_from_nearest_landmark_table_py_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" - ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) - - endif() -endif(CYTHON_FOUND) + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/witness_complex_from_nearest_landmark_table.py) + + add_gudhi_py_test(test_witness_complex) + + # Reader utils + add_gudhi_py_test(test_reader_utils) + + # Documentation generation is available through sphinx - requires all modules + if(SPHINX_PATH) + if(MATPLOTLIB_FOUND) + if(NUMPY_FOUND) + if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/") + # User warning - Sphinx is a static pages generator, and configured to work fine with user_version + # Images and biblio warnings because not found on developper version + if (GUDHI_CYTHON_PATH STREQUAL "src/cython") + set (GUDHI_SPHINX_MESSAGE "${GUDHI_SPHINX_MESSAGE} \n WARNING : Sphinx is configured for user version, you run it on developper version. Images and biblio will miss") + endif() + # sphinx target requires gudhi.so, because conf.py reads gudhi version from it + add_custom_target(sphinx + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b html ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/sphinx + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + COMMENT "${GUDHI_SPHINX_MESSAGE}" VERBATIM) + + add_test(NAME sphinx_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_PATH} -b doctest ${CMAKE_CURRENT_SOURCE_DIR}/doc ${CMAKE_CURRENT_BINARY_DIR}/doctest) + + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MODULES") + else(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + message("++ Python documentation module will not be compiled because it requires a CGAL with Eigen3 version greater or equal than 4.8.1") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.8.1) + else(NUMPY_FOUND) + message("++ Python module will not be compiled because numpy was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(NUMPY_FOUND) + else(MATPLOTLIB_FOUND) + message("++ Python module will not be compiled because matplotlib was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(MATPLOTLIB_FOUND) + else(SPHINX_PATH) + message("++ Python module will not be compiled because sphinx and sphinxcontrib-bibtex were not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(SPHINX_PATH) + + + # Set missing or not modules + set(GUDHI_MODULES ${GUDHI_MODULES} "python" CACHE INTERNAL "GUDHI_MODULES") + else(CYTHON_FOUND) + message("++ Python module will not be compiled because cython was not found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") + endif(CYTHON_FOUND) +else(PYTHONINTERP_FOUND) + message("++ Python module will not be compiled because no Python interpreter was found") + set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python" CACHE INTERNAL "GUDHI_MISSING_MODULES") +endif(PYTHONINTERP_FOUND) -- cgit v1.2.3