Loading...
Searching...
No Matches
Persistence_landscape_on_grid.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): Pawel Dlotko
4 *
5 * Copyright (C) 2016 Inria
6 *
7 * Modification(s):
8 * - 2025/06 Hannah Schreiber: Various small bug fixes (missing `inline`s, `DEBUG_TRACES`s etc.)
9 * - YYYY/MM Author: Description of the modification
10 */
11
12#ifndef PERSISTENCE_LANDSCAPE_ON_GRID_H_
13#define PERSISTENCE_LANDSCAPE_ON_GRID_H_
14
15// standard include
16#ifdef DEBUG_TRACES
17#include <iostream> // std::cerr, std::clog
18#endif
19#include <cstddef> // std::size_t
20#include <cstdint> // std::uint16_t
21#include <ostream> // std::ostream
22#include <fstream> // std::ofstream, std::ifstream
23#include <sstream> // std::istringstream, std::ostringstream
24#include <stdexcept> // std::invalid_argument
25#include <limits> // std::numeric_limits
26#include <algorithm> // std::make_heap, std::pop_heap, std::push_heap
27#include <cmath> // std::pow
28#include <utility> // std::pair
29#include <vector>
30#include <string>
31
32// gudhi include
33#include <gudhi/read_persistence_from_file.h>
35#include <gudhi/Debug_utils.h>
36
37namespace Gudhi {
38namespace Persistence_representations {
39
40// pre declaration needed before C++20 for friends with templates defined inside a class
42template <typename Operation>
43Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid& land1,
45
63{
64 public:
69 : grid_min_(0),
70 grid_max_(0),
71 number_of_functions_for_vectorization_(0),
72 number_of_functions_for_projections_to_reals_(0)
73 {}
74
78 Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
79 double grid_min,
80 double grid_max,
81 std::size_t number_of_points)
82 {
83 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points);
84 }
85
90 Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
91 double grid_min,
92 double grid_max,
93 std::size_t number_of_points,
94 unsigned number_of_levels_of_landscape)
95 {
96 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points, number_of_levels_of_landscape);
97 }
98
107 Persistence_landscape_on_grid(const char* filename,
108 double grid_min,
109 double grid_max,
110 std::size_t number_of_points,
111 unsigned number_of_levels_of_landscape,
112 std::uint16_t dimension = std::numeric_limits<std::uint16_t>::max())
113 {
114 std::vector<std::pair<double, double> > p;
115 if (dimension == std::numeric_limits<std::uint16_t>::max()) {
117 } else {
119 }
120 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points, number_of_levels_of_landscape);
121 }
122
130 Persistence_landscape_on_grid(const char* filename,
131 double grid_min,
132 double grid_max,
133 std::size_t number_of_points,
134 std::uint16_t dimension = std::numeric_limits<std::uint16_t>::max())
135 {
136 std::vector<std::pair<double, double> > p;
137 if (dimension == std::numeric_limits<std::uint16_t>::max()) {
139 } else {
141 }
142 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points);
143 }
144
152 Persistence_landscape_on_grid(const char* filename,
153 std::size_t number_of_points,
154 unsigned number_of_levels_of_landscape,
155 std::uint16_t dimension = std::numeric_limits<std::uint16_t>::max())
156 {
157 std::vector<std::pair<double, double> > p;
158 if (dimension == std::numeric_limits<std::uint16_t>::max()) {
160 } else {
162 }
163 double grid_min = std::numeric_limits<double>::max();
164 double grid_max = -std::numeric_limits<double>::max();
165 for (std::size_t i = 0; i != p.size(); ++i) {
166 if (p[i].first < grid_min) grid_min = p[i].first;
167 if (p[i].second > grid_max) grid_max = p[i].second;
168 }
169 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points, number_of_levels_of_landscape);
170 }
171
180 Persistence_landscape_on_grid(const char* filename,
181 std::size_t number_of_points,
182 std::uint16_t dimension = std::numeric_limits<std::uint16_t>::max())
183 {
184 std::vector<std::pair<double, double> > p;
185 if (dimension == std::numeric_limits<std::uint16_t>::max()) {
187 } else {
189 }
190 double grid_min = std::numeric_limits<double>::max();
191 double grid_max = -std::numeric_limits<double>::max();
192 for (std::size_t i = 0; i != p.size(); ++i) {
193 if (p[i].first < grid_min) grid_min = p[i].first;
194 if (p[i].second > grid_max) grid_max = p[i].second;
195 }
196 this->_set_up_values_of_landscapes(p, grid_min, grid_max, number_of_points);
197 }
198
202 void load_landscape_from_file(const char* filename);
203
207 void print_to_file(const char* filename) const;
208
214 {
215 std::size_t maximal_level = this->number_of_nonzero_levels();
216 double result = 0;
217 for (std::size_t i = 0; i != maximal_level; ++i) {
218 result += this->compute_integral_of_landscape(i);
219 }
220 return result;
221 }
222
226 double compute_integral_of_landscape(std::size_t level) const
227 {
228 double result = 0;
229 double dx = (this->grid_max_ - this->grid_min_) / static_cast<double>(this->values_of_landscapes_.size() - 1);
230
231#ifdef DEBUG_TRACES
232 std::clog << "this->grid_max : " << this->grid_max_ << std::endl;
233 std::clog << "this->grid_min : " << this->grid_min_ << std::endl;
234 std::clog << "this->values_of_landscapes.size() : " << this->values_of_landscapes_.size() << std::endl;
235#endif
236
237 double previous_x = this->grid_min_ - dx;
238 double previous_y = 0;
239 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
240 double current_x = previous_x + dx;
241 double current_y = 0;
242 if (this->values_of_landscapes_[i].size() > level) current_y = this->values_of_landscapes_[i][level];
243
244#ifdef DEBUG_TRACES
245 std::clog << "this->values_of_landscapes[i].size() : " << this->values_of_landscapes_[i].size()
246 << " , level : " << level << std::endl;
247 if (this->values_of_landscapes_[i].size() > level)
248 std::clog << "this->values_of_landscapes[i][level] : " << this->values_of_landscapes_[i][level] << std::endl;
249 std::clog << "previous_y : " << previous_y << std::endl;
250 std::clog << "current_y : " << current_y << std::endl;
251 std::clog << "dx : " << dx << std::endl;
252 std::clog << "0.5*dx*( previous_y + current_y ); " << 0.5 * dx * (previous_y + current_y) << std::endl;
253#endif
254
255 result += 0.5 * dx * (previous_y + current_y);
256 previous_x = current_x;
257 previous_y = current_y;
258 }
259 return result;
260 }
261
266 double compute_integral_of_landscape(double p) const
267 {
268 std::size_t maximal_level = this->number_of_nonzero_levels();
269 double result = 0;
270 for (std::size_t i = 0; i != maximal_level; ++i) {
271 result += this->compute_integral_of_landscape(p, i);
272 }
273 return result;
274 }
275
280 double compute_integral_of_landscape(double p, std::size_t level) const
281 {
282 double result = 0;
283 double dx = (this->grid_max_ - this->grid_min_) / static_cast<double>(this->values_of_landscapes_.size() - 1);
284 double previous_x = this->grid_min_;
285 double previous_y = 0;
286 if (this->values_of_landscapes_[0].size() > level) previous_y = this->values_of_landscapes_[0][level];
287
288#ifdef DEBUG_TRACES
289 std::clog << "dx : " << dx << std::endl;
290 std::clog << "previous_x : " << previous_x << std::endl;
291 std::clog << "previous_y : " << previous_y << std::endl;
292 std::clog << "power : " << p << std::endl;
293#endif
294
295 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
296 double current_x = previous_x + dx;
297 double current_y = 0;
298 if (this->values_of_landscapes_[i].size() > level) current_y = this->values_of_landscapes_[i][level];
299
300#ifdef DEBUG_TRACES
301 std::clog << "current_y : " << current_y << std::endl;
302#endif
303
304 if (current_y == previous_y) continue;
305
306 std::pair<double, double> coef =
307 compute_parameters_of_a_line(std::make_pair(previous_x, previous_y), std::make_pair(current_x, current_y));
308 double a = coef.first;
309 double b = coef.second;
310
311#ifdef DEBUG_TRACES
312 std::clog << "A line passing through points : (" << previous_x << "," << previous_y << ") and (" << current_x
313 << "," << current_y << ") is : " << a << "x+" << b << std::endl;
314#endif
315
316 // In this interval, the landscape has a form f(x) = ax+b. We want to compute integral of (ax+b)^p = 1/a *
317 // (ax+b)^{p+1}/(p+1)
318 double value_to_add = 0;
319 if (a != 0) {
320 value_to_add =
321 1 / (a * (p + 1)) * (std::pow((a * current_x + b), p + 1) - std::pow((a * previous_x + b), p + 1));
322 } else {
323 value_to_add = (current_x - previous_x) * (std::pow(b, p));
324 }
325 result += value_to_add;
326#ifdef DEBUG_TRACES
327 std::clog << "Increasing result by : " << value_to_add << std::endl;
328 std::clog << "result : " << result << std::endl;
329#endif
330 previous_x = current_x;
331 previous_y = current_y;
332 }
333#ifdef DEBUG_TRACES
334 std::clog << "The total result is : " << result << std::endl;
335#endif
336 return result;
337 }
338
344 friend std::ostream& operator<<(std::ostream& out, const Persistence_landscape_on_grid& land)
345 {
346 double dx = (land.grid_max_ - land.grid_min_) / static_cast<double>(land.values_of_landscapes_.size() - 1);
347 double x = land.grid_min_;
348 for (std::size_t i = 0; i != land.values_of_landscapes_.size(); ++i) {
349 out << x << " : ";
350 for (std::size_t j = 0; j != land.values_of_landscapes_[i].size(); ++j) {
351 out << land.values_of_landscapes_[i][j] << " ";
352 }
353 out << std::endl;
354 x += dx;
355 }
356 return out;
357 }
358
364 double compute_value_at_a_given_point(unsigned level, double x) const
365 {
366 if ((x < this->grid_min_) || (x > this->grid_max_)) return 0;
367
368 // find a position of a vector closest to x:
369 double dx = (this->grid_max_ - this->grid_min_) / static_cast<double>(this->values_of_landscapes_.size() - 1);
370 std::size_t position = std::size_t((x - this->grid_min_) / dx);
371
372#ifdef DEBUG_TRACES
373 std::clog << "This is a procedure compute_value_at_a_given_point \n";
374 std::clog << "level : " << level << std::endl;
375 std::clog << "x : " << x << std::endl;
376 std::clog << "position : " << position << std::endl;
377#endif
378
379 // check if we are not exactly in the grid point:
380 if (almost_equal(position * dx + this->grid_min_, x)) {
381 if (this->values_of_landscapes_[position].size() < level) {
382 return this->values_of_landscapes_[position][level];
383 } else {
384 return 0;
385 }
386 }
387 // in the other case, approximate with a line:
388 std::pair<double, double> line;
389 if ((this->values_of_landscapes_[position].size() > level) &&
390 (this->values_of_landscapes_[position + 1].size() > level)) {
392 std::make_pair(position * dx + this->grid_min_, this->values_of_landscapes_[position][level]),
393 std::make_pair((position + 1) * dx + this->grid_min_, this->values_of_landscapes_[position + 1][level]));
394 } else {
395 if ((this->values_of_landscapes_[position].size() > level) ||
396 (this->values_of_landscapes_[position + 1].size() > level)) {
397 if ((this->values_of_landscapes_[position].size() > level)) {
399 std::make_pair(position * dx + this->grid_min_, this->values_of_landscapes_[position][level]),
400 std::make_pair((position + 1) * dx + this->grid_min_, 0));
401 } else {
403 std::make_pair(position * dx + this->grid_min_, 0),
404 std::make_pair((position + 1) * dx + this->grid_min_, this->values_of_landscapes_[position + 1][level]));
405 }
406 } else {
407 return 0;
408 }
409 }
410 // compute the value of the linear function parametrized by line on a point x:
411 return line.first * x + line.second;
412 }
413
414 friend bool check_if_defined_on_the_same_domain(const Persistence_landscape_on_grid& land1,
416 {
417 if (land1.values_of_landscapes_.size() != land2.values_of_landscapes_.size()) return false;
418 if (land1.grid_min_ != land2.grid_min_) return false;
419 if (land1.grid_max_ != land2.grid_max_) return false;
420 return true;
421 }
422
426 template <typename Operation>
430 {
431 // TODO: replace this with a GUDHI_CHECK?
432 // first we need to check if the domains are the same:
433 if (!check_if_defined_on_the_same_domain(land1, land2)) throw std::invalid_argument("Two grids are not compatible");
434
435 Operation oper;
437 result.values_of_landscapes_ = std::vector<std::vector<double> >(land1.values_of_landscapes_.size());
438 result.grid_min_ = land1.grid_min_;
439 result.grid_max_ = land1.grid_max_;
440
441 // now we perform the operations:
442 for (std::size_t grid_point = 0; grid_point != land1.values_of_landscapes_.size(); ++grid_point) {
443 result.values_of_landscapes_[grid_point] = std::vector<double>(
444 std::max(land1.values_of_landscapes_[grid_point].size(), land2.values_of_landscapes_[grid_point].size()));
445 for (std::size_t lambda = 0; lambda != std::max(land1.values_of_landscapes_[grid_point].size(),
446 land2.values_of_landscapes_[grid_point].size());
447 ++lambda) {
448 double value1 = 0;
449 double value2 = 0;
450 if (lambda < land1.values_of_landscapes_[grid_point].size())
451 value1 = land1.values_of_landscapes_[grid_point][lambda];
452 if (lambda < land2.values_of_landscapes_[grid_point].size())
453 value2 = land2.values_of_landscapes_[grid_point][lambda];
454 result.values_of_landscapes_[grid_point][lambda] = oper(value1, value2);
455 }
456 }
457
458 return result;
459 }
460
461 // TODO: `add_two_landscapes` and `subtract_two_landscapes` do not seem to be used outside of resp.
462 // `operator+` and `operator-` and their doc is marked private. Are they really necessary?
463 // Can `operation_on_pair_of_landscapes_on_grid` not be directly called in `operator+` and `operator-`?
464
473
482
487 const Persistence_landscape_on_grid& second)
488 {
489 return add_two_landscapes(first, second);
490 }
491
496 const Persistence_landscape_on_grid& second)
497 {
498 return subtract_two_landscapes(first, second);
499 }
500
505 {
506 return first._multiply_landscape_by_real_number_not_overwrite(con);
507 }
508
513 {
514 return first._multiply_landscape_by_real_number_not_overwrite(con);
515 }
516
521 {
522 *this = *this + rhs;
523 return *this;
524 }
525
530 {
531 *this = *this - rhs;
532 return *this;
533 }
534
540 {
541 *this = *this * x;
542 return *this;
543 }
544
549 {
550 if (x == 0) throw("In operator /=, division by 0. Program terminated.");
551 *this = *this * (1 / x);
552 return *this;
553 }
554
559 {
560 if (this->values_of_landscapes_.size() != rhs.values_of_landscapes_.size()) {
561#ifdef DEBUG_TRACES
562 std::clog << "values_of_landscapes of incompatible sizes\n";
563#endif
564 return false;
565 }
566 if (!almost_equal(this->grid_min_, rhs.grid_min_)) {
567#ifdef DEBUG_TRACES
568 std::clog << "grid_min not equal\n";
569#endif
570 return false;
571 }
572 if (!almost_equal(this->grid_max_, rhs.grid_max_)) {
573#ifdef DEBUG_TRACES
574 std::clog << "grid_max not equal\n";
575#endif
576 return false;
577 }
578 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
579 for (std::size_t aa = 0; aa != this->values_of_landscapes_[i].size(); ++aa) {
580 if (!almost_equal(this->values_of_landscapes_[i][aa], rhs.values_of_landscapes_[i][aa])) {
581#ifdef DEBUG_TRACES
582 std::clog << "Problem in the position : " << i << " of values_of_landscapes. \n";
583 std::clog << this->values_of_landscapes_[i][aa] << " " << rhs.values_of_landscapes_[i][aa] << std::endl;
584#endif
585 return false;
586 }
587 }
588 }
589 return true;
590 }
591
595 bool operator!=(const Persistence_landscape_on_grid& rhs) const { return !((*this) == rhs); }
596
600 double compute_maximum() const
601 {
602 // since the function can only be entirely positive or negative, the maximal value will be an extrema value in the
603 // arrays:
604 double max_value = -std::numeric_limits<double>::max();
605 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
606 if (this->values_of_landscapes_[i].size()) {
607 if (this->values_of_landscapes_[i][0] > max_value) max_value = this->values_of_landscapes_[i][0];
608 if (this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1] > max_value)
609 max_value = this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1];
610 }
611 }
612 return max_value;
613 }
614
618 std::pair<double, double> compute_minimum_maximum() const
619 {
620 // since the function can only be entirely positive or negative, the maximal value will be an extrema value in the
621 // arrays:
622 double max_value = -std::numeric_limits<double>::max();
623 double min_value = 0;
624 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
625 if (this->values_of_landscapes_[i].size()) {
626 if (this->values_of_landscapes_[i][0] > max_value) max_value = this->values_of_landscapes_[i][0];
627 if (this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1] > max_value)
628 max_value = this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1];
629
630 if (this->values_of_landscapes_[i][0] < min_value) min_value = this->values_of_landscapes_[i][0];
631 if (this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1] < min_value)
632 min_value = this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1];
633 }
634 }
635 return std::make_pair(min_value, max_value);
636 }
637
642 std::pair<double, double> get_x_range(std::size_t level = 0) const
643 {
644 return std::make_pair(this->grid_min_, this->grid_max_);
645 }
646
651 std::pair<double, double> get_y_range(std::size_t level = 0) const { return this->compute_minimum_maximum(); }
652
656 std::size_t number_of_nonzero_levels() const
657 {
658 std::size_t result = 0;
659 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
660 if (this->values_of_landscapes_[i].size() > result) result = this->values_of_landscapes_[i].size();
661 }
662 return result;
663 }
664
668 double compute_norm_of_landscape(double i) const
669 {
670 std::vector<std::pair<double, double> > p;
671 Persistence_landscape_on_grid l(p, this->grid_min_, this->grid_max_, this->values_of_landscapes_.size() - 1);
672
673 if (i < std::numeric_limits<double>::max()) {
674 return compute_distance_of_landscapes_on_grid(*this, l, i);
675 } else {
677 }
678 }
679
683 double operator()(unsigned int level, double x) const { return this->compute_value_at_a_given_point(level, x); }
684
689 const Persistence_landscape_on_grid& second)
690 {
691 double result = 0;
692
693 // first we need to check if first and second is defined on the same domain"
694 if (!check_if_defined_on_the_same_domain(first, second)) throw "Two grids are not compatible";
695
696 for (std::size_t i = 0; i != first.values_of_landscapes_.size(); ++i) {
697 for (std::size_t j = 0;
698 j != std::min(first.values_of_landscapes_[i].size(), second.values_of_landscapes_[i].size());
699 ++j) {
700 if (result < std::abs(first.values_of_landscapes_[i][j] - second.values_of_landscapes_[i][j])) {
701 result = std::abs(first.values_of_landscapes_[i][j] - second.values_of_landscapes_[i][j]);
702 }
703 }
704 if (first.values_of_landscapes_[i].size() ==
705 std::min(first.values_of_landscapes_[i].size(), second.values_of_landscapes_[i].size())) {
706 for (std::size_t j = first.values_of_landscapes_[i].size(); j != second.values_of_landscapes_[i].size(); ++j) {
707 if (result < second.values_of_landscapes_[i][j]) result = second.values_of_landscapes_[i][j];
708 }
709 }
710 if (second.values_of_landscapes_[i].size() ==
711 std::min(first.values_of_landscapes_[i].size(), second.values_of_landscapes_[i].size())) {
712 for (std::size_t j = second.values_of_landscapes_[i].size(); j != first.values_of_landscapes_[i].size(); ++j) {
713 if (result < first.values_of_landscapes_[i][j]) result = first.values_of_landscapes_[i][j];
714 }
715 }
716 }
717 return result;
718 }
719
726 void abs()
727 {
728 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
729 for (std::size_t j = 0; j != this->values_of_landscapes_[i].size(); ++j) {
730 this->values_of_landscapes_[i][j] = std::abs(this->values_of_landscapes_[i][j]);
731 }
732 }
733 }
734
738 std::size_t size() const { return this->number_of_nonzero_levels(); }
739
743 double find_max(unsigned lambda) const
744 {
745 double max_value = -std::numeric_limits<double>::max();
746 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
747 if (this->values_of_landscapes_[i].size() > lambda) {
748 if (this->values_of_landscapes_[i][lambda] > max_value) max_value = this->values_of_landscapes_[i][lambda];
749 }
750 }
751 return max_value;
752 }
753
758 {
759 // TODO: replace with a GUDHI_CHECK?
760 if (!check_if_defined_on_the_same_domain(l1, l2))
761 throw std::invalid_argument("Landscapes are not defined on the same grid, the program will now terminate");
762 std::size_t maximal_level = l1.number_of_nonzero_levels();
763 double result = 0;
764 for (std::size_t i = 0; i != maximal_level; ++i) {
765 result += compute_inner_product(l1, l2, i);
766 }
767 return result;
768 }
769
775 std::size_t level)
776 {
777 // TODO: replace with a GUDHI_CHECK?
778 if (!check_if_defined_on_the_same_domain(l1, l2))
779 throw std::invalid_argument("Landscapes are not defined on the same grid, the program will now terminate");
780
781 double result = 0;
782
783 double dx = (l1.grid_max_ - l1.grid_min_) / static_cast<double>(l1.values_of_landscapes_.size() - 1);
784
785 double previous_x = l1.grid_min_ - dx;
786 double previous_y_l1 = 0;
787 double previous_y_l2 = 0;
788 for (std::size_t i = 0; i != l1.values_of_landscapes_.size(); ++i) {
789#ifdef DEBUG_TRACES
790 std::clog << "i : " << i << std::endl;
791#endif
792
793 double current_x = previous_x + dx;
794 double current_y_l1 = 0;
795 if (l1.values_of_landscapes_[i].size() > level) current_y_l1 = l1.values_of_landscapes_[i][level];
796
797 double current_y_l2 = 0;
798 if (l2.values_of_landscapes_[i].size() > level) current_y_l2 = l2.values_of_landscapes_[i][level];
799
800#ifdef DEBUG_TRACES
801 std::clog << "previous_x : " << previous_x << std::endl;
802 std::clog << "previous_y_l1 : " << previous_y_l1 << std::endl;
803 std::clog << "current_y_l1 : " << current_y_l1 << std::endl;
804 std::clog << "previous_y_l2 : " << previous_y_l2 << std::endl;
805 std::clog << "current_y_l2 : " << current_y_l2 << std::endl;
806#endif
807
808 std::pair<double, double> l1_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l1),
809 std::make_pair(current_x, current_y_l1));
810 std::pair<double, double> l2_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l2),
811 std::make_pair(current_x, current_y_l2));
812
813 // let us assume that the first line is of a form y = ax+b, and the second one is of a form y = cx + d. Then here
814 // are a,b,c,d:
815 double a = l1_coords.first;
816 double b = l1_coords.second;
817
818 double c = l2_coords.first;
819 double d = l2_coords.second;
820
821#ifdef DEBUG_TRACES
822 std::clog << "Here are the formulas for a line: \n";
823 std::clog << "a : " << a << std::endl;
824 std::clog << "b : " << b << std::endl;
825 std::clog << "c : " << c << std::endl;
826 std::clog << "d : " << d << std::endl;
827#endif
828
829 // now, to compute the inner product in this interval we need to compute the integral of (ax+b)(cx+d) = acx^2 +
830 // (ad+bc)x + bd in the interval from previous_x to current_x:
831 // The integral is ac/3*x^3 + (ac+bd)/2*x^2 + bd*x
832
833 double added_value = (a * c / 3 * current_x * current_x * current_x +
834 (a * d + b * c) / 2 * current_x * current_x + b * d * current_x) -
835 (a * c / 3 * previous_x * previous_x * previous_x +
836 (a * d + b * c) / 2 * previous_x * previous_x + b * d * previous_x);
837
838#ifdef DEBUG_TRACES
839 std::clog << "Value of the integral on the left end i.e. : " << previous_x << " is : "
840 << a * c / 3 * previous_x * previous_x * previous_x + (a * d + b * c) / 2 * previous_x * previous_x +
841 b * d * previous_x
842 << std::endl;
843 std::clog << "Value of the integral on the right end i.e. : " << current_x << " is "
844 << a * c / 3 * current_x * current_x * current_x + (a * d + b * c) / 2 * current_x * current_x +
845 b * d * current_x
846 << std::endl;
847#endif
848
849 result += added_value;
850
851#ifdef DEBUG_TRACES
852 std::clog << "added_value : " << added_value << std::endl;
853 std::clog << "result : " << result << std::endl;
854#endif
855
856 previous_x = current_x;
857 previous_y_l1 = current_y_l1;
858 previous_y_l2 = current_y_l2;
859 }
860 return result;
861 }
862
873 const Persistence_landscape_on_grid& second,
874 double p)
875 {
876 // This is what we want to compute: (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p).
877 // We will do it one step at a time:
878
879#ifdef DEBUG_TRACES
880 std::clog << "first : " << first << std::endl;
881 std::clog << "second : " << second << std::endl;
882#endif
883
884 // first-second :
885 Persistence_landscape_on_grid lan = first - second;
886
887#ifdef DEBUG_TRACES
888 std::clog << "Difference : " << lan << std::endl;
889#endif
890
891 //| first-second |:
892 lan.abs();
893
894#ifdef DEBUG_TRACES
895 std::clog << "Abs : " << lan << std::endl;
896#endif
897
898 if (p < std::numeric_limits<double>::max()) {
899 // \int_{- \infty}^{+\infty}| first-second |^p
900 double result;
901 if (p != 1) {
902#ifdef DEBUG_TRACES
903 std::clog << "p : " << p << std::endl;
904#endif
905 result = lan.compute_integral_of_landscape(p);
906#ifdef DEBUG_TRACES
907 std::clog << "integral : " << result << std::endl;
908#endif
909 } else {
910 result = lan.compute_integral_of_landscape();
911#ifdef DEBUG_TRACES
912 std::clog << "integral, without power : " << result << std::endl;
913#endif
914 }
915 // (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p)
916 return std::pow(result, 1.0 / p);
917 } else {
918 // p == infty
919 return lan.compute_maximum();
920 }
921 }
922
923 // Functions that are needed for that class to implement the concept.
924
932 double project_to_R(int number_of_function) const
933 {
934 return this->compute_integral_of_landscape(static_cast<std::size_t>(number_of_function));
935 }
936
941 std::size_t number_of_projections_to_R() const { return number_of_functions_for_projections_to_reals_; }
942
947 std::vector<double> vectorize(int number_of_function) const
948 {
949 // TODO: GUDHI_CHECK instead?
950 // TODO(PD) think of something smarter over here
951 if (number_of_function < 0 || static_cast<std::size_t>(number_of_function) >= this->values_of_landscapes_.size()) {
952 throw std::invalid_argument("Wrong number of function.");
953 }
954 std::vector<double> v(this->values_of_landscapes_.size());
955 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
956 v[i] = 0;
957 if (this->values_of_landscapes_[i].size() > static_cast<std::size_t>(number_of_function)) {
958 v[i] = this->values_of_landscapes_[i][number_of_function];
959 }
960 }
961 return v;
962 }
963
968 std::size_t number_of_vectorize_functions() const { return number_of_functions_for_vectorization_; }
969
974 void compute_average(const std::vector<Persistence_landscape_on_grid*>& to_average)
975 {
976 // After execution of this procedure, the average is supposed to be in the current object. To make sure that this is
977 // the case, we need to do some cleaning first.
978 this->values_of_landscapes_.clear();
979 this->grid_min_ = this->grid_max_ = 0;
980
981 // if there is nothing to average, then the average is a zero landscape.
982 if (to_average.size() == 0) return;
983
984 // now we need to check if the grids in all objects of to_average are the same:
985 for (std::size_t i = 0; i != to_average.size(); ++i) {
986 if (!check_if_defined_on_the_same_domain(*(to_average[0]), *(to_average[i])))
987 throw "Two grids are not compatible";
988 }
989
990 this->values_of_landscapes_ = std::vector<std::vector<double> >((to_average[0])->values_of_landscapes_.size());
991 this->grid_min_ = (to_average[0])->grid_min_;
992 this->grid_max_ = (to_average[0])->grid_max_;
993
994#ifdef DEBUG_TRACES
995 std::clog << "Computations of average. The data from the current landscape have been cleared. We are ready to do "
996 "the computations. \n";
997#endif
998
999 // for every point in the grid:
1000 for (std::size_t grid_point = 0; grid_point != (to_average[0])->values_of_landscapes_.size(); ++grid_point) {
1001 // set up a vector of the correct size:
1002 std::size_t maximal_size_of_vector = 0;
1003 for (std::size_t land_no = 0; land_no != to_average.size(); ++land_no) {
1004 if ((to_average[land_no])->values_of_landscapes_[grid_point].size() > maximal_size_of_vector)
1005 maximal_size_of_vector = (to_average[land_no])->values_of_landscapes_[grid_point].size();
1006 }
1007 this->values_of_landscapes_[grid_point] = std::vector<double>(maximal_size_of_vector);
1008
1009#ifdef DEBUG_TRACES
1010 std::clog << "We are considering the point : " << grid_point
1011 << " of the grid. In this point, there are at most : " << maximal_size_of_vector
1012 << " nonzero landscape functions \n";
1013#endif
1014
1015 // and compute an arithmetic average:
1016 for (std::size_t land_no = 0; land_no != to_average.size(); ++land_no) {
1017 // summing:
1018 for (std::size_t i = 0; i != (to_average[land_no])->values_of_landscapes_[grid_point].size(); ++i) {
1019 // compute the average in a smarter way.
1020 this->values_of_landscapes_[grid_point][i] += (to_average[land_no])->values_of_landscapes_[grid_point][i];
1021 }
1022 }
1023 // normalizing:
1024 for (std::size_t i = 0; i != this->values_of_landscapes_[grid_point].size(); ++i) {
1025 this->values_of_landscapes_[grid_point][i] /= static_cast<double>(to_average.size());
1026 }
1027 }
1028 } // compute_average
1029
1036 double distance(const Persistence_landscape_on_grid& second, double power = 1) const
1037 {
1038 if (power < std::numeric_limits<double>::max()) {
1039 return compute_distance_of_landscapes_on_grid(*this, second, power);
1040 } else {
1041 return compute_max_norm_distance_of_landscapes(*this, second);
1042 }
1043 }
1044
1051 {
1052 return compute_inner_product((*this), second);
1053 }
1054
1055 // end of implementation of functions needed for concepts.
1056
1060 std::vector<std::vector<double> > output_for_visualization() const { return this->values_of_landscapes_; }
1061
1070 void plot(const char* filename, std::size_t from, std::size_t to) const
1071 {
1072 this->plot(filename,
1073 std::numeric_limits<double>::max(),
1074 std::numeric_limits<double>::max(),
1075 std::numeric_limits<double>::max(),
1076 std::numeric_limits<double>::max(),
1077 from,
1078 to);
1079 }
1080
1085 void plot(const char* filename,
1086 double min_x = std::numeric_limits<double>::max(),
1087 double max_x = std::numeric_limits<double>::max(),
1088 double min_y = std::numeric_limits<double>::max(),
1089 double max_y = std::numeric_limits<double>::max(),
1090 std::size_t from = std::numeric_limits<std::size_t>::max(),
1091 std::size_t to = std::numeric_limits<std::size_t>::max()) const;
1092
1093 private:
1094 double grid_min_;
1095 double grid_max_;
1096 std::vector<std::vector<double> > values_of_landscapes_;
1097 std::size_t number_of_functions_for_vectorization_;
1098 std::size_t number_of_functions_for_projections_to_reals_;
1099
1100 void _set_up_values_of_landscapes(const std::vector<std::pair<double, double> >& p,
1101 double grid_min,
1102 double grid_max,
1103 std::size_t number_of_points,
1104 unsigned number_of_levels = std::numeric_limits<unsigned>::max());
1105 Persistence_landscape_on_grid _multiply_landscape_by_real_number_not_overwrite(double x) const;
1106};
1107
1108inline void Persistence_landscape_on_grid::_set_up_values_of_landscapes(
1109 const std::vector<std::pair<double, double> >& p,
1110 double grid_min,
1111 double grid_max,
1112 std::size_t number_of_points,
1113 unsigned number_of_levels)
1114{
1115#ifdef DEBUG_TRACES
1116 std::clog << "Here is the procedure : set_up_values_of_landscapes. The parameters are : grid_min_ : " << grid_min
1117 << ", grid_max_ : " << grid_max << ", number_of_points_ : " << number_of_points
1118 << ", number_of_levels: " << number_of_levels << std::endl;
1119 std::clog << "Here are the intervals at our disposal : \n";
1120 for (std::size_t i = 0; i != p.size(); ++i) {
1121 std::clog << p[i].first << " , " << p[i].second << std::endl;
1122 }
1123#endif
1124
1125 if ((grid_min == std::numeric_limits<double>::max()) || (grid_max == std::numeric_limits<double>::max())) {
1126 // in this case, we need to find grid_min_ and grid_min_ based on the data.
1127 double min = std::numeric_limits<double>::max();
1128 double max = std::numeric_limits<double>::min();
1129 for (std::size_t i = 0; i != p.size(); ++i) {
1130 if (p[i].first < min) min = p[i].first;
1131 if (p[i].second > max) max = p[i].second;
1132 }
1133 if (grid_min == std::numeric_limits<double>::max()) {
1134 grid_min = min;
1135 } else {
1136 // in this case grid_max_ == std::numeric_limits<double>::max()
1137 grid_max = max;
1138 }
1139 }
1140
1141 // if number_of_levels == std::numeric_limits<std::size_t>::max(), then we will have all the nonzero values of
1142 // landscapes, and will store them in a vector if number_of_levels != std::numeric_limits<std::size_t>::max(), then we
1143 // will use those vectors as heaps.
1144 this->values_of_landscapes_ = std::vector<std::vector<double> >(number_of_points + 1);
1145
1146 this->grid_min_ = grid_min;
1147 this->grid_max_ = grid_max;
1148
1149 if (grid_max <= grid_min) {
1150 throw std::invalid_argument(
1151 "Wrong parameters of grid_min and grid_max given to the procedure. The program will now terminate.");
1152 }
1153
1154 double dx = (grid_max - grid_min) / static_cast<double>(number_of_points);
1155 // for every interval in the diagram:
1156 for (std::size_t int_no = 0; int_no != p.size(); ++int_no) {
1157 std::size_t grid_interval_begin = (p[int_no].first - grid_min) / dx;
1158 std::size_t grid_interval_end = (p[int_no].second - grid_min) / dx;
1159 std::size_t grid_interval_midpoint = (std::size_t)(0.5 * (grid_interval_begin + grid_interval_end));
1160
1161#ifdef DEBUG_TRACES
1162 std::clog << "Considering an interval : " << p[int_no].first << "," << p[int_no].second << std::endl;
1163
1164 std::clog << "grid_interval_begin : " << grid_interval_begin << std::endl;
1165 std::clog << "grid_interval_end : " << grid_interval_end << std::endl;
1166 std::clog << "grid_interval_midpoint : " << grid_interval_midpoint << std::endl;
1167#endif
1168
1169 double landscape_value = dx;
1170 for (std::size_t i = grid_interval_begin + 1; i < grid_interval_midpoint; ++i) {
1171#ifdef DEBUG_TRACES
1172 std::clog << "Adding landscape value (going up) for a point : " << i << " equal : " << landscape_value
1173 << std::endl;
1174#endif
1175 if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1176 // we have a heap of no more that number_of_levels values.
1177 // Note that if we are using heaps, we want to know the shortest distance in the heap.
1178 // This is achieved by putting -distance to the heap.
1179 if (this->values_of_landscapes_[i].size() >= number_of_levels) {
1180 // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
1181 // smallest element in the heap.
1182 if (-landscape_value < this->values_of_landscapes_[i].front()) {
1183 // if it is, we remove the largest value in the heap, and move on.
1184 std::pop_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1185 this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1] = -landscape_value;
1186 std::push_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1187 }
1188 } else {
1189 // in this case we are still filling in the array.
1190 this->values_of_landscapes_[i].push_back(-landscape_value);
1191 if (this->values_of_landscapes_[i].size() == number_of_levels - 1) {
1192 // this->values_of_landscapes[i].size() == number_of_levels
1193 // in this case we need to create the heap.
1194 std::make_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1195 }
1196 }
1197 } else {
1198 // we have vector of all values
1199 this->values_of_landscapes_[i].push_back(landscape_value);
1200 }
1201 landscape_value += dx;
1202 }
1203 for (std::size_t i = grid_interval_midpoint; i <= grid_interval_end; ++i) {
1204 if (landscape_value > 0) {
1205 if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1206 // we have a heap of no more that number_of_levels values
1207 if (this->values_of_landscapes_[i].size() >= number_of_levels) {
1208 // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
1209 // smallest element in the heap.
1210 if (-landscape_value < this->values_of_landscapes_[i].front()) {
1211 // if it is, we remove the largest value in the heap, and move on.
1212 std::pop_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1213 this->values_of_landscapes_[i][this->values_of_landscapes_[i].size() - 1] = -landscape_value;
1214 std::push_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1215 }
1216 } else {
1217 // in this case we are still filling in the array.
1218 this->values_of_landscapes_[i].push_back(-landscape_value);
1219 if (this->values_of_landscapes_[i].size() == number_of_levels - 1) {
1220 // this->values_of_landscapes[i].size() == number_of_levels
1221 // in this case we need to create the heap.
1222 std::make_heap(this->values_of_landscapes_[i].begin(), this->values_of_landscapes_[i].end());
1223 }
1224 }
1225 } else {
1226 this->values_of_landscapes_[i].push_back(landscape_value);
1227 }
1228
1229#ifdef DEBUG_TRACES
1230 std::clog << "Adding landscape value (going down) for a point : " << i << " equal : " << landscape_value
1231 << std::endl;
1232#endif
1233 }
1234 landscape_value -= dx;
1235 }
1236 }
1237
1238 if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1239 // in this case, vectors are used as heaps. And, since we want to have the smallest element at the top of
1240 // each heap, we store minus distances. To get if right at the end, we need to multiply each value
1241 // in the heap by -1 to get real vector of distances.
1242 for (std::size_t pt = 0; pt != this->values_of_landscapes_.size(); ++pt) {
1243 for (std::size_t j = 0; j != this->values_of_landscapes_[pt].size(); ++j) {
1244 this->values_of_landscapes_[pt][j] *= -1;
1245 }
1246 }
1247 }
1248
1249 // and now we need to sort the values:
1250 for (std::size_t pt = 0; pt != this->values_of_landscapes_.size(); ++pt) {
1251 std::sort(this->values_of_landscapes_[pt].begin(), this->values_of_landscapes_[pt].end(), std::greater<double>());
1252 }
1253} // set_up_values_of_landscapes
1254
1256{
1257 std::ifstream in;
1258 in.open(filename);
1259 // check if the file exist.
1260 if (!in.good()) {
1261#ifdef DEBUG_TRACES
1262 std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n";
1263#endif
1264 throw std::invalid_argument("The persistence landscape file do not exist.");
1265 }
1266
1267 std::size_t number_of_points_in_the_grid = 0;
1268 in >> this->grid_min_ >> this->grid_max_ >> number_of_points_in_the_grid;
1269
1270 std::vector<std::vector<double> > v(number_of_points_in_the_grid);
1271 std::string line;
1272 std::getline(in, line);
1273 double number;
1274 for (std::size_t i = 0; i != number_of_points_in_the_grid; ++i) {
1275 // read a line of a file and convert it to a vector.
1276 std::getline(in, line);
1277 std::istringstream stream(line);
1278 while (stream >> number) {
1279 v[i].push_back(number);
1280 }
1281 }
1282 this->values_of_landscapes_ = v;
1283 in.close();
1284}
1285
1286inline void Persistence_landscape_on_grid::print_to_file(const char* filename) const
1287{
1288 std::ofstream out;
1289 out.open(filename);
1290
1291 // first we store the parameters of the grid:
1292 out << grid_min_ << std::endl << grid_max_ << std::endl << this->values_of_landscapes_.size() << std::endl;
1293
1294 // and now in the following lines, the values of this->values_of_landscapes for the following arguments:
1295 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
1296 for (std::size_t j = 0; j != this->values_of_landscapes_[i].size(); ++j) {
1297 out << this->values_of_landscapes_[i][j] << " ";
1298 }
1299 out << std::endl;
1300 }
1301
1302 out.close();
1303}
1304
1305inline void Persistence_landscape_on_grid::plot(const char* filename,
1306 double min_x,
1307 double max_x,
1308 double min_y,
1309 double max_y,
1310 std::size_t from_,
1311 std::size_t to_) const
1312{
1313 // this program create a gnuplot script file that allows to plot persistence diagram.
1314 std::ofstream out;
1315
1316 std::ostringstream gnuplot_script;
1317 gnuplot_script << filename << "_GnuplotScript";
1318 out.open(gnuplot_script.str().c_str());
1319
1320 if (min_x == max_x) {
1321 std::pair<double, double> min_max = compute_minimum_maximum();
1322 out << "set xrange [" << this->grid_min_ << " : " << this->grid_max_ << "]" << std::endl;
1323 out << "set yrange [" << min_max.first << " : " << min_max.second << "]" << std::endl;
1324 } else {
1325 out << "set xrange [" << min_x << " : " << max_x << "]" << std::endl;
1326 out << "set yrange [" << min_y << " : " << max_y << "]" << std::endl;
1327 }
1328
1330 double dx = (this->grid_max_ - this->grid_min_) / static_cast<double>(this->values_of_landscapes_.size() - 1);
1331
1332 std::size_t from = 0;
1333 if (from_ != std::numeric_limits<std::size_t>::max()) {
1334 if (from_ < number_of_nonzero_levels) {
1335 from = from_;
1336 } else {
1337 return;
1338 }
1339 }
1340 std::size_t to = number_of_nonzero_levels;
1341 if (to_ != std::numeric_limits<std::size_t>::max()) {
1342 if (to_ < number_of_nonzero_levels) {
1343 to = to_;
1344 }
1345 }
1346
1347 out << "plot ";
1348 for (std::size_t lambda = from; lambda != to; ++lambda) {
1349 out << " '-' using 1:2 notitle with lp";
1350 if (lambda + 1 != to) {
1351 out << ", \\";
1352 }
1353 out << std::endl;
1354 }
1355
1356 for (std::size_t lambda = from; lambda != to; ++lambda) {
1357 double point = this->grid_min_;
1358 for (std::size_t i = 0; i != this->values_of_landscapes_.size(); ++i) {
1359 double value = 0;
1360 if (this->values_of_landscapes_[i].size() > lambda) {
1361 value = this->values_of_landscapes_[i][lambda];
1362 }
1363 out << point << " " << value << std::endl;
1364 point += dx;
1365 }
1366 out << "EOF" << std::endl;
1367 }
1368#ifdef DEBUG_TRACES
1369 std::clog << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
1370 << gnuplot_script.str().c_str() << "\'\"" << std::endl;
1371#endif
1372}
1373
1374inline Persistence_landscape_on_grid Persistence_landscape_on_grid::_multiply_landscape_by_real_number_not_overwrite(
1375 double x) const
1376{
1378 result.values_of_landscapes_ = std::vector<std::vector<double> >(this->values_of_landscapes_.size());
1379 result.grid_min_ = this->grid_min_;
1380 result.grid_max_ = this->grid_max_;
1381
1382 for (std::size_t grid_point = 0; grid_point != this->values_of_landscapes_.size(); ++grid_point) {
1383 result.values_of_landscapes_[grid_point] = std::vector<double>(this->values_of_landscapes_[grid_point].size());
1384 for (std::size_t i = 0; i != this->values_of_landscapes_[grid_point].size(); ++i) {
1385 result.values_of_landscapes_[grid_point][i] = x * this->values_of_landscapes_[grid_point][i];
1386 }
1387 }
1388
1389 return result;
1390}
1391
1392} // namespace Persistence_representations
1393} // namespace Gudhi
1394
1395#endif // PERSISTENCE_LANDSCAPE_ON_GRID_H_
A class implementing persistence landscapes by approximating them on a collection of grid points.
Definition Persistence_landscape_on_grid.h:63
std::size_t size() const
Definition Persistence_landscape_on_grid.h:738
void print_to_file(const char *filename) const
Definition Persistence_landscape_on_grid.h:1286
bool operator!=(const Persistence_landscape_on_grid &rhs) const
Definition Persistence_landscape_on_grid.h:595
friend Persistence_landscape_on_grid operator-(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition Persistence_landscape_on_grid.h:495
Persistence_landscape_on_grid(const char *filename, double grid_min, double grid_max, std::size_t number_of_points, std::uint16_t dimension=std::numeric_limits< std::uint16_t >::max())
Definition Persistence_landscape_on_grid.h:130
double compute_integral_of_landscape() const
Definition Persistence_landscape_on_grid.h:213
Persistence_landscape_on_grid(const std::vector< std::pair< double, double > > &p, double grid_min, double grid_max, std::size_t number_of_points)
Definition Persistence_landscape_on_grid.h:78
std::vector< std::vector< double > > output_for_visualization() const
Definition Persistence_landscape_on_grid.h:1060
void plot(const char *filename, std::size_t from, std::size_t to) const
Definition Persistence_landscape_on_grid.h:1070
void load_landscape_from_file(const char *filename)
Definition Persistence_landscape_on_grid.h:1255
std::size_t number_of_vectorize_functions() const
Definition Persistence_landscape_on_grid.h:968
Persistence_landscape_on_grid operator-=(const Persistence_landscape_on_grid &rhs)
Definition Persistence_landscape_on_grid.h:529
Persistence_landscape_on_grid(const char *filename, std::size_t number_of_points, unsigned number_of_levels_of_landscape, std::uint16_t dimension=std::numeric_limits< std::uint16_t >::max())
Definition Persistence_landscape_on_grid.h:152
std::vector< double > vectorize(int number_of_function) const
Definition Persistence_landscape_on_grid.h:947
std::pair< double, double > get_x_range(std::size_t level=0) const
Definition Persistence_landscape_on_grid.h:642
std::pair< double, double > compute_minimum_maximum() const
Definition Persistence_landscape_on_grid.h:618
std::size_t number_of_projections_to_R() const
Definition Persistence_landscape_on_grid.h:941
std::size_t number_of_nonzero_levels() const
Definition Persistence_landscape_on_grid.h:656
Persistence_landscape_on_grid(const char *filename, std::size_t number_of_points, std::uint16_t dimension=std::numeric_limits< std::uint16_t >::max())
Definition Persistence_landscape_on_grid.h:180
friend Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid &land1, const Persistence_landscape_on_grid &land2)
Definition Persistence_landscape_on_grid.h:427
double compute_integral_of_landscape(double p, std::size_t level) const
Definition Persistence_landscape_on_grid.h:280
Persistence_landscape_on_grid operator+=(const Persistence_landscape_on_grid &rhs)
Definition Persistence_landscape_on_grid.h:520
double compute_scalar_product(const Persistence_landscape_on_grid &second)
Definition Persistence_landscape_on_grid.h:1050
double operator()(unsigned int level, double x) const
Definition Persistence_landscape_on_grid.h:683
Persistence_landscape_on_grid operator/=(double x)
Definition Persistence_landscape_on_grid.h:548
friend Persistence_landscape_on_grid operator*(double con, const Persistence_landscape_on_grid &first)
Definition Persistence_landscape_on_grid.h:512
double compute_integral_of_landscape(std::size_t level) const
Definition Persistence_landscape_on_grid.h:226
friend Persistence_landscape_on_grid operator+(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition Persistence_landscape_on_grid.h:486
Persistence_landscape_on_grid(const char *filename, double grid_min, double grid_max, std::size_t number_of_points, unsigned number_of_levels_of_landscape, std::uint16_t dimension=std::numeric_limits< std::uint16_t >::max())
Definition Persistence_landscape_on_grid.h:107
friend double compute_max_norm_distance_of_landscapes(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition Persistence_landscape_on_grid.h:688
double find_max(unsigned lambda) const
Definition Persistence_landscape_on_grid.h:743
double distance(const Persistence_landscape_on_grid &second, double power=1) const
Definition Persistence_landscape_on_grid.h:1036
friend double compute_inner_product(const Persistence_landscape_on_grid &l1, const Persistence_landscape_on_grid &l2)
Definition Persistence_landscape_on_grid.h:757
friend Persistence_landscape_on_grid operator*(const Persistence_landscape_on_grid &first, double con)
Definition Persistence_landscape_on_grid.h:504
friend Persistence_landscape_on_grid subtract_two_landscapes(const Persistence_landscape_on_grid &land1, const Persistence_landscape_on_grid &land2)
Definition Persistence_landscape_on_grid.h:477
double compute_maximum() const
Definition Persistence_landscape_on_grid.h:600
void compute_average(const std::vector< Persistence_landscape_on_grid * > &to_average)
Definition Persistence_landscape_on_grid.h:974
double compute_value_at_a_given_point(unsigned level, double x) const
Definition Persistence_landscape_on_grid.h:364
Persistence_landscape_on_grid(const std::vector< std::pair< double, double > > &p, double grid_min, double grid_max, std::size_t number_of_points, unsigned number_of_levels_of_landscape)
Definition Persistence_landscape_on_grid.h:90
bool operator==(const Persistence_landscape_on_grid &rhs) const
Definition Persistence_landscape_on_grid.h:558
double project_to_R(int number_of_function) const
Definition Persistence_landscape_on_grid.h:932
double compute_integral_of_landscape(double p) const
Definition Persistence_landscape_on_grid.h:266
void abs()
Definition Persistence_landscape_on_grid.h:726
friend std::ostream & operator<<(std::ostream &out, const Persistence_landscape_on_grid &land)
Definition Persistence_landscape_on_grid.h:344
double compute_norm_of_landscape(double i) const
Definition Persistence_landscape_on_grid.h:668
std::pair< double, double > get_y_range(std::size_t level=0) const
Definition Persistence_landscape_on_grid.h:651
friend double compute_inner_product(const Persistence_landscape_on_grid &l1, const Persistence_landscape_on_grid &l2, std::size_t level)
Definition Persistence_landscape_on_grid.h:773
friend double compute_distance_of_landscapes_on_grid(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second, double p)
Computations of distance between two landscapes on a grid. p is the parameter of the procedure.
Definition Persistence_landscape_on_grid.h:872
Persistence_landscape_on_grid operator*=(double x)
Definition Persistence_landscape_on_grid.h:539
Persistence_landscape_on_grid()
Definition Persistence_landscape_on_grid.h:68
friend Persistence_landscape_on_grid add_two_landscapes(const Persistence_landscape_on_grid &land1, const Persistence_landscape_on_grid &land2)
Definition Persistence_landscape_on_grid.h:468
This file contain an implementation of some common procedures used in the Persistence_representations...
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
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