12#ifndef PERSISTENCE_LANDSCAPE_H_
13#define PERSISTENCE_LANDSCAPE_H_
32#include <gudhi/read_persistence_from_file.h>
34#include <gudhi/Debug_utils.h>
37namespace Persistence_representations {
41template <
typename Operation>
77 std::size_t number_of_levels = std::numeric_limits<std::size_t>::max())
79 this->_construct_persistence_landscape_from_barcode(p, number_of_levels);
80 this->_set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
89 unsigned int dimension = std::numeric_limits<unsigned int>::max(),
90 std::size_t number_of_levels = std::numeric_limits<std::size_t>::max())
92 std::vector<std::pair<double, double> > barcode;
93 if (dimension < std::numeric_limits<unsigned int>::max()) {
98 this->_construct_persistence_landscape_from_barcode(barcode, number_of_levels);
99 this->_set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
143 for (std::size_t level = 0; level != land.land_.size(); ++level) {
144 out <<
"Lambda_" << level <<
":" << std::endl;
145 for (std::size_t i = 0; i != land.land_[level].size(); ++i) {
146 if (land.land_[level][i].first == -std::numeric_limits<int>::max()) {
149 if (land.land_[level][i].first == std::numeric_limits<int>::max()) {
152 out << land.land_[level][i].first;
155 out <<
" , " << land.land_[level][i].second << std::endl;
161 template <
typename Operation>
166 std::clog <<
"operation_on_pair_of_landscapes\n";
169 std::vector<std::vector<std::pair<double, double> > > land(std::max(land1.land_.size(), land2.land_.size()));
174 for (std::size_t i = 0; i != std::min(land1.land_.size(), land2.land_.size()); ++i) {
175 std::clog <<
"land1.land[" << i <<
"].size() : " << land1.land_[i].size() << std::endl;
176 std::clog <<
"land2.land[" << i <<
"].size() : " << land2.land_[i].size() << std::endl;
180 for (std::size_t i = 0; i != std::min(land1.land_.size(), land2.land_.size()); ++i) {
181 std::vector<std::pair<double, double> > lambda_n;
184 while ((p + 1 < land1.land_[i].size()) && (q + 1 < land2.land_[i].size())) {
186 std::clog <<
"p : " << p <<
"\n";
187 std::clog <<
"q : " << q <<
"\n";
188 std::clog <<
"land1.land.size() : " << land1.land_.size() << std::endl;
189 std::clog <<
"land2.land.size() : " << land2.land_.size() << std::endl;
190 std::clog <<
"land1.land[" << i <<
"].size() : " << land1.land_[i].size() << std::endl;
191 std::clog <<
"land2.land[" << i <<
"].size() : " << land2.land_[i].size() << std::endl;
192 std::clog <<
"land1.land[i][p].first : " << land1.land_[i][p].first <<
"\n";
193 std::clog <<
"land2.land[i][q].first : " << land2.land_[i][q].first <<
"\n";
196 if (land1.land_[i][p].first < land2.land_[i][q].first) {
198 std::clog <<
"first \n";
199 std::clog <<
" function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) : "
200 <<
function_value(land2.land_[i][q - 1], land2.land_[i][q], land1.land_[i][p].first) <<
"\n";
203 std::make_pair(land1.land_[i][p].first,
204 oper(
static_cast<double>(land1.land_[i][p].second),
205 function_value(land2.land_[i][q - 1], land2.land_[i][q], land1.land_[i][p].first))));
209 if (land1.land_[i][p].first > land2.land_[i][q].first) {
211 std::clog <<
"Second \n";
212 std::clog <<
"function_value(" << land1.land_[i][p - 1].first <<
" " << land1.land_[i][p - 1].second <<
" ,"
213 << land1.land_[i][p].first <<
" " << land1.land_[i][p].second <<
", " << land2.land_[i][q].first
214 <<
" ) : " <<
function_value(land1.land_[i][p - 1], land1.land_[i][p - 1], land2.land_[i][q].first)
216 std::clog <<
"oper( " <<
function_value(land1.land_[i][p], land1.land_[i][p - 1], land2.land_[i][q].first)
217 <<
"," << land2.land_[i][q].second <<
" : "
218 << oper(land2.land_[i][q].second,
219 function_value(land1.land_[i][p], land1.land_[i][p - 1], land2.land_[i][q].first))
223 std::make_pair(land2.land_[i][q].first,
224 oper(
function_value(land1.land_[i][p], land1.land_[i][p - 1], land2.land_[i][q].first),
225 land2.land_[i][q].second)));
229 if (land1.land_[i][p].first == land2.land_[i][q].first) {
231 std::clog <<
"Third \n";
234 std::make_pair(land2.land_[i][q].first, oper(land1.land_[i][p].second, land2.land_[i][q].second)));
239 std::clog <<
"Next iteration \n";
242 while ((p + 1 < land1.land_[i].size()) && (q + 1 >= land2.land_[i].size())) {
244 std::clog <<
"New point : " << land1.land_[i][p].first
245 <<
" oper(land1.land[i][p].second,0) : " << oper(land1.land_[i][p].second, 0) << std::endl;
247 lambda_n.push_back(std::make_pair(land1.land_[i][p].first, oper(land1.land_[i][p].second, 0)));
250 while ((p + 1 >= land1.land_[i].size()) && (q + 1 < land2.land_[i].size())) {
252 std::clog <<
"New point : " << land2.land_[i][q].first
253 <<
" oper(0,land2.land[i][q].second) : " << oper(0, land2.land_[i][q].second) << std::endl;
255 lambda_n.push_back(std::make_pair(land2.land_[i][q].first, oper(0, land2.land_[i][q].second)));
258 lambda_n.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
261 result.land_[i].swap(lambda_n);
263 if (land1.land_.size() > std::min(land1.land_.size(), land2.land_.size())) {
265 std::clog <<
"land1.land.size() > std::min( land1.land.size() , land2.land.size() )" << std::endl;
267 for (std::size_t i = std::min(land1.land_.size(), land2.land_.size());
268 i != std::max(land1.land_.size(), land2.land_.size());
270 std::vector<std::pair<double, double> > lambda_n(land1.land_[i]);
271 for (std::size_t nr = 0; nr != land1.land_[i].size(); ++nr) {
272 lambda_n[nr] = std::make_pair(land1.land_[i][nr].first, oper(land1.land_[i][nr].second, 0));
276 result.land_[i].swap(lambda_n);
279 if (land2.land_.size() > std::min(land1.land_.size(), land2.land_.size())) {
281 std::clog <<
"( land2.land.size() > std::min( land1.land.size() , land2.land.size() ) ) " << std::endl;
283 for (std::size_t i = std::min(land1.land_.size(), land2.land_.size());
284 i != std::max(land1.land_.size(), land2.land_.size());
286 std::vector<std::pair<double, double> > lambda_n(land2.land_[i]);
287 for (std::size_t nr = 0; nr != land2.land_[i].size(); ++nr) {
288 lambda_n[nr] = std::make_pair(land2.land_[i][nr].first, oper(0, land2.land_[i][nr].second));
292 result.land_[i].swap(lambda_n);
296 std::clog <<
"operation_on_pair_of_landscapes END\n";
311 return operation_on_pair_of_landscapes<std::plus<double> >(land1, land2);
320 return operation_on_pair_of_landscapes<std::minus<double> >(land1, land2);
344 return first._multiply_landscape_by_real_number_not_overwrite(con);
352 return first._multiply_landscape_by_real_number_not_overwrite(con);
388 if (x == 0)
throw std::invalid_argument(
"In operator /=, division by 0.");
389 *
this = *
this * (1 / x);
409 if (this->land_.size()) {
410 maxValue = -std::numeric_limits<int>::max();
411 for (std::size_t i = 0; i != this->land_[0].size(); ++i) {
412 if (this->land_[0][i].second > maxValue) maxValue = this->land_[0][i].second;
421 double compute_minimum()
const
424 if (this->land_.size()) {
425 minValue = std::numeric_limits<int>::max();
426 for (std::size_t i = 0; i != this->land_[0].size(); ++i) {
427 if (this->land_[0][i].second < minValue) minValue = this->land_[0][i].second;
436 double compute_norm_of_landscape(
double i)
439 if (i < std::numeric_limits<double>::max()) {
457 return std::max(compute_maximal_distance_non_symmetric(first, second),
458 compute_maximal_distance_non_symmetric(second, first));
478 std::clog <<
"Abs of difference ; " << lan << std::endl;
481 if (p < std::numeric_limits<double>::max()) {
486 std::clog <<
"Power != 1, compute integral to the power p\n";
491 std::clog <<
"Power = 1, compute integral \n";
496 return std::pow(result, 1.0 / p);
500 std::clog <<
"Power = infty, compute maximum \n";
520 std::size_t
size()
const {
return this->land_.size(); }
525 double find_max(
unsigned int lambda)
const;
534 for (std::size_t level = 0; level != std::min(l1.
size(), l2.
size()); ++level) {
536 std::clog <<
"Computing inner product for a level : " << level << std::endl;
538 auto&& l1_land_level = l1.land_[level];
539 auto&& l2_land_level = l2.land_[level];
541 if (l1_land_level.size() * l2_land_level.size() == 0)
continue;
544 double x1 = -std::numeric_limits<int>::max();
546 if (l1_land_level[1].first < l2_land_level[1].first) {
547 x2 = l1_land_level[1].first;
549 x2 = l2_land_level[1].first;
553 std::size_t l1It = 0;
554 std::size_t l2It = 0;
556 while ((l1It < l1_land_level.size() - 1) && (l2It < l2_land_level.size() - 1)) {
561 if (l1_land_level[l1It + 1].first != l1_land_level[l1It].first) {
562 a = (l1_land_level[l1It + 1].second - l1_land_level[l1It].second) /
563 (l1_land_level[l1It + 1].first - l1_land_level[l1It].first);
567 b = l1_land_level[l1It].second - a * l1_land_level[l1It].first;
568 if (l2_land_level[l2It + 1].first != l2_land_level[l2It].first) {
569 c = (l2_land_level[l2It + 1].second - l2_land_level[l2It].second) /
570 (l2_land_level[l2It + 1].first - l2_land_level[l2It].first);
574 d = l2_land_level[l2It].second - c * l2_land_level[l2It].first;
576 double contributionFromThisPart = (a * c * x2 * x2 * x2 / 3 + (a * d + b * c) * x2 * x2 / 2 + b * d * x2) -
577 (a * c * x1 * x1 * x1 / 3 + (a * d + b * c) * x1 * x1 / 2 + b * d * x1);
579 result += contributionFromThisPart;
582 std::clog <<
"[l1_land_level[l1It].first,l1_land_level[l1It+1].first] : " << l1_land_level[l1It].first <<
" , "
583 << l1_land_level[l1It + 1].first << std::endl;
584 std::clog <<
"[l2_land_level[l2It].first,l2_land_level[l2It+1].first] : " << l2_land_level[l2It].first <<
" , "
585 << l2_land_level[l2It + 1].first << std::endl;
586 std::clog <<
"a : " << a <<
", b : " << b <<
" , c: " << c <<
", d : " << d << std::endl;
587 std::clog <<
"x1 : " << x1 <<
" , x2 : " << x2 << std::endl;
588 std::clog <<
"contributionFromThisPart : " << contributionFromThisPart << std::endl;
589 std::clog <<
"result : " << result << std::endl;
598 if (x2 == l1_land_level[l1It + 1].first) {
599 if (x2 == l2_land_level[l2It + 1].first) {
603 std::clog <<
"Incrementing both \n";
607 std::clog <<
"Incrementing first \n";
615 std::clog <<
"Incrementing second \n";
619 if (l1It + 1 >= l1_land_level.size())
break;
620 if (l2It + 1 >= l2_land_level.size())
break;
624 if (l1_land_level[l1It + 1].first < l2_land_level[l2It + 1].first) {
625 x2 = l1_land_level[l1It + 1].first;
627 x2 = l2_land_level[l2It + 1].first;
658 std::vector<double>
vectorize(
int number_of_function)
const
661 std::vector<double> v;
662 if (
static_cast<std::size_t
>(number_of_function) > this->land_.size()) {
665 v.reserve(this->land_[number_of_function].
size());
666 for (std::size_t i = 0; i != this->land_[number_of_function].size(); ++i) {
667 v.push_back(this->land_[number_of_function][i].second);
685 std::clog <<
"to_average.size() : " << to_average.size() << std::endl;
688 std::vector<Persistence_landscape*> nextLevelMerge(to_average.size());
689 for (std::size_t i = 0; i != to_average.size(); ++i) {
690 nextLevelMerge[i] = to_average[i];
696 bool is_this_first_level =
true;
698 while (nextLevelMerge.size() != 1) {
700 std::clog <<
"nextLevelMerge.size() : " << nextLevelMerge.size() << std::endl;
702 std::vector<Persistence_landscape*> nextNextLevelMerge;
703 nextNextLevelMerge.reserve(to_average.size());
704 for (std::size_t i = 0; i < nextLevelMerge.size(); i = i + 2) {
706 std::clog <<
"i : " << i << std::endl;
709 if (i + 1 != nextLevelMerge.size()) {
710 (*l) = (*nextLevelMerge[i]) + (*nextLevelMerge[i + 1]);
712 (*l) = *nextLevelMerge[i];
714 nextNextLevelMerge.push_back(l);
717 std::clog <<
"After this iteration \n";
720 if (!is_this_first_level) {
722 for (std::size_t i = 0; i != nextLevelMerge.size(); ++i) {
723 delete nextLevelMerge[i];
726 is_this_first_level =
false;
727 nextLevelMerge.swap(nextNextLevelMerge);
729 (*this) = (*nextLevelMerge[0]);
730 if (!is_this_first_level)
delete nextLevelMerge[0];
731 (*this) *= 1 /
static_cast<double>(to_average.size());
742 if (power < std::numeric_limits<double>::max()) {
765 std::pair<double, double>
get_y_range(std::size_t level = 0)
const
767 std::pair<double, double> result;
768 if (level < this->land_.size()) {
770 double minn = this->compute_minimum();
771 result = std::make_pair(minn, maxx);
773 result = std::make_pair(0, 0);
779 void plot(
const char* filename,
780 double xRangeBegin = std::numeric_limits<double>::max(),
781 double xRangeEnd = std::numeric_limits<double>::max(),
782 double yRangeBegin = std::numeric_limits<double>::max(),
783 double yRangeEnd = std::numeric_limits<double>::max(),
784 int from = std::numeric_limits<int>::max(),
785 int to = std::numeric_limits<int>::max());
792 std::clog <<
" compute_maximal_distance_non_symmetric \n";
796 std::size_t minimalNumberOfLevels = std::min(pl1.land_.size(), pl2.land_.size());
797 for (std::size_t level = 0; level != minimalNumberOfLevels; ++level) {
799 std::clog <<
"Level : " << level << std::endl;
800 std::clog <<
"PL1 : \n";
801 for (std::size_t i = 0; i != pl1.land_[level].size(); ++i) {
802 std::clog <<
"(" << pl1.land_[level][i].first <<
"," << pl1.land_[level][i].second <<
") \n";
804 std::clog <<
"PL2 : \n";
805 for (std::size_t i = 0; i != pl2.land_[level].size(); ++i) {
806 std::clog <<
"(" << pl2.land_[level][i].first <<
"," << pl2.land_[level][i].second <<
") \n";
812 for (std::size_t i = 1; i != pl1.land_[level].size() - 1; ++i) {
814 if ((pl1.land_[level][i].first >= pl2.land_[level][p2Count].first) &&
815 (pl1.land_[level][i].first <= pl2.land_[level][p2Count + 1].first))
819 double val = std::fabs(
820 function_value(pl2.land_[level][p2Count], pl2.land_[level][p2Count + 1], pl1.land_[level][i].first) -
821 pl1.land_[level][i].second);
822 if (maxDist <= val) maxDist = val;
825 std::clog << pl1.land_[level][i].first <<
"in [" << pl2.land_[level][p2Count].first <<
","
826 << pl2.land_[level][p2Count + 1].first <<
"] \n";
827 std::clog <<
"pl1[level][i].second : " << pl1.land_[level][i].second << std::endl;
828 std::clog <<
"function_value( pl2[level][p2Count] , pl2[level][p2Count+1] , pl1[level][i].first ) : "
829 <<
function_value(pl2.land_[level][p2Count], pl2.land_[level][p2Count + 1], pl1.land_[level][i].first)
831 std::clog <<
"val : " << val << std::endl;
837 std::clog <<
"minimalNumberOfLevels : " << minimalNumberOfLevels << std::endl;
840 if (minimalNumberOfLevels < pl1.land_.size()) {
841 for (std::size_t level = minimalNumberOfLevels; level != pl1.land_.size(); ++level) {
842 for (std::size_t i = 0; i != pl1.land_[level].size(); ++i) {
844 std::clog <<
"pl1[level][i].second : " << pl1.land_[level][i].second << std::endl;
846 if (maxDist < pl1.land_[level][i].second) maxDist = pl1.land_[level][i].second;
853 std::vector<std::vector<std::pair<double, double> > > land_;
854 std::size_t number_of_functions_for_vectorization_;
855 std::size_t number_of_functions_for_projections_to_reals_;
857 void _construct_persistence_landscape_from_barcode(
858 const std::vector<std::pair<double, double> >& p,
859 std::size_t number_of_levels = std::numeric_limits<std::size_t>::max());
861 void _multiply_landscape_by_real_number_overwrite(
double x);
864 void _set_up_numbers_of_functions_for_vectorization_and_projections_to_reals()
866 this->number_of_functions_for_vectorization_ = this->land_.size();
867 this->number_of_functions_for_projections_to_reals_ = this->land_.size();
873 if (this->land_.size() != rhs.land_.size()) {
879 for (std::size_t level = 0; level != this->land_.size(); ++level) {
880 if (this->land_[level].
size() != rhs.land_[level].size()) {
882 std::clog <<
"this->land[level].size() : " << this->land_[level].size() <<
"\n";
883 std::clog <<
"rhs.land[level].size() : " << rhs.land_[level].size() <<
"\n";
888 for (std::size_t i = 0; i != this->land_[level].size(); ++i) {
889 if (!(
almost_equal(this->land_[level][i].first, rhs.land_[level][i].first) &&
890 almost_equal(this->land_[level][i].second, rhs.land_[level][i].second))) {
892 std::clog <<
"this->land[level][i] : " << this->land_[level][i].first <<
" " << this->land_[level][i].second
894 std::clog <<
"rhs.land[level][i] : " << rhs.land_[level][i].first <<
" " << rhs.land_[level][i].second <<
"\n";
904inline void Persistence_landscape::_construct_persistence_landscape_from_barcode(
905 const std::vector<std::pair<double, double> >& p,
906 std::size_t number_of_levels)
909 std::clog <<
"Persistence_landscape::Persistence_landscape( const std::vector< std::pair< double , double > >& p )"
914 std::vector<std::pair<double, double> > bars;
915 bars.insert(bars.begin(), p.begin(), p.end());
916 std::sort(bars.begin(), bars.end(), compare_points_sorting);
919 std::clog <<
"Bars : \n";
920 for (std::size_t i = 0; i != bars.size(); ++i) {
921 std::clog << bars[i].first <<
" " << bars[i].second <<
"\n";
925 std::vector<std::pair<double, double> > characteristicPoints(p.size());
926 for (std::size_t i = 0; i != bars.size(); ++i) {
927 characteristicPoints[i] =
928 std::make_pair((bars[i].first + bars[i].second) / 2.0, (bars[i].second - bars[i].first) / 2.0);
930 std::vector<std::vector<std::pair<double, double> > > Persistence_landscape;
931 std::size_t number_of_levels_in_the_landscape = 0;
932 while (!characteristicPoints.empty()) {
934 for (std::size_t i = 0; i != characteristicPoints.size(); ++i) {
935 std::clog <<
"(" << characteristicPoints[i].first <<
" " << characteristicPoints[i].second <<
")\n";
939 std::vector<std::pair<double, double> > lambda_n;
940 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
941 lambda_n.push_back(std::make_pair(minus_length(characteristicPoints[0]), 0));
942 lambda_n.push_back(characteristicPoints[0]);
945 std::clog <<
"1 Adding to lambda_n : (" << -std::numeric_limits<int>::max() <<
" " << 0 <<
") , ("
946 << minus_length(characteristicPoints[0]) <<
" " << 0 <<
") , (" << characteristicPoints[0].first <<
" "
947 << characteristicPoints[0].second <<
") \n";
951 std::vector<std::pair<double, double> > newCharacteristicPoints;
952 while (i < characteristicPoints.size()) {
954 if ((minus_length(characteristicPoints[i]) >= minus_length(lambda_n[lambda_n.size() - 1])) &&
955 (birth_plus_deaths(characteristicPoints[i]) > birth_plus_deaths(lambda_n[lambda_n.size() - 1]))) {
956 if (minus_length(characteristicPoints[i]) < birth_plus_deaths(lambda_n[lambda_n.size() - 1])) {
957 std::pair<double, double> point = std::make_pair(
958 (minus_length(characteristicPoints[i]) + birth_plus_deaths(lambda_n[lambda_n.size() - 1])) / 2,
959 (birth_plus_deaths(lambda_n[lambda_n.size() - 1]) - minus_length(characteristicPoints[i])) / 2);
960 lambda_n.push_back(point);
962 std::clog <<
"2 Adding to lambda_n : (" << point.first <<
" " << point.second <<
")\n";
966 std::clog <<
"characteristicPoints[i+p] : " << characteristicPoints[i + p].first <<
" "
967 << characteristicPoints[i + p].second <<
"\n";
968 std::clog <<
"point : " << point.first <<
" " << point.second <<
"\n";
971 while ((i + p < characteristicPoints.size()) &&
972 (
almost_equal(minus_length(point), minus_length(characteristicPoints[i + p]))) &&
973 (birth_plus_deaths(point) <= birth_plus_deaths(characteristicPoints[i + p]))) {
974 newCharacteristicPoints.push_back(characteristicPoints[i + p]);
976 std::clog <<
"3.5 Adding to newCharacteristicPoints : (" << characteristicPoints[i + p].first <<
" "
977 << characteristicPoints[i + p].second <<
")\n";
982 newCharacteristicPoints.push_back(point);
984 std::clog <<
"4 Adding to newCharacteristicPoints : (" << point.first <<
" " << point.second <<
")\n";
987 while ((i + p < characteristicPoints.size()) &&
988 (minus_length(point) <= minus_length(characteristicPoints[i + p])) &&
989 (birth_plus_deaths(point) >= birth_plus_deaths(characteristicPoints[i + p]))) {
990 newCharacteristicPoints.push_back(characteristicPoints[i + p]);
992 std::clog <<
"characteristicPoints[i+p] : " << characteristicPoints[i + p].first <<
" "
993 << characteristicPoints[i + p].second <<
"\n";
994 std::clog <<
"point : " << point.first <<
" " << point.second <<
"\n";
995 std::clog <<
"characteristicPoints[i+p] birth and death : " << minus_length(characteristicPoints[i + p])
996 <<
" , " << birth_plus_deaths(characteristicPoints[i + p]) <<
"\n";
997 std::clog <<
"point birth and death : " << minus_length(point) <<
" , " << birth_plus_deaths(point) <<
"\n";
999 std::clog <<
"3 Adding to newCharacteristicPoints : (" << characteristicPoints[i + p].first <<
" "
1000 << characteristicPoints[i + p].second <<
")\n";
1006 lambda_n.push_back(std::make_pair(birth_plus_deaths(lambda_n[lambda_n.size() - 1]), 0));
1007 lambda_n.push_back(std::make_pair(minus_length(characteristicPoints[i]), 0));
1009 std::clog <<
"5 Adding to lambda_n : (" << birth_plus_deaths(lambda_n[lambda_n.size() - 1]) <<
" " << 0
1011 std::clog <<
"5 Adding to lambda_n : (" << minus_length(characteristicPoints[i]) <<
" " << 0 <<
")\n";
1014 lambda_n.push_back(characteristicPoints[i]);
1016 std::clog <<
"6 Adding to lambda_n : (" << characteristicPoints[i].first <<
" "
1017 << characteristicPoints[i].second <<
")\n";
1020 newCharacteristicPoints.push_back(characteristicPoints[i]);
1022 std::clog <<
"7 Adding to newCharacteristicPoints : (" << characteristicPoints[i].first <<
" "
1023 << characteristicPoints[i].second <<
")\n";
1028 lambda_n.push_back(std::make_pair(birth_plus_deaths(lambda_n[lambda_n.size() - 1]), 0));
1029 lambda_n.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
1031 characteristicPoints = newCharacteristicPoints;
1033 lambda_n.erase(std::unique(lambda_n.begin(), lambda_n.end()), lambda_n.end());
1034 this->land_.push_back(lambda_n);
1036 ++number_of_levels_in_the_landscape;
1037 if (number_of_levels == number_of_levels_in_the_landscape) {
1046 if (this->land_.size() < lambda)
return 0;
1047 double maximum = -std::numeric_limits<int>::max();
1048 for (std::size_t i = 0; i != this->land_[lambda].size(); ++i) {
1049 if (this->land_[lambda][i].second > maximum) maximum = this->land_[lambda][i].second;
1057 for (std::size_t i = 0; i != this->land_.size(); ++i) {
1058 for (std::size_t nr = 2; nr != this->land_[i].size() - 1; ++nr) {
1060 result += 0.5 * (this->land_[i][nr].first - this->land_[i][nr - 1].first) *
1061 (this->land_[i][nr].second + this->land_[i][nr - 1].second);
1070 if (level >= this->land_.size()) {
1075 if (level < 0)
return 0;
1077 for (std::size_t nr = 2; nr != this->land_[level].size() - 1; ++nr) {
1079 result += 0.5 * (this->land_[level][nr].first - this->land_[level][nr - 1].first) *
1080 (this->land_[level][nr].second + this->land_[level][nr - 1].second);
1089 for (std::size_t i = 0; i != this->land_.size(); ++i) {
1090 for (std::size_t nr = 2; nr != this->land_[i].size() - 1; ++nr) {
1092 std::clog <<
"nr : " << nr <<
"\n";
1099 std::clog <<
"(" << this->land_[i][nr].first <<
"," << this->land_[i][nr].second <<
") , "
1100 << this->land_[i][nr - 1].first <<
"," << this->land_[i][nr].second <<
")" << std::endl;
1102 if (this->land_[i][nr].first == this->land_[i][nr - 1].first)
continue;
1104 result += 1 / (a * (p + 1)) *
1105 (std::pow((a * this->land_[i][nr].first + b), p + 1) -
1106 std::pow((a * this->land_[i][nr - 1].first + b), p + 1));
1108 result += (this->land_[i][nr].first - this->land_[i][nr - 1].first) * (std::pow(this->land_[i][nr].second, p));
1111 std::clog <<
"a : " << a <<
" , b : " << b << std::endl;
1112 std::clog <<
"result : " << result << std::endl;
1123 if (level >= this->land_.size())
return 0;
1127 unsigned int coordBegin = 1;
1128 unsigned int coordEnd = this->land_[level].size() - 2;
1131 std::clog <<
"Here \n";
1132 std::clog <<
"x : " << x <<
"\n";
1133 std::clog <<
"this->land[level][coordBegin].first : " << this->land_[level][coordBegin].first <<
"\n";
1134 std::clog <<
"this->land[level][coordEnd].first : " << this->land_[level][coordEnd].first <<
"\n";
1138 if (x <= this->land_[level][coordBegin].first)
return 0;
1139 if (x >= this->land_[level][coordEnd].first)
return 0;
1142 std::clog <<
"Entering to the while loop \n";
1145 while (coordBegin + 1 != coordEnd) {
1147 std::clog <<
"coordBegin : " << coordBegin <<
"\n";
1148 std::clog <<
"coordEnd : " << coordEnd <<
"\n";
1149 std::clog <<
"this->land[level][coordBegin].first : " << this->land_[level][coordBegin].first <<
"\n";
1150 std::clog <<
"this->land[level][coordEnd].first : " << this->land_[level][coordEnd].first <<
"\n";
1153 unsigned int newCord = (
unsigned int)floor((coordEnd + coordBegin) / 2.0);
1156 std::clog <<
"newCord : " << newCord <<
"\n";
1157 std::clog <<
"this->land[level][newCord].first : " << this->land_[level][newCord].first <<
"\n";
1160 if (this->land_[level][newCord].first <= x) {
1161 coordBegin = newCord;
1162 if (this->land_[level][newCord].first == x)
return this->land_[level][newCord].second;
1169 std::clog <<
"x : " << x <<
" is between : " << this->land_[level][coordBegin].first <<
" a "
1170 << this->land_[level][coordEnd].first <<
"\n";
1171 std::clog <<
"the y coords are : " << this->land_[level][coordBegin].second <<
" a "
1172 << this->land_[level][coordEnd].second <<
"\n";
1173 std::clog <<
"coordBegin : " << coordBegin <<
"\n";
1174 std::clog <<
"coordEnd : " << coordEnd <<
"\n";
1176 return function_value(this->land_[level][coordBegin], this->land_[level][coordEnd], x);
1179inline void Persistence_landscape::_multiply_landscape_by_real_number_overwrite(
double x)
1181 for (std::size_t dim = 0; dim != this->land_.size(); ++dim) {
1182 for (std::size_t i = 0; i != this->land_[dim].size(); ++i) {
1183 this->land_[dim][i].second *= x;
1191 for (std::size_t level = 0; level != this->land_.size(); ++level) {
1193 std::clog <<
"level: " << level << std::endl;
1195 std::vector<std::pair<double, double> > lambda_n;
1196 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
1197 for (std::size_t i = 1; i != this->land_[level].size(); ++i) {
1199 std::clog <<
"this->land[" << level <<
"][" << i <<
"] : " << this->land_[level][i].first <<
" "
1200 << this->land_[level][i].second << std::endl;
1204 if ((this->land_[level][i - 1].second) * (this->land_[level][i].second) < 0) {
1208 lambda_n.push_back(std::make_pair(zero, 0));
1209 lambda_n.push_back(std::make_pair(this->land_[level][i].first, std::fabs(this->land_[level][i].second)));
1211 std::clog <<
"Adding pair : (" << zero <<
",0)" << std::endl;
1212 std::clog <<
"In the same step adding pair : (" << this->land_[level][i].first <<
","
1213 << std::fabs(this->land_[level][i].second) <<
") " << std::endl;
1216 lambda_n.push_back(std::make_pair(this->land_[level][i].first, std::fabs(this->land_[level][i].second)));
1218 std::clog <<
"Adding pair : (" << this->land_[level][i].first <<
"," << std::fabs(this->land_[level][i].second)
1219 <<
") " << std::endl;
1223 result.land_.push_back(lambda_n);
1231 for (std::size_t level = 0; level != this->land_.size(); ++level) {
1233 std::clog <<
"level: " << level << std::endl;
1235 std::vector<std::pair<double, double> > lambda_n;
1236 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
1237 for (std::size_t i = 1; i != this->land_[level].size(); ++i) {
1239 std::clog <<
"this->land[" << level <<
"][" << i <<
"] : " << this->land_[level][i].first <<
" "
1240 << this->land_[level][i].second << std::endl;
1244 if ((this->land_[level][i - 1].second) * (this->land_[level][i].second) < 0) {
1248 lambda_n.push_back(std::make_pair(zero, 0));
1249 lambda_n.push_back(std::make_pair(this->land_[level][i].first, std::fabs(this->land_[level][i].second)));
1251 std::clog <<
"Adding pair : (" << zero <<
",0)" << std::endl;
1252 std::clog <<
"In the same step adding pair : (" << this->land_[level][i].first <<
","
1253 << std::fabs(this->land_[level][i].second) <<
") " << std::endl;
1256 lambda_n.push_back(std::make_pair(this->land_[level][i].first, std::fabs(this->land_[level][i].second)));
1258 std::clog <<
"Adding pair : (" << this->land_[level][i].first <<
"," << std::fabs(this->land_[level][i].second)
1259 <<
") " << std::endl;
1263 result->land_.push_back(lambda_n);
1268inline Persistence_landscape Persistence_landscape::_multiply_landscape_by_real_number_not_overwrite(
double x)
const
1270 std::vector<std::vector<std::pair<double, double> > > result(this->land_.size());
1271 for (std::size_t dim = 0; dim != this->land_.size(); ++dim) {
1272 std::vector<std::pair<double, double> > lambda_dim(this->land_[dim].
size());
1273 for (std::size_t i = 0; i != this->land_[dim].size(); ++i) {
1274 lambda_dim[i] = std::make_pair(this->land_[dim][i].first, x * this->land_[dim][i].second);
1276 result[dim] = lambda_dim;
1281 res.land_.swap(result);
1287 std::ofstream write;
1288 write.open(filename);
1289 for (std::size_t dim = 0; dim != this->land_.size(); ++dim) {
1290 write <<
"#lambda_" << dim << std::endl;
1291 for (std::size_t i = 1; i != this->land_[dim].size() - 1; ++i) {
1292 write << this->land_[dim][i].first <<
" " << this->land_[dim][i].second << std::endl;
1301 this->land_.clear();
1308 std::cerr <<
"The file : " << filename <<
" do not exist. The program will now terminate \n";
1310 throw std::invalid_argument(
"The persistence landscape file do not exist.");
1314 std::vector<std::pair<double, double> > landscapeAtThisLevel;
1316 bool isThisAFirsLine =
true;
1319 if (!(line.length() == 0 || line[0] ==
'#')) {
1320 std::stringstream lineSS;
1325 landscapeAtThisLevel.push_back(std::make_pair(begin, end));
1327 std::clog <<
"Reading a point : " << begin <<
" , " << end << std::endl;
1331 std::clog <<
"IGNORE LINE\n";
1333 if (!isThisAFirsLine) {
1334 landscapeAtThisLevel.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
1335 this->land_.push_back(landscapeAtThisLevel);
1336 std::vector<std::pair<double, double> > newLevelOdLandscape;
1337 landscapeAtThisLevel.swap(newLevelOdLandscape);
1339 landscapeAtThisLevel.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
1340 isThisAFirsLine =
false;
1343 if (landscapeAtThisLevel.size() > 1) {
1346 landscapeAtThisLevel.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
1347 this->land_.push_back(landscapeAtThisLevel);
1353inline void Persistence_landscape::plot(
const char* filename,
1364 std::ostringstream gnuplot_script;
1365 gnuplot_script << filename <<
"_GnuplotScript";
1366 out.open(gnuplot_script.str().c_str());
1368 if ((xRangeBegin != std::numeric_limits<double>::max()) || (xRangeEnd != std::numeric_limits<double>::max()) ||
1369 (yRangeBegin != std::numeric_limits<double>::max()) || (yRangeEnd != std::numeric_limits<double>::max())) {
1370 out <<
"set xrange [" << xRangeBegin <<
" : " << xRangeEnd <<
"]" << std::endl;
1371 out <<
"set yrange [" << yRangeBegin <<
" : " << yRangeEnd <<
"]" << std::endl;
1374 if (from == std::numeric_limits<int>::max()) {
1377 if (to == std::numeric_limits<int>::max()) {
1378 to = this->land_.size();
1382 for (std::size_t lambda = std::min((std::size_t)from, this->land_.size());
1383 lambda != std::min((std::size_t)to, this->land_.size());
1386 out <<
" '-' using 1:2 notitle with lp";
1387 if (lambda + 1 != std::min((std::size_t)to, this->land_.size())) {
1393 for (std::size_t lambda = std::min((std::size_t)from, this->land_.size());
1394 lambda != std::min((std::size_t)to, this->land_.size());
1396 for (std::size_t i = 1; i != this->land_[lambda].size() - 1; ++i) {
1397 out << this->land_[lambda][i].first <<
" " << this->land_[lambda][i].second << std::endl;
1399 out <<
"EOF" << std::endl;
1402 std::clog <<
"To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
1403 << gnuplot_script.str().c_str() <<
"\'\"" << std::endl;
A class implementing persistence landscapes data structures.
Definition Persistence_landscape.h:66
friend double compute_inner_product(const Persistence_landscape &l1, const Persistence_landscape &l2)
Definition Persistence_landscape.h:530
std::size_t number_of_projections_to_R() const
Definition Persistence_landscape.h:652
friend std::ostream & operator<<(std::ostream &out, const Persistence_landscape &land)
Definition Persistence_landscape.h:141
bool operator==(const Persistence_landscape &rhs) const
Definition Persistence_landscape.h:871
friend double compute_distance_of_landscapes(const Persistence_landscape &first, const Persistence_landscape &second, double p)
Definition Persistence_landscape.h:464
friend Persistence_landscape operator+(const Persistence_landscape &first, const Persistence_landscape &second)
Definition Persistence_landscape.h:326
double compute_scalar_product(const Persistence_landscape &second) const
Definition Persistence_landscape.h:754
friend Persistence_landscape operator-(const Persistence_landscape &first, const Persistence_landscape &second)
Definition Persistence_landscape.h:334
friend double compute_max_norm_distance_of_landscapes(const Persistence_landscape &first, const Persistence_landscape &second)
Definition Persistence_landscape.h:454
Persistence_landscape(const char *filename, unsigned int dimension=std::numeric_limits< unsigned int >::max(), std::size_t number_of_levels=std::numeric_limits< std::size_t >::max())
Definition Persistence_landscape.h:88
Persistence_landscape abs()
Definition Persistence_landscape.h:1188
double compute_integral_of_a_level_of_a_landscape(std::size_t level) const
Definition Persistence_landscape.h:1067
friend Persistence_landscape add_two_landscapes(const Persistence_landscape &land1, const Persistence_landscape &land2)
Definition Persistence_landscape.h:308
std::pair< double, double > get_y_range(std::size_t level=0) const
Definition Persistence_landscape.h:765
friend Persistence_landscape subtract_two_landscapes(const Persistence_landscape &land1, const Persistence_landscape &land2)
Definition Persistence_landscape.h:317
double compute_integral_of_landscape() const
Definition Persistence_landscape.h:1054
double find_max(unsigned int lambda) const
Definition Persistence_landscape.h:1044
Persistence_landscape()
Definition Persistence_landscape.h:71
Persistence_landscape operator-=(const Persistence_landscape &rhs)
Definition Persistence_landscape.h:367
double distance(const Persistence_landscape &second, double power=1) const
Definition Persistence_landscape.h:740
double operator()(unsigned int level, double x) const
Definition Persistence_landscape.h:449
double compute_value_at_a_given_point(unsigned int level, double x) const
Definition Persistence_landscape.h:1120
Persistence_landscape operator+=(const Persistence_landscape &rhs)
Definition Persistence_landscape.h:358
std::size_t size() const
Definition Persistence_landscape.h:520
double project_to_R(int number_of_function) const
Definition Persistence_landscape.h:643
Persistence_landscape operator/=(double x)
Definition Persistence_landscape.h:386
friend Persistence_landscape operator*(const Persistence_landscape &first, double con)
Definition Persistence_landscape.h:342
std::vector< double > vectorize(int number_of_function) const
Definition Persistence_landscape.h:658
double compute_maximum() const
Definition Persistence_landscape.h:406
void compute_average(const std::vector< Persistence_landscape * > &to_average)
Definition Persistence_landscape.h:682
Persistence_landscape operator*=(double x)
Definition Persistence_landscape.h:377
void print_to_file(const char *filename) const
Definition Persistence_landscape.h:1285
Persistence_landscape(const std::vector< std::pair< double, double > > &p, std::size_t number_of_levels=std::numeric_limits< std::size_t >::max())
Definition Persistence_landscape.h:76
friend Persistence_landscape operator*(double con, const Persistence_landscape &first)
Definition Persistence_landscape.h:350
std::size_t number_of_vectorize_functions() const
Definition Persistence_landscape.h:676
bool operator!=(const Persistence_landscape &rhs) const
Definition Persistence_landscape.h:401
void load_landscape_from_file(const char *filename)
Definition Persistence_landscape.h:1298
This file contain an implementation of some common procedures used in the Persistence_representations...
double find_zero_of_a_line_segment_between_those_two_points(const std::pair< double, double > &p1, const std::pair< double, double > &p2)
Definition common_persistence_representations.h:134
std::pair< double, double > compute_parameters_of_a_line(const std::pair< double, double > &p1, const std::pair< double, double > &p2)
Definition common_persistence_representations.h:121
double function_value(const std::pair< double, double > &p1, const std::pair< double, double > &p2, double x)
Definition common_persistence_representations.h:158
bool almost_equal(double a, double b)
Definition common_persistence_representations.h:65
std::vector< std::pair< double, double > > read_persistence_intervals_in_one_dimension_from_file(std::string const &filename, int dimension=-1, double what_to_substitute_for_infinite_bar=-1)
Definition read_persistence_from_file.h:44
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14