11#ifndef PERSISTENCE_LANDSCAPE_H_
12#define PERSISTENCE_LANDSCAPE_H_
15#include <gudhi/read_persistence_from_file.h>
16#include <gudhi/common_persistence_representations.h>
31namespace Persistence_representations {
35template <
typename operation>
71 size_t number_of_levels = std::numeric_limits<size_t>::max());
79 size_t number_of_levels = std::numeric_limits<size_t>::max());
122 template <
typename operation>
131 return operation_on_pair_of_landscapes<std::plus<double> >(land1, land2);
139 return operation_on_pair_of_landscapes<std::minus<double> >(land1, land2);
160 return first.multiply_lanscape_by_real_number_not_overwrite(con);
167 return first.multiply_lanscape_by_real_number_not_overwrite(con);
199 if (x == 0)
throw(
"In operator /=, division by 0. Program terminated.");
200 *
this = *
this * (1 / x);
219 if (this->land.size()) {
220 maxValue = -std::numeric_limits<int>::max();
221 for (
size_t i = 0; i != this->land[0].size(); ++i) {
222 if (this->land[0][i].second > maxValue) maxValue = this->land[0][i].second;
231 double compute_minimum()
const {
233 if (this->land.size()) {
234 minValue = std::numeric_limits<int>::max();
235 for (
size_t i = 0; i != this->land[0].size(); ++i) {
236 if (this->land[0][i].second < minValue) minValue = this->land[0][i].second;
245 double compute_norm_of_landscape(
double i) {
247 if (i < std::numeric_limits<double>::max()) {
284 size_t size()
const {
return this->land.size(); }
289 double find_max(
unsigned lambda)
const;
320 std::vector<double>
vectorize(
int number_of_function)
const {
322 std::vector<double> v;
323 if ((
size_t)number_of_function > this->land.size()) {
326 v.reserve(this->land[number_of_function].
size());
327 for (
size_t i = 0; i != this->land[number_of_function].size(); ++i) {
328 v.push_back(this->land[number_of_function][i].second);
346 std::clog <<
"to_average.size() : " << to_average.size() << std::endl;
349 std::vector<Persistence_landscape*> nextLevelMerge(to_average.size());
350 for (
size_t i = 0; i != to_average.size(); ++i) {
351 nextLevelMerge[i] = to_average[i];
353 bool is_this_first_level =
true;
358 while (nextLevelMerge.size() != 1) {
360 std::clog <<
"nextLevelMerge.size() : " << nextLevelMerge.size() << std::endl;
362 std::vector<Persistence_landscape*> nextNextLevelMerge;
363 nextNextLevelMerge.reserve(to_average.size());
364 for (
size_t i = 0; i < nextLevelMerge.size(); i = i + 2) {
366 std::clog <<
"i : " << i << std::endl;
369 if (i + 1 != nextLevelMerge.size()) {
370 (*l) = (*nextLevelMerge[i]) + (*nextLevelMerge[i + 1]);
372 (*l) = *nextLevelMerge[i];
374 nextNextLevelMerge.push_back(l);
377 std::clog <<
"After this iteration \n";
381 if (!is_this_first_level) {
383 for (
size_t i = 0; i != nextLevelMerge.size(); ++i) {
384 delete nextLevelMerge[i];
387 is_this_first_level =
false;
388 nextLevelMerge.swap(nextNextLevelMerge);
390 (*this) = (*nextLevelMerge[0]);
391 if (!is_this_first_level)
delete nextLevelMerge[0];
392 (*this) *= 1 /
static_cast<double>(to_average.size());
402 if (power < std::numeric_limits<double>::max()) {
424 std::pair<double, double> result;
425 if (level < this->land.size()) {
427 double minn = this->compute_minimum();
428 result = std::make_pair(minn, maxx);
430 result = std::make_pair(0, 0);
436 void plot(
const char* filename,
double xRangeBegin = std::numeric_limits<double>::max(),
437 double xRangeEnd = std::numeric_limits<double>::max(),
438 double yRangeBegin = std::numeric_limits<double>::max(),
439 double yRangeEnd = std::numeric_limits<double>::max(),
int from = std::numeric_limits<int>::max(),
440 int to = std::numeric_limits<int>::max());
443 std::vector<std::vector<std::pair<double, double> > > land;
444 size_t number_of_functions_for_vectorization;
445 size_t number_of_functions_for_projections_to_reals;
447 void construct_persistence_landscape_from_barcode(
const std::vector<std::pair<double, double> >& p,
448 size_t number_of_levels = std::numeric_limits<size_t>::max());
450 void multiply_lanscape_by_real_number_overwrite(
double x);
454 void set_up_numbers_of_functions_for_vectorization_and_projections_to_reals() {
456 this->number_of_functions_for_vectorization = this->land.size();
457 this->number_of_functions_for_projections_to_reals = this->land.size();
462 std::vector<std::pair<double, double> > barcode;
463 if (dimension < std::numeric_limits<double>::max()) {
464 barcode = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
466 barcode = read_persistence_intervals_in_one_dimension_from_file(filename);
468 this->construct_persistence_landscape_from_barcode(barcode, number_of_levels);
469 this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
472bool operatorEqualDbg =
false;
474 if (this->land.size() != rhs.land.size()) {
475 if (operatorEqualDbg) std::clog <<
"1\n";
478 for (
size_t level = 0; level != this->land.size(); ++level) {
479 if (this->land[level].
size() != rhs.land[level].size()) {
480 if (operatorEqualDbg) std::clog <<
"this->land[level].size() : " << this->land[level].size() <<
"\n";
481 if (operatorEqualDbg) std::clog <<
"rhs.land[level].size() : " << rhs.land[level].size() <<
"\n";
482 if (operatorEqualDbg) std::clog <<
"2\n";
485 for (
size_t i = 0; i != this->land[level].size(); ++i) {
486 if (!(almost_equal(this->land[level][i].first, rhs.land[level][i].first) &&
487 almost_equal(this->land[level][i].second, rhs.land[level][i].second))) {
488 if (operatorEqualDbg)
489 std::clog <<
"this->land[level][i] : " << this->land[level][i].first <<
" " << this->land[level][i].second
491 if (operatorEqualDbg)
492 std::clog <<
"rhs.land[level][i] : " << rhs.land[level][i].first <<
" " << rhs.land[level][i].second <<
"\n";
493 if (operatorEqualDbg) std::clog <<
"3\n";
502 size_t number_of_levels) {
503 this->construct_persistence_landscape_from_barcode(p, number_of_levels);
504 this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
507void Persistence_landscape::construct_persistence_landscape_from_barcode(
508 const std::vector<std::pair<double, double> >& p,
size_t number_of_levels) {
511 std::clog <<
"Persistence_landscape::Persistence_landscape( const std::vector< std::pair< double , double > >& p )"
516 std::vector<std::pair<double, double> > bars;
517 bars.insert(bars.begin(), p.begin(), p.end());
518 std::sort(bars.begin(), bars.end(), compare_points_sorting);
521 std::clog <<
"Bars : \n";
522 for (
size_t i = 0; i != bars.size(); ++i) {
523 std::clog << bars[i].first <<
" " << bars[i].second <<
"\n";
528 std::vector<std::pair<double, double> > characteristicPoints(p.size());
529 for (
size_t i = 0; i != bars.size(); ++i) {
530 characteristicPoints[i] =
531 std::make_pair((bars[i].first + bars[i].second) / 2.0, (bars[i].second - bars[i].first) / 2.0);
534 size_t number_of_levels_in_the_landscape = 0;
535 while (!characteristicPoints.empty()) {
537 for (
size_t i = 0; i != characteristicPoints.size(); ++i) {
538 std::clog <<
"(" << characteristicPoints[i].first <<
" " << characteristicPoints[i].second <<
")\n";
543 std::vector<std::pair<double, double> > lambda_n;
544 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
545 lambda_n.push_back(std::make_pair(minus_length(characteristicPoints[0]), 0));
546 lambda_n.push_back(characteristicPoints[0]);
549 std::clog <<
"1 Adding to lambda_n : (" << -std::numeric_limits<int>::max() <<
" " << 0 <<
") , ("
550 << minus_length(characteristicPoints[0]) <<
" " << 0 <<
") , (" << characteristicPoints[0].first <<
" "
551 << characteristicPoints[0].second <<
") \n";
555 std::vector<std::pair<double, double> > newCharacteristicPoints;
556 while (i < characteristicPoints.size()) {
558 if ((minus_length(characteristicPoints[i]) >= minus_length(lambda_n[lambda_n.size() - 1])) &&
559 (birth_plus_deaths(characteristicPoints[i]) > birth_plus_deaths(lambda_n[lambda_n.size() - 1]))) {
560 if (minus_length(characteristicPoints[i]) < birth_plus_deaths(lambda_n[lambda_n.size() - 1])) {
561 std::pair<double, double> point = std::make_pair(
562 (minus_length(characteristicPoints[i]) + birth_plus_deaths(lambda_n[lambda_n.size() - 1])) / 2,
563 (birth_plus_deaths(lambda_n[lambda_n.size() - 1]) - minus_length(characteristicPoints[i])) / 2);
564 lambda_n.push_back(point);
566 std::clog <<
"2 Adding to lambda_n : (" << point.first <<
" " << point.second <<
")\n";
570 std::clog <<
"characteristicPoints[i+p] : " << characteristicPoints[i + p].first <<
" "
571 << characteristicPoints[i + p].second <<
"\n";
572 std::clog <<
"point : " << point.first <<
" " << point.second <<
"\n";
576 while ((i + p < characteristicPoints.size()) &&
577 (almost_equal(minus_length(point), minus_length(characteristicPoints[i + p]))) &&
578 (birth_plus_deaths(point) <= birth_plus_deaths(characteristicPoints[i + p]))) {
579 newCharacteristicPoints.push_back(characteristicPoints[i + p]);
581 std::clog <<
"3.5 Adding to newCharacteristicPoints : (" << characteristicPoints[i + p].first <<
" "
582 << characteristicPoints[i + p].second <<
")\n";
588 newCharacteristicPoints.push_back(point);
590 std::clog <<
"4 Adding to newCharacteristicPoints : (" << point.first <<
" " << point.second <<
")\n";
593 while ((i + p < characteristicPoints.size()) &&
594 (minus_length(point) <= minus_length(characteristicPoints[i + p])) &&
595 (birth_plus_deaths(point) >= birth_plus_deaths(characteristicPoints[i + p]))) {
596 newCharacteristicPoints.push_back(characteristicPoints[i + p]);
598 std::clog <<
"characteristicPoints[i+p] : " << characteristicPoints[i + p].first <<
" "
599 << characteristicPoints[i + p].second <<
"\n";
600 std::clog <<
"point : " << point.first <<
" " << point.second <<
"\n";
601 std::clog <<
"characteristicPoints[i+p] birth and death : " << minus_length(characteristicPoints[i + p])
602 <<
" , " << birth_plus_deaths(characteristicPoints[i + p]) <<
"\n";
603 std::clog <<
"point birth and death : " << minus_length(point) <<
" , " << birth_plus_deaths(point)
606 std::clog <<
"3 Adding to newCharacteristicPoints : (" << characteristicPoints[i + p].first <<
" "
607 << characteristicPoints[i + p].second <<
")\n";
614 lambda_n.push_back(std::make_pair(birth_plus_deaths(lambda_n[lambda_n.size() - 1]), 0));
615 lambda_n.push_back(std::make_pair(minus_length(characteristicPoints[i]), 0));
617 std::clog <<
"5 Adding to lambda_n : (" << birth_plus_deaths(lambda_n[lambda_n.size() - 1]) <<
" " << 0
619 std::clog <<
"5 Adding to lambda_n : (" << minus_length(characteristicPoints[i]) <<
" " << 0 <<
")\n";
622 lambda_n.push_back(characteristicPoints[i]);
624 std::clog <<
"6 Adding to lambda_n : (" << characteristicPoints[i].first <<
" "
625 << characteristicPoints[i].second <<
")\n";
628 newCharacteristicPoints.push_back(characteristicPoints[i]);
630 std::clog <<
"7 Adding to newCharacteristicPoints : (" << characteristicPoints[i].first <<
" "
631 << characteristicPoints[i].second <<
")\n";
636 lambda_n.push_back(std::make_pair(birth_plus_deaths(lambda_n[lambda_n.size() - 1]), 0));
637 lambda_n.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
639 characteristicPoints = newCharacteristicPoints;
641 lambda_n.erase(std::unique(lambda_n.begin(), lambda_n.end()), lambda_n.end());
642 this->land.push_back(lambda_n);
644 ++number_of_levels_in_the_landscape;
645 if (number_of_levels == number_of_levels_in_the_landscape) {
653 if (this->land.size() < lambda)
return 0;
654 double maximum = -std::numeric_limits<int>::max();
655 for (
size_t i = 0; i != this->land[lambda].size(); ++i) {
656 if (this->land[lambda][i].second > maximum) maximum = this->land[lambda][i].second;
663 for (
size_t i = 0; i != this->land.size(); ++i) {
664 for (
size_t nr = 2; nr != this->land[i].size() - 1; ++nr) {
666 result += 0.5 * (this->land[i][nr].first - this->land[i][nr - 1].first) *
667 (this->land[i][nr].second + this->land[i][nr - 1].second);
675 if (level >= this->land.size()) {
680 if (level < 0)
return 0;
682 for (
size_t nr = 2; nr != this->land[level].size() - 1; ++nr) {
684 result += 0.5 * (this->land[level][nr].first - this->land[level][nr - 1].first) *
685 (this->land[level][nr].second + this->land[level][nr - 1].second);
694 for (
size_t i = 0; i != this->land.size(); ++i) {
695 for (
size_t nr = 2; nr != this->land[i].size() - 1; ++nr) {
696 if (dbg) std::clog <<
"nr : " << nr <<
"\n";
699 std::pair<double, double> coef = compute_parameters_of_a_line(this->land[i][nr], this->land[i][nr - 1]);
700 double a = coef.first;
701 double b = coef.second;
704 std::clog <<
"(" << this->land[i][nr].first <<
"," << this->land[i][nr].second <<
") , "
705 << this->land[i][nr - 1].first <<
"," << this->land[i][nr].second <<
")" << std::endl;
706 if (this->land[i][nr].first == this->land[i][nr - 1].first)
continue;
708 result += 1 / (a * (p + 1)) *
709 (pow((a * this->land[i][nr].first + b), p + 1) - pow((a * this->land[i][nr - 1].first + b), p + 1));
711 result += (this->land[i][nr].first - this->land[i][nr - 1].first) * (pow(this->land[i][nr].second, p));
714 std::clog <<
"a : " << a <<
" , b : " << b << std::endl;
715 std::clog <<
"result : " << result << std::endl;
724 bool compute_value_at_a_given_pointDbg =
false;
726 if (level >= this->land.size())
return 0;
730 unsigned coordBegin = 1;
731 unsigned coordEnd = this->land[level].size() - 2;
733 if (compute_value_at_a_given_pointDbg) {
734 std::clog <<
"Here \n";
735 std::clog <<
"x : " << x <<
"\n";
736 std::clog <<
"this->land[level][coordBegin].first : " << this->land[level][coordBegin].first <<
"\n";
737 std::clog <<
"this->land[level][coordEnd].first : " << this->land[level][coordEnd].first <<
"\n";
741 if (x <= this->land[level][coordBegin].first)
return 0;
742 if (x >= this->land[level][coordEnd].first)
return 0;
744 if (compute_value_at_a_given_pointDbg) std::clog <<
"Entering to the while loop \n";
746 while (coordBegin + 1 != coordEnd) {
747 if (compute_value_at_a_given_pointDbg) {
748 std::clog <<
"coordBegin : " << coordBegin <<
"\n";
749 std::clog <<
"coordEnd : " << coordEnd <<
"\n";
750 std::clog <<
"this->land[level][coordBegin].first : " << this->land[level][coordBegin].first <<
"\n";
751 std::clog <<
"this->land[level][coordEnd].first : " << this->land[level][coordEnd].first <<
"\n";
754 unsigned newCord = (unsigned)floor((coordEnd + coordBegin) / 2.0);
756 if (compute_value_at_a_given_pointDbg) {
757 std::clog <<
"newCord : " << newCord <<
"\n";
758 std::clog <<
"this->land[level][newCord].first : " << this->land[level][newCord].first <<
"\n";
762 if (this->land[level][newCord].first <= x) {
763 coordBegin = newCord;
764 if (this->land[level][newCord].first == x)
return this->land[level][newCord].second;
770 if (compute_value_at_a_given_pointDbg) {
771 std::clog <<
"x : " << x <<
" is between : " << this->land[level][coordBegin].first <<
" a "
772 << this->land[level][coordEnd].first <<
"\n";
773 std::clog <<
"the y coords are : " << this->land[level][coordBegin].second <<
" a "
774 << this->land[level][coordEnd].second <<
"\n";
775 std::clog <<
"coordBegin : " << coordBegin <<
"\n";
776 std::clog <<
"coordEnd : " << coordEnd <<
"\n";
779 return function_value(this->land[level][coordBegin], this->land[level][coordEnd], x);
783 for (
size_t level = 0; level != land.land.size(); ++level) {
784 out <<
"Lambda_" << level <<
":" << std::endl;
785 for (
size_t i = 0; i != land.land[level].size(); ++i) {
786 if (land.land[level][i].first == -std::numeric_limits<int>::max()) {
789 if (land.land[level][i].first == std::numeric_limits<int>::max()) {
792 out << land.land[level][i].first;
795 out <<
" , " << land.land[level][i].second << std::endl;
801void Persistence_landscape::multiply_lanscape_by_real_number_overwrite(
double x) {
802 for (
size_t dim = 0; dim != this->land.size(); ++dim) {
803 for (
size_t i = 0; i != this->land[dim].size(); ++i) {
804 this->land[dim][i].second *= x;
812 for (
size_t level = 0; level != this->land.size(); ++level) {
814 std::clog <<
"level: " << level << std::endl;
816 std::vector<std::pair<double, double> > lambda_n;
817 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
818 for (
size_t i = 1; i != this->land[level].size(); ++i) {
820 std::clog <<
"this->land[" << level <<
"][" << i <<
"] : " << this->land[level][i].first <<
" "
821 << this->land[level][i].second << std::endl;
825 if ((this->land[level][i - 1].second) * (this->land[level][i].second) < 0) {
827 find_zero_of_a_line_segment_between_those_two_points(this->land[level][i - 1], this->land[level][i]);
829 lambda_n.push_back(std::make_pair(zero, 0));
830 lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
832 std::clog <<
"Adding pair : (" << zero <<
",0)" << std::endl;
833 std::clog <<
"In the same step adding pair : (" << this->land[level][i].first <<
","
834 << fabs(this->land[level][i].second) <<
") " << std::endl;
838 lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
840 std::clog <<
"Adding pair : (" << this->land[level][i].first <<
"," << fabs(this->land[level][i].second)
841 <<
") " << std::endl;
846 result.land.push_back(lambda_n);
853 for (
size_t level = 0; level != this->land.size(); ++level) {
855 std::clog <<
"level: " << level << std::endl;
857 std::vector<std::pair<double, double> > lambda_n;
858 lambda_n.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
859 for (
size_t i = 1; i != this->land[level].size(); ++i) {
861 std::clog <<
"this->land[" << level <<
"][" << i <<
"] : " << this->land[level][i].first <<
" "
862 << this->land[level][i].second << std::endl;
866 if ((this->land[level][i - 1].second) * (this->land[level][i].second) < 0) {
868 find_zero_of_a_line_segment_between_those_two_points(this->land[level][i - 1], this->land[level][i]);
870 lambda_n.push_back(std::make_pair(zero, 0));
871 lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
873 std::clog <<
"Adding pair : (" << zero <<
",0)" << std::endl;
874 std::clog <<
"In the same step adding pair : (" << this->land[level][i].first <<
","
875 << fabs(this->land[level][i].second) <<
") " << std::endl;
879 lambda_n.push_back(std::make_pair(this->land[level][i].first, fabs(this->land[level][i].second)));
881 std::clog <<
"Adding pair : (" << this->land[level][i].first <<
"," << fabs(this->land[level][i].second)
882 <<
") " << std::endl;
887 result->land.push_back(lambda_n);
892Persistence_landscape Persistence_landscape::multiply_lanscape_by_real_number_not_overwrite(
double x)
const {
893 std::vector<std::vector<std::pair<double, double> > > result(this->land.size());
894 for (
size_t dim = 0; dim != this->land.size(); ++dim) {
895 std::vector<std::pair<double, double> > lambda_dim(this->land[dim].
size());
896 for (
size_t i = 0; i != this->land[dim].size(); ++i) {
897 lambda_dim[i] = std::make_pair(this->land[dim][i].first, x * this->land[dim][i].second);
899 result[dim] = lambda_dim;
904 res.land.swap(result);
910 write.open(filename);
911 for (
size_t dim = 0; dim != this->land.size(); ++dim) {
912 write <<
"#lambda_" << dim << std::endl;
913 for (
size_t i = 1; i != this->land[dim].size() - 1; ++i) {
914 write << this->land[dim][i].first <<
" " << this->land[dim][i].second << std::endl;
929 std::cerr <<
"The file : " << filename <<
" do not exist. The program will now terminate \n";
930 throw "The persistence landscape file do not exist. The program will now terminate \n";
934 std::vector<std::pair<double, double> > landscapeAtThisLevel;
936 bool isThisAFirsLine =
true;
939 if (!(line.length() == 0 || line[0] ==
'#')) {
940 std::stringstream lineSS;
945 landscapeAtThisLevel.push_back(std::make_pair(beginn, endd));
947 std::clog <<
"Reading a point : " << beginn <<
" , " << endd << std::endl;
951 std::clog <<
"IGNORE LINE\n";
954 if (!isThisAFirsLine) {
955 landscapeAtThisLevel.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
956 this->land.push_back(landscapeAtThisLevel);
957 std::vector<std::pair<double, double> > newLevelOdLandscape;
958 landscapeAtThisLevel.swap(newLevelOdLandscape);
960 landscapeAtThisLevel.push_back(std::make_pair(-std::numeric_limits<int>::max(), 0));
961 isThisAFirsLine =
false;
964 if (landscapeAtThisLevel.size() > 1) {
967 landscapeAtThisLevel.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
968 this->land.push_back(landscapeAtThisLevel);
977 bool operation_on_pair_of_landscapesDBG =
false;
978 if (operation_on_pair_of_landscapesDBG) {
979 std::clog <<
"operation_on_pair_of_landscapes\n";
983 std::vector<std::vector<std::pair<double, double> > > land(std::max(land1.land.size(), land2.land.size()));
987 if (operation_on_pair_of_landscapesDBG) {
988 for (
size_t i = 0; i != std::min(land1.land.size(), land2.land.size()); ++i) {
989 std::clog <<
"land1.land[" << i <<
"].size() : " << land1.land[i].size() << std::endl;
990 std::clog <<
"land2.land[" << i <<
"].size() : " << land2.land[i].size() << std::endl;
995 for (
size_t i = 0; i != std::min(land1.land.size(), land2.land.size()); ++i) {
996 std::vector<std::pair<double, double> > lambda_n;
999 while ((p + 1 < land1.land[i].size()) && (q + 1 < land2.land[i].size())) {
1000 if (operation_on_pair_of_landscapesDBG) {
1001 std::clog <<
"p : " << p <<
"\n";
1002 std::clog <<
"q : " << q <<
"\n";
1003 std::clog <<
"land1.land.size() : " << land1.land.size() << std::endl;
1004 std::clog <<
"land2.land.size() : " << land2.land.size() << std::endl;
1005 std::clog <<
"land1.land[" << i <<
"].size() : " << land1.land[i].size() << std::endl;
1006 std::clog <<
"land2.land[" << i <<
"].size() : " << land2.land[i].size() << std::endl;
1007 std::clog <<
"land1.land[i][p].first : " << land1.land[i][p].first <<
"\n";
1008 std::clog <<
"land2.land[i][q].first : " << land2.land[i][q].first <<
"\n";
1011 if (land1.land[i][p].first < land2.land[i][q].first) {
1012 if (operation_on_pair_of_landscapesDBG) {
1013 std::clog <<
"first \n";
1014 std::clog <<
" function_value(land2.land[i][q-1],land2.land[i][q],land1.land[i][p].first) : "
1015 << function_value(land2.land[i][q - 1], land2.land[i][q], land1.land[i][p].first) <<
"\n";
1018 std::make_pair(land1.land[i][p].first,
1019 oper(
static_cast<double>(land1.land[i][p].second),
1020 function_value(land2.land[i][q - 1], land2.land[i][q], land1.land[i][p].first))));
1024 if (land1.land[i][p].first > land2.land[i][q].first) {
1025 if (operation_on_pair_of_landscapesDBG) {
1026 std::clog <<
"Second \n";
1027 std::clog <<
"function_value(" << land1.land[i][p - 1].first <<
" " << land1.land[i][p - 1].second <<
" ,"
1028 << land1.land[i][p].first <<
" " << land1.land[i][p].second <<
", " << land2.land[i][q].first
1029 <<
" ) : " << function_value(land1.land[i][p - 1], land1.land[i][p - 1], land2.land[i][q].first)
1031 std::clog <<
"oper( " << function_value(land1.land[i][p], land1.land[i][p - 1], land2.land[i][q].first) <<
","
1032 << land2.land[i][q].second <<
" : "
1033 << oper(land2.land[i][q].second,
1034 function_value(land1.land[i][p], land1.land[i][p - 1], land2.land[i][q].first))
1037 lambda_n.push_back(std::make_pair(
1038 land2.land[i][q].first, oper(function_value(land1.land[i][p], land1.land[i][p - 1], land2.land[i][q].first),
1039 land2.land[i][q].second)));
1043 if (land1.land[i][p].first == land2.land[i][q].first) {
1044 if (operation_on_pair_of_landscapesDBG) std::clog <<
"Third \n";
1046 std::make_pair(land2.land[i][q].first, oper(land1.land[i][p].second, land2.land[i][q].second)));
1050 if (operation_on_pair_of_landscapesDBG) {
1051 std::clog <<
"Next iteration \n";
1054 while ((p + 1 < land1.land[i].size()) && (q + 1 >= land2.land[i].size())) {
1055 if (operation_on_pair_of_landscapesDBG) {
1056 std::clog <<
"New point : " << land1.land[i][p].first
1057 <<
" oper(land1.land[i][p].second,0) : " << oper(land1.land[i][p].second, 0) << std::endl;
1059 lambda_n.push_back(std::make_pair(land1.land[i][p].first, oper(land1.land[i][p].second, 0)));
1062 while ((p + 1 >= land1.land[i].size()) && (q + 1 < land2.land[i].size())) {
1063 if (operation_on_pair_of_landscapesDBG) {
1064 std::clog <<
"New point : " << land2.land[i][q].first
1065 <<
" oper(0,land2.land[i][q].second) : " << oper(0, land2.land[i][q].second) << std::endl;
1067 lambda_n.push_back(std::make_pair(land2.land[i][q].first, oper(0, land2.land[i][q].second)));
1070 lambda_n.push_back(std::make_pair(std::numeric_limits<int>::max(), 0));
1073 result.land[i].swap(lambda_n);
1075 if (land1.land.size() > std::min(land1.land.size(), land2.land.size())) {
1076 if (operation_on_pair_of_landscapesDBG) {
1077 std::clog <<
"land1.land.size() > std::min( land1.land.size() , land2.land.size() )" << std::endl;
1079 for (
size_t i = std::min(land1.land.size(), land2.land.size()); i != std::max(land1.land.size(), land2.land.size());
1081 std::vector<std::pair<double, double> > lambda_n(land1.land[i]);
1082 for (
size_t nr = 0; nr != land1.land[i].size(); ++nr) {
1083 lambda_n[nr] = std::make_pair(land1.land[i][nr].first, oper(land1.land[i][nr].second, 0));
1087 result.land[i].swap(lambda_n);
1090 if (land2.land.size() > std::min(land1.land.size(), land2.land.size())) {
1091 if (operation_on_pair_of_landscapesDBG) {
1092 std::clog <<
"( land2.land.size() > std::min( land1.land.size() , land2.land.size() ) ) " << std::endl;
1094 for (
size_t i = std::min(land1.land.size(), land2.land.size()); i != std::max(land1.land.size(), land2.land.size());
1096 std::vector<std::pair<double, double> > lambda_n(land2.land[i]);
1097 for (
size_t nr = 0; nr != land2.land[i].size(); ++nr) {
1098 lambda_n[nr] = std::make_pair(land2.land[i][nr].first, oper(0, land2.land[i][nr].second));
1102 result.land[i].swap(lambda_n);
1105 if (operation_on_pair_of_landscapesDBG) {
1106 std::clog <<
"operation_on_pair_of_landscapes END\n";
1114 if (dbg) std::clog <<
" compute_maximal_distance_non_symmetric \n";
1117 size_t minimalNumberOfLevels = std::min(pl1.land.size(), pl2.land.size());
1118 for (
size_t level = 0; level != minimalNumberOfLevels; ++level) {
1120 std::clog <<
"Level : " << level << std::endl;
1121 std::clog <<
"PL1 : \n";
1122 for (
size_t i = 0; i != pl1.land[level].size(); ++i) {
1123 std::clog <<
"(" << pl1.land[level][i].first <<
"," << pl1.land[level][i].second <<
") \n";
1125 std::clog <<
"PL2 : \n";
1126 for (
size_t i = 0; i != pl2.land[level].size(); ++i) {
1127 std::clog <<
"(" << pl2.land[level][i].first <<
"," << pl2.land[level][i].second <<
") \n";
1134 for (
size_t i = 1; i != pl1.land[level].size() - 1; ++i) {
1136 if ((pl1.land[level][i].first >= pl2.land[level][p2Count].first) &&
1137 (pl1.land[level][i].first <= pl2.land[level][p2Count + 1].first))
1142 fabs(function_value(pl2.land[level][p2Count], pl2.land[level][p2Count + 1], pl1.land[level][i].first) -
1143 pl1.land[level][i].second);
1144 if (maxDist <= val) maxDist = val;
1147 std::clog << pl1.land[level][i].first <<
"in [" << pl2.land[level][p2Count].first <<
","
1148 << pl2.land[level][p2Count + 1].first <<
"] \n";
1149 std::clog <<
"pl1[level][i].second : " << pl1.land[level][i].second << std::endl;
1150 std::clog <<
"function_value( pl2[level][p2Count] , pl2[level][p2Count+1] , pl1[level][i].first ) : "
1151 << function_value(pl2.land[level][p2Count], pl2.land[level][p2Count + 1], pl1.land[level][i].first)
1153 std::clog <<
"val : " << val << std::endl;
1159 if (dbg) std::clog <<
"minimalNumberOfLevels : " << minimalNumberOfLevels << std::endl;
1161 if (minimalNumberOfLevels < pl1.land.size()) {
1162 for (
size_t level = minimalNumberOfLevels; level != pl1.land.size(); ++level) {
1163 for (
size_t i = 0; i != pl1.land[level].size(); ++i) {
1164 if (dbg) std::clog <<
"pl1[level][i].second : " << pl1.land[level][i].second << std::endl;
1165 if (maxDist < pl1.land[level][i].second) maxDist = pl1.land[level][i].second;
1185 std::clog <<
"Abs of difference ; " << lan << std::endl;
1189 if (p < std::numeric_limits<double>::max()) {
1193 if (dbg) std::clog <<
"Power != 1, compute integral to the power p\n";
1196 if (dbg) std::clog <<
"Power = 1, compute integral \n";
1200 return pow(result, 1.0 / p);
1203 if (dbg) std::clog <<
"Power = infty, compute maximum \n";
1210 return std::max(compute_maximal_distance_non_symmetric(first, second),
1211 compute_maximal_distance_non_symmetric(second, first));
1214bool comparePairsForMerging(std::pair<double, unsigned> first, std::pair<double, unsigned> second) {
1215 return (first.first < second.first);
1222 for (
size_t level = 0; level != std::min(l1.
size(), l2.
size()); ++level) {
1224 std::clog <<
"Computing inner product for a level : " << level << std::endl;
1227 auto&& l1_land_level = l1.land[level];
1228 auto&& l2_land_level = l2.land[level];
1230 if (l1_land_level.size() * l2_land_level.size() == 0)
continue;
1233 double x1 = -std::numeric_limits<int>::max();
1235 if (l1_land_level[1].first < l2_land_level[1].first) {
1236 x2 = l1_land_level[1].first;
1238 x2 = l2_land_level[1].first;
1245 while ((l1It < l1_land_level.size() - 1) && (l2It < l2_land_level.size() - 1)) {
1250 if (l1_land_level[l1It + 1].first != l1_land_level[l1It].first) {
1251 a = (l1_land_level[l1It + 1].second - l1_land_level[l1It].second) /
1252 (l1_land_level[l1It + 1].first - l1_land_level[l1It].first);
1256 b = l1_land_level[l1It].second - a * l1_land_level[l1It].first;
1257 if (l2_land_level[l2It + 1].first != l2_land_level[l2It].first) {
1258 c = (l2_land_level[l2It + 1].second - l2_land_level[l2It].second) /
1259 (l2_land_level[l2It + 1].first - l2_land_level[l2It].first);
1263 d = l2_land_level[l2It].second - c * l2_land_level[l2It].first;
1265 double contributionFromThisPart = (a * c * x2 * x2 * x2 / 3 + (a * d + b * c) * x2 * x2 / 2 + b * d * x2) -
1266 (a * c * x1 * x1 * x1 / 3 + (a * d + b * c) * x1 * x1 / 2 + b * d * x1);
1268 result += contributionFromThisPart;
1271 std::clog <<
"[l1_land_level[l1It].first,l1_land_level[l1It+1].first] : " << l1_land_level[l1It].first
1272 <<
" , " << l1_land_level[l1It + 1].first << std::endl;
1273 std::clog <<
"[l2_land_level[l2It].first,l2_land_level[l2It+1].first] : " << l2_land_level[l2It].first
1274 <<
" , " << l2_land_level[l2It + 1].first << std::endl;
1275 std::clog <<
"a : " << a <<
", b : " << b <<
" , c: " << c <<
", d : " << d << std::endl;
1276 std::clog <<
"x1 : " << x1 <<
" , x2 : " << x2 << std::endl;
1277 std::clog <<
"contributionFromThisPart : " << contributionFromThisPart << std::endl;
1278 std::clog <<
"result : " << result << std::endl;
1289 if (x2 == l1_land_level[l1It + 1].first) {
1290 if (x2 == l2_land_level[l2It + 1].first) {
1294 std::clog <<
"Incrementing both \n";
1298 std::clog <<
"Incrementing first \n";
1306 std::clog <<
"Incrementing second \n";
1310 if ( l1It + 1 >= l1_land_level.size() )
break;
1311 if ( l2It + 1 >= l2_land_level.size() )
break;
1315 if (l1_land_level[l1It + 1].first < l2_land_level[l2It + 1].first) {
1316 x2 = l1_land_level[l1It + 1].first;
1318 x2 = l2_land_level[l2It + 1].first;
1325void Persistence_landscape::plot(
const char* filename,
double xRangeBegin,
double xRangeEnd,
double yRangeBegin,
1326 double yRangeEnd,
int from,
int to) {
1330 std::ostringstream gnuplot_script;
1331 gnuplot_script << filename <<
"_GnuplotScript";
1332 out.open(gnuplot_script.str().c_str());
1334 if ((xRangeBegin != std::numeric_limits<double>::max()) || (xRangeEnd != std::numeric_limits<double>::max()) ||
1335 (yRangeBegin != std::numeric_limits<double>::max()) || (yRangeEnd != std::numeric_limits<double>::max())) {
1336 out <<
"set xrange [" << xRangeBegin <<
" : " << xRangeEnd <<
"]" << std::endl;
1337 out <<
"set yrange [" << yRangeBegin <<
" : " << yRangeEnd <<
"]" << std::endl;
1340 if (from == std::numeric_limits<int>::max()) {
1343 if (to == std::numeric_limits<int>::max()) {
1344 to = this->land.size();
1348 for (
size_t lambda = std::min((
size_t)from, this->land.size()); lambda != std::min((
size_t)to, this->land.size());
1351 out <<
" '-' using 1:2 notitle with lp";
1352 if (lambda + 1 != std::min((
size_t)to, this->land.size())) {
1358 for (
size_t lambda = std::min((
size_t)from, this->land.size()); lambda != std::min((
size_t)to, this->land.size());
1360 for (
size_t i = 1; i != this->land[lambda].size() - 1; ++i) {
1361 out << this->land[lambda][i].first <<
" " << this->land[lambda][i].second << std::endl;
1363 out <<
"EOF" << std::endl;
1365 std::clog <<
"To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
1366 << gnuplot_script.str().c_str() <<
"\'\"" << std::endl;
A class implementing persistence landscapes data structures.
Definition: Persistence_landscape.h:60
friend double compute_inner_product(const Persistence_landscape &l1, const Persistence_landscape &l2)
Definition: Persistence_landscape.h:1218
bool operator==(const Persistence_landscape &rhs) const
Definition: Persistence_landscape.h:473
friend double compute_distance_of_landscapes(const Persistence_landscape &first, const Persistence_landscape &second, double p)
Definition: Persistence_landscape.h:1172
friend Persistence_landscape operator+(const Persistence_landscape &first, const Persistence_landscape &second)
Definition: Persistence_landscape.h:145
size_t number_of_projections_to_R() const
Definition: Persistence_landscape.h:314
double compute_scalar_product(const Persistence_landscape &second) const
Definition: Persistence_landscape.h:414
friend Persistence_landscape operator-(const Persistence_landscape &first, const Persistence_landscape &second)
Definition: Persistence_landscape.h:152
friend double compute_max_norm_distance_of_landscapes(const Persistence_landscape &first, const Persistence_landscape &second)
Definition: Persistence_landscape.h:1208
size_t number_of_vectorize_functions() const
Definition: Persistence_landscape.h:336
Persistence_landscape abs()
Definition: Persistence_landscape.h:810
friend Persistence_landscape add_two_landscapes(const Persistence_landscape &land1, const Persistence_landscape &land2)
Definition: Persistence_landscape.h:129
double find_max(unsigned lambda) const
Definition: Persistence_landscape.h:652
double compute_integral_of_a_level_of_a_landscape(size_t level) const
Definition: Persistence_landscape.h:673
friend Persistence_landscape subtract_two_landscapes(const Persistence_landscape &land1, const Persistence_landscape &land2)
Definition: Persistence_landscape.h:137
double compute_integral_of_landscape() const
Definition: Persistence_landscape.h:661
Persistence_landscape()
Definition: Persistence_landscape.h:65
Persistence_landscape operator-=(const Persistence_landscape &rhs)
Definition: Persistence_landscape.h:181
double distance(const Persistence_landscape &second, double power=1) const
Definition: Persistence_landscape.h:401
Persistence_landscape operator+=(const Persistence_landscape &rhs)
Definition: Persistence_landscape.h:173
double compute_value_at_a_given_point(unsigned level, double x) const
Definition: Persistence_landscape.h:723
double project_to_R(int number_of_function) const
Definition: Persistence_landscape.h:306
Persistence_landscape operator/=(double x)
Definition: Persistence_landscape.h:198
friend Persistence_landscape operator*(const Persistence_landscape &first, double con)
Definition: Persistence_landscape.h:159
std::vector< double > vectorize(int number_of_function) const
Definition: Persistence_landscape.h:320
double compute_maximum() const
Definition: Persistence_landscape.h:217
std::pair< double, double > get_y_range(size_t level=0) const
Definition: Persistence_landscape.h:423
void compute_average(const std::vector< Persistence_landscape * > &to_average)
Definition: Persistence_landscape.h:342
Persistence_landscape operator*=(double x)
Definition: Persistence_landscape.h:190
void print_to_file(const char *filename) const
Definition: Persistence_landscape.h:908
double operator()(unsigned level, double x) const
Definition: Persistence_landscape.h:257
friend Persistence_landscape operator*(double con, const Persistence_landscape &first)
Definition: Persistence_landscape.h:166
friend std::ostream & operator<<(std::ostream &out, Persistence_landscape &land)
Definition: Persistence_landscape.h:782
size_t size() const
Definition: Persistence_landscape.h:284
bool operator!=(const Persistence_landscape &rhs) const
Definition: Persistence_landscape.h:212
void load_landscape_from_file(const char *filename)
Definition: Persistence_landscape.h:920
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14