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  * - YYYY/MM Author: Description of the modification
9  */
10 
11 #ifndef PERSISTENCE_LANDSCAPE_ON_GRID_H_
12 #define PERSISTENCE_LANDSCAPE_ON_GRID_H_
13 
14 // gudhi include
15 #include <gudhi/read_persistence_from_file.h>
16 #include <gudhi/common_persistence_representations.h>
17 
18 // standard include
19 #include <iostream>
20 #include <vector>
21 #include <limits>
22 #include <fstream>
23 #include <sstream>
24 #include <algorithm>
25 #include <cmath>
26 #include <functional>
27 #include <utility>
28 #include <string>
29 #include <cstdint>
30 
31 namespace Gudhi {
32 namespace Persistence_representations {
33 
34 // pre declaration
36 template <typename operation>
37 Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid& land1,
38  const Persistence_landscape_on_grid& land2);
39 
57 // this class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances,
58 // Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product
60  public:
65  this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
66  this->grid_min = this->grid_max = 0;
67  }
68 
72  Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
73  size_t number_of_points_);
74 
79  Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
80  size_t number_of_points_, unsigned number_of_levels_of_landscape);
81 
90  Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_,
91  unsigned number_of_levels_of_landscape,
92  uint16_t dimension_ = std::numeric_limits<uint16_t>::max());
93 
101  Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_,
102  uint16_t dimension_ = std::numeric_limits<uint16_t>::max());
103 
111  Persistence_landscape_on_grid(const char* filename, size_t number_of_points, unsigned number_of_levels_of_landscape,
112  uint16_t dimension = std::numeric_limits<uint16_t>::max());
113 
123  Persistence_landscape_on_grid(const char* filename, size_t number_of_points,
124  uint16_t dimension = std::numeric_limits<uint16_t>::max());
125 
129  void load_landscape_from_file(const char* filename);
130 
134  void print_to_file(const char* filename) const;
135 
141  size_t maximal_level = this->number_of_nonzero_levels();
142  double result = 0;
143  for (size_t i = 0; i != maximal_level; ++i) {
144  result += this->compute_integral_of_landscape(i);
145  }
146  return result;
147  }
148 
152  double compute_integral_of_landscape(size_t level) const {
153  bool dbg = false;
154  double result = 0;
155  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
156 
157  if (dbg) {
158  std::clog << "this->grid_max : " << this->grid_max << std::endl;
159  std::clog << "this->grid_min : " << this->grid_min << std::endl;
160  std::clog << "this->values_of_landscapes.size() : " << this->values_of_landscapes.size() << std::endl;
161  getchar();
162  }
163 
164  double previous_x = this->grid_min - dx;
165  double previous_y = 0;
166  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
167  double current_x = previous_x + dx;
168  double current_y = 0;
169  if (this->values_of_landscapes[i].size() > level) current_y = this->values_of_landscapes[i][level];
170 
171  if (dbg) {
172  std::clog << "this->values_of_landscapes[i].size() : " << this->values_of_landscapes[i].size()
173  << " , level : " << level << std::endl;
174  if (this->values_of_landscapes[i].size() > level)
175  std::clog << "this->values_of_landscapes[i][level] : " << this->values_of_landscapes[i][level] << std::endl;
176  std::clog << "previous_y : " << previous_y << std::endl;
177  std::clog << "current_y : " << current_y << std::endl;
178  std::clog << "dx : " << dx << std::endl;
179  std::clog << "0.5*dx*( previous_y + current_y ); " << 0.5 * dx * (previous_y + current_y) << std::endl;
180  }
181 
182  result += 0.5 * dx * (previous_y + current_y);
183  previous_x = current_x;
184  previous_y = current_y;
185  }
186  return result;
187  }
188 
193  double compute_integral_of_landscape(double p) const {
194  size_t maximal_level = this->number_of_nonzero_levels();
195  double result = 0;
196  for (size_t i = 0; i != maximal_level; ++i) {
197  result += this->compute_integral_of_landscape(p, i);
198  }
199  return result;
200  }
201 
206  double compute_integral_of_landscape(double p, size_t level) const {
207  bool dbg = false;
208 
209  double result = 0;
210  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
211  double previous_x = this->grid_min;
212  double previous_y = 0;
213  if (this->values_of_landscapes[0].size() > level) previous_y = this->values_of_landscapes[0][level];
214 
215  if (dbg) {
216  std::clog << "dx : " << dx << std::endl;
217  std::clog << "previous_x : " << previous_x << std::endl;
218  std::clog << "previous_y : " << previous_y << std::endl;
219  std::clog << "power : " << p << std::endl;
220  getchar();
221  }
222 
223  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
224  double current_x = previous_x + dx;
225  double current_y = 0;
226  if (this->values_of_landscapes[i].size() > level) current_y = this->values_of_landscapes[i][level];
227 
228  if (dbg) std::clog << "current_y : " << current_y << std::endl;
229 
230  if (current_y == previous_y) continue;
231 
232  std::pair<double, double> coef =
233  compute_parameters_of_a_line(std::make_pair(previous_x, previous_y), std::make_pair(current_x, current_y));
234  double a = coef.first;
235  double b = coef.second;
236 
237  if (dbg) {
238  std::clog << "A line passing through points : (" << previous_x << "," << previous_y << ") and (" << current_x
239  << "," << current_y << ") is : " << a << "x+" << b << std::endl;
240  }
241 
242  // In this interval, the landscape has a form f(x) = ax+b. We want to compute integral of (ax+b)^p = 1/a *
243  // (ax+b)^{p+1}/(p+1)
244  double value_to_add = 0;
245  if (a != 0) {
246  value_to_add = 1 / (a * (p + 1)) * (pow((a * current_x + b), p + 1) - pow((a * previous_x + b), p + 1));
247  } else {
248  value_to_add = (current_x - previous_x) * (pow(b, p));
249  }
250  result += value_to_add;
251  if (dbg) {
252  std::clog << "Increasing result by : " << value_to_add << std::endl;
253  std::clog << "result : " << result << std::endl;
254  getchar();
255  }
256  previous_x = current_x;
257  previous_y = current_y;
258  }
259  if (dbg) std::clog << "The total result is : " << result << std::endl;
260  return result;
261  }
262 
268  friend std::ostream& operator<<(std::ostream& out, const Persistence_landscape_on_grid& land) {
269  double dx = (land.grid_max - land.grid_min) / static_cast<double>(land.values_of_landscapes.size() - 1);
270  double x = land.grid_min;
271  for (size_t i = 0; i != land.values_of_landscapes.size(); ++i) {
272  out << x << " : ";
273  for (size_t j = 0; j != land.values_of_landscapes[i].size(); ++j) {
274  out << land.values_of_landscapes[i][j] << " ";
275  }
276  out << std::endl;
277  x += dx;
278  }
279  return out;
280  }
281 
282  template <typename oper>
283  friend Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(
285 
291  double compute_value_at_a_given_point(unsigned level, double x) const {
292  bool dbg = false;
293  if ((x < this->grid_min) || (x > this->grid_max)) return 0;
294 
295  // find a position of a vector closest to x:
296  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
297  size_t position = size_t((x - this->grid_min) / dx);
298 
299  if (dbg) {
300  std::clog << "This is a procedure compute_value_at_a_given_point \n";
301  std::clog << "level : " << level << std::endl;
302  std::clog << "x : " << x << std::endl;
303  std::clog << "position : " << position << std::endl;
304  }
305  // check if we are not exactly in the grid point:
306  if (almost_equal(position * dx + this->grid_min, x)) {
307  if (this->values_of_landscapes[position].size() < level) {
308  return this->values_of_landscapes[position][level];
309  } else {
310  return 0;
311  }
312  }
313  // in the other case, approximate with a line:
314  std::pair<double, double> line;
315  if ((this->values_of_landscapes[position].size() > level) &&
316  (this->values_of_landscapes[position + 1].size() > level)) {
317  line = compute_parameters_of_a_line(
318  std::make_pair(position * dx + this->grid_min, this->values_of_landscapes[position][level]),
319  std::make_pair((position + 1) * dx + this->grid_min, this->values_of_landscapes[position + 1][level]));
320  } else {
321  if ((this->values_of_landscapes[position].size() > level) ||
322  (this->values_of_landscapes[position + 1].size() > level)) {
323  if ((this->values_of_landscapes[position].size() > level)) {
324  line = compute_parameters_of_a_line(
325  std::make_pair(position * dx + this->grid_min, this->values_of_landscapes[position][level]),
326  std::make_pair((position + 1) * dx + this->grid_min, 0));
327  } else {
328  line = compute_parameters_of_a_line(
329  std::make_pair(position * dx + this->grid_min, 0),
330  std::make_pair((position + 1) * dx + this->grid_min, this->values_of_landscapes[position + 1][level]));
331  }
332  } else {
333  return 0;
334  }
335  }
336  // compute the value of the linear function parametrized by line on a point x:
337  return line.first * x + line.second;
338  }
339 
340  public:
345  const Persistence_landscape_on_grid& land2) {
346  return operation_on_pair_of_landscapes_on_grid<std::plus<double> >(land1, land2);
347  }
348 
353  const Persistence_landscape_on_grid& land2) {
354  return operation_on_pair_of_landscapes_on_grid<std::minus<double> >(land1, land2);
355  }
356 
361  const Persistence_landscape_on_grid& second) {
362  return add_two_landscapes(first, second);
363  }
364 
369  const Persistence_landscape_on_grid& second) {
370  return subtract_two_landscapes(first, second);
371  }
372 
377  return first.multiply_lanscape_by_real_number_not_overwrite(con);
378  }
379 
384  return first.multiply_lanscape_by_real_number_not_overwrite(con);
385  }
386 
387  friend bool check_if_defined_on_the_same_domain(const Persistence_landscape_on_grid& land1,
388  const Persistence_landscape_on_grid& land2) {
389  if (land1.values_of_landscapes.size() != land2.values_of_landscapes.size()) return false;
390  if (land1.grid_min != land2.grid_min) return false;
391  if (land1.grid_max != land2.grid_max) return false;
392  return true;
393  }
394 
399  *this = *this + rhs;
400  return *this;
401  }
402 
407  *this = *this - rhs;
408  return *this;
409  }
410 
416  *this = *this * x;
417  return *this;
418  }
419 
424  if (x == 0) throw("In operator /=, division by 0. Program terminated.");
425  *this = *this * (1 / x);
426  return *this;
427  }
428 
432  bool operator==(const Persistence_landscape_on_grid& rhs) const {
433  bool dbg = true;
434  if (this->values_of_landscapes.size() != rhs.values_of_landscapes.size()) {
435  if (dbg) std::clog << "values_of_landscapes of incompatible sizes\n";
436  return false;
437  }
438  if (!almost_equal(this->grid_min, rhs.grid_min)) {
439  if (dbg) std::clog << "grid_min not equal\n";
440  return false;
441  }
442  if (!almost_equal(this->grid_max, rhs.grid_max)) {
443  if (dbg) std::clog << "grid_max not equal\n";
444  return false;
445  }
446  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
447  for (size_t aa = 0; aa != this->values_of_landscapes[i].size(); ++aa) {
448  if (!almost_equal(this->values_of_landscapes[i][aa], rhs.values_of_landscapes[i][aa])) {
449  if (dbg) {
450  std::clog << "Problem in the position : " << i << " of values_of_landscapes. \n";
451  std::clog << this->values_of_landscapes[i][aa] << " " << rhs.values_of_landscapes[i][aa] << std::endl;
452  }
453  return false;
454  }
455  }
456  }
457  return true;
458  }
459 
463  bool operator!=(const Persistence_landscape_on_grid& rhs) const { return !((*this) == rhs); }
464 
468  double compute_maximum() const {
469  // since the function can only be entirely positive or negative, the maximal value will be an extremal value in the
470  // arrays:
471  double max_value = -std::numeric_limits<double>::max();
472  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
473  if (this->values_of_landscapes[i].size()) {
474  if (this->values_of_landscapes[i][0] > max_value) max_value = this->values_of_landscapes[i][0];
475  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] > max_value)
476  max_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
477  }
478  }
479  return max_value;
480  }
481 
485  std::pair<double, double> compute_minimum_maximum() const {
486  // since the function can only be entirely positive or negative, the maximal value will be an extremal value in the
487  // arrays:
488  double max_value = -std::numeric_limits<double>::max();
489  double min_value = 0;
490  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
491  if (this->values_of_landscapes[i].size()) {
492  if (this->values_of_landscapes[i][0] > max_value) max_value = this->values_of_landscapes[i][0];
493  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] > max_value)
494  max_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
495 
496  if (this->values_of_landscapes[i][0] < min_value) min_value = this->values_of_landscapes[i][0];
497  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] < min_value)
498  min_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
499  }
500  }
501  return std::make_pair(min_value, max_value);
502  }
503 
508  std::pair<double, double> get_x_range(size_t level = 0) const {
509  return std::make_pair(this->grid_min, this->grid_max);
510  }
511 
516  std::pair<double, double> get_y_range(size_t level = 0) const { return this->compute_minimum_maximum(); }
517 
521  size_t number_of_nonzero_levels() const {
522  size_t result = 0;
523  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
524  if (this->values_of_landscapes[i].size() > result) result = this->values_of_landscapes[i].size();
525  }
526  return result;
527  }
528 
532  double compute_norm_of_landscape(double i) const {
533  std::vector<std::pair<double, double> > p;
534  Persistence_landscape_on_grid l(p, this->grid_min, this->grid_max, this->values_of_landscapes.size() - 1);
535 
536  if (i < std::numeric_limits<double>::max()) {
537  return compute_distance_of_landscapes_on_grid(*this, l, i);
538  } else {
540  }
541  }
542 
546  double operator()(unsigned level, double x) const { return this->compute_value_at_a_given_point(level, x); }
547 
552  const Persistence_landscape_on_grid& second);
553 
560  void abs() {
561  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
562  for (size_t j = 0; j != this->values_of_landscapes[i].size(); ++j) {
563  this->values_of_landscapes[i][j] = std::abs(this->values_of_landscapes[i][j]);
564  }
565  }
566  }
567 
571  size_t size() const { return this->number_of_nonzero_levels(); }
572 
576  double find_max(unsigned lambda) const {
577  double max_value = -std::numeric_limits<double>::max();
578  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
579  if (this->values_of_landscapes[i].size() > lambda) {
580  if (this->values_of_landscapes[i][lambda] > max_value) max_value = this->values_of_landscapes[i][lambda];
581  }
582  }
583  return max_value;
584  }
585 
590  const Persistence_landscape_on_grid& l2) {
591  if (!check_if_defined_on_the_same_domain(l1, l2))
592  throw "Landscapes are not defined on the same grid, the program will now terminate";
593  size_t maximal_level = l1.number_of_nonzero_levels();
594  double result = 0;
595  for (size_t i = 0; i != maximal_level; ++i) {
596  result += compute_inner_product(l1, l2, i);
597  }
598  return result;
599  }
600 
605  size_t level) {
606  bool dbg = false;
607 
608  if (!check_if_defined_on_the_same_domain(l1, l2))
609  throw "Landscapes are not defined on the same grid, the program will now terminate";
610  double result = 0;
611 
612  double dx = (l1.grid_max - l1.grid_min) / static_cast<double>(l1.values_of_landscapes.size() - 1);
613 
614  double previous_x = l1.grid_min - dx;
615  double previous_y_l1 = 0;
616  double previous_y_l2 = 0;
617  for (size_t i = 0; i != l1.values_of_landscapes.size(); ++i) {
618  if (dbg) std::clog << "i : " << i << std::endl;
619 
620  double current_x = previous_x + dx;
621  double current_y_l1 = 0;
622  if (l1.values_of_landscapes[i].size() > level) current_y_l1 = l1.values_of_landscapes[i][level];
623 
624  double current_y_l2 = 0;
625  if (l2.values_of_landscapes[i].size() > level) current_y_l2 = l2.values_of_landscapes[i][level];
626 
627  if (dbg) {
628  std::clog << "previous_x : " << previous_x << std::endl;
629  std::clog << "previous_y_l1 : " << previous_y_l1 << std::endl;
630  std::clog << "current_y_l1 : " << current_y_l1 << std::endl;
631  std::clog << "previous_y_l2 : " << previous_y_l2 << std::endl;
632  std::clog << "current_y_l2 : " << current_y_l2 << std::endl;
633  }
634 
635  std::pair<double, double> l1_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l1),
636  std::make_pair(current_x, current_y_l1));
637  std::pair<double, double> l2_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l2),
638  std::make_pair(current_x, current_y_l2));
639 
640  // 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
641  // are a,b,c,d:
642  double a = l1_coords.first;
643  double b = l1_coords.second;
644 
645  double c = l2_coords.first;
646  double d = l2_coords.second;
647 
648  if (dbg) {
649  std::clog << "Here are the formulas for a line: \n";
650  std::clog << "a : " << a << std::endl;
651  std::clog << "b : " << b << std::endl;
652  std::clog << "c : " << c << std::endl;
653  std::clog << "d : " << d << std::endl;
654  }
655 
656  // now, to compute the inner product in this interval we need to compute the integral of (ax+b)(cx+d) = acx^2 +
657  // (ad+bc)x + bd in the interval from previous_x to current_x:
658  // The integral is ac/3*x^3 + (ac+bd)/2*x^2 + bd*x
659 
660  double added_value = (a * c / 3 * current_x * current_x * current_x +
661  (a * d + b * c) / 2 * current_x * current_x + b * d * current_x) -
662  (a * c / 3 * previous_x * previous_x * previous_x +
663  (a * d + b * c) / 2 * previous_x * previous_x + b * d * previous_x);
664 
665  if (dbg) {
666  std::clog << "Value of the integral on the left end i.e. : " << previous_x << " is : "
667  << a * c / 3 * previous_x * previous_x * previous_x + (a * d + b * c) / 2 * previous_x * previous_x +
668  b * d * previous_x
669  << std::endl;
670  std::clog << "Value of the integral on the right end i.e. : " << current_x << " is "
671  << a * c / 3 * current_x * current_x * current_x + (a * d + b * c) / 2 * current_x * current_x +
672  b * d * current_x
673  << std::endl;
674  }
675 
676  result += added_value;
677 
678  if (dbg) {
679  std::clog << "added_value : " << added_value << std::endl;
680  std::clog << "result : " << result << std::endl;
681  getchar();
682  }
683 
684  previous_x = current_x;
685  previous_y_l1 = current_y_l1;
686  previous_y_l2 = current_y_l2;
687  }
688  return result;
689  }
690 
700  const Persistence_landscape_on_grid& second, double p) {
701  bool dbg = false;
702  // This is what we want to compute: (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p). We will do it one step at a
703  // time:
704 
705  if (dbg) {
706  std::clog << "first : " << first << std::endl;
707  std::clog << "second : " << second << std::endl;
708  getchar();
709  }
710 
711  // first-second :
712  Persistence_landscape_on_grid lan = first - second;
713 
714  if (dbg) {
715  std::clog << "Difference : " << lan << std::endl;
716  }
717 
718  //| first-second |:
719  lan.abs();
720 
721  if (dbg) {
722  std::clog << "Abs : " << lan << std::endl;
723  }
724 
725  if (p < std::numeric_limits<double>::max()) {
726  // \int_{- \infty}^{+\infty}| first-second |^p
727  double result;
728  if (p != 1) {
729  if (dbg) {
730  std::clog << "p : " << p << std::endl;
731  getchar();
732  }
733  result = lan.compute_integral_of_landscape(p);
734  if (dbg) {
735  std::clog << "integral : " << result << std::endl;
736  getchar();
737  }
738  } else {
739  result = lan.compute_integral_of_landscape();
740  if (dbg) {
741  std::clog << "integral, without power : " << result << std::endl;
742  getchar();
743  }
744  }
745  // (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p)
746  return pow(result, 1.0 / p);
747  } else {
748  // p == infty
749  return lan.compute_maximum();
750  }
751  }
752 
753  // Functions that are needed for that class to implement the concept.
754 
763  double project_to_R(int number_of_function) const {
764  return this->compute_integral_of_landscape((size_t)number_of_function);
765  }
766 
771  size_t number_of_projections_to_R() const { return number_of_functions_for_projections_to_reals; }
772 
777  std::vector<double> vectorize(int number_of_function) const {
778  // TODO(PD) think of something smarter over here
779  if ((number_of_function < 0) || ((size_t)number_of_function >= this->values_of_landscapes.size())) {
780  throw "Wrong number of function\n";
781  }
782  std::vector<double> v(this->values_of_landscapes.size());
783  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
784  v[i] = 0;
785  if (this->values_of_landscapes[i].size() > (size_t)number_of_function) {
786  v[i] = this->values_of_landscapes[i][number_of_function];
787  }
788  }
789  return v;
790  }
791 
796  size_t number_of_vectorize_functions() const { return number_of_functions_for_vectorization; }
797 
802  void compute_average(const std::vector<Persistence_landscape_on_grid*>& to_average) {
803  bool dbg = false;
804  // After execution of this procedure, the average is supposed to be in the current object. To make sure that this is
805  // the case, we need to do some cleaning first.
806  this->values_of_landscapes.clear();
807  this->grid_min = this->grid_max = 0;
808 
809  // if there is nothing to average, then the average is a zero landscape.
810  if (to_average.size() == 0) return;
811 
812  // now we need to check if the grids in all objects of to_average are the same:
813  for (size_t i = 0; i != to_average.size(); ++i) {
814  if (!check_if_defined_on_the_same_domain(*(to_average[0]), *(to_average[i])))
815  throw "Two grids are not compatible";
816  }
817 
818  this->values_of_landscapes = std::vector<std::vector<double> >((to_average[0])->values_of_landscapes.size());
819  this->grid_min = (to_average[0])->grid_min;
820  this->grid_max = (to_average[0])->grid_max;
821 
822  if (dbg) {
823  std::clog << "Computations of average. The data from the current landscape have been cleared. We are ready to do "
824  "the computations. \n";
825  }
826 
827  // for every point in the grid:
828  for (size_t grid_point = 0; grid_point != (to_average[0])->values_of_landscapes.size(); ++grid_point) {
829  // set up a vector of the correct size:
830  size_t maximal_size_of_vector = 0;
831  for (size_t land_no = 0; land_no != to_average.size(); ++land_no) {
832  if ((to_average[land_no])->values_of_landscapes[grid_point].size() > maximal_size_of_vector)
833  maximal_size_of_vector = (to_average[land_no])->values_of_landscapes[grid_point].size();
834  }
835  this->values_of_landscapes[grid_point] = std::vector<double>(maximal_size_of_vector);
836 
837  if (dbg) {
838  std::clog << "We are considering the point : " << grid_point
839  << " of the grid. In this point, there are at most : " << maximal_size_of_vector
840  << " nonzero landscape functions \n";
841  }
842 
843  // and compute an arithmetic average:
844  for (size_t land_no = 0; land_no != to_average.size(); ++land_no) {
845  // summing:
846  for (size_t i = 0; i != (to_average[land_no])->values_of_landscapes[grid_point].size(); ++i) {
847  // compute the average in a smarter way.
848  this->values_of_landscapes[grid_point][i] += (to_average[land_no])->values_of_landscapes[grid_point][i];
849  }
850  }
851  // normalizing:
852  for (size_t i = 0; i != this->values_of_landscapes[grid_point].size(); ++i) {
853  this->values_of_landscapes[grid_point][i] /= static_cast<double>(to_average.size());
854  }
855  }
856  } // compute_average
857 
864  double distance(const Persistence_landscape_on_grid& second, double power = 1) const {
865  if (power < std::numeric_limits<double>::max()) {
866  return compute_distance_of_landscapes_on_grid(*this, second, power);
867  } else {
868  return compute_max_norm_distance_of_landscapes(*this, second);
869  }
870  }
871 
878  return compute_inner_product((*this), second);
879  }
880 
881  // end of implementation of functions needed for concepts.
882 
886  std::vector<std::vector<double> > output_for_visualization() const { return this->values_of_landscapes; }
887 
897  void plot(const char* filename, size_t from_, size_t to_) const {
898  this->plot(filename, std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
899  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), from_, to_);
900  }
901 
906  void plot(const char* filename, double min_x = std::numeric_limits<double>::max(),
907  double max_x = std::numeric_limits<double>::max(), double min_y = std::numeric_limits<double>::max(),
908  double max_y = std::numeric_limits<double>::max(), size_t from_ = std::numeric_limits<size_t>::max(),
909  size_t to_ = std::numeric_limits<size_t>::max()) const;
910 
911  protected:
912  double grid_min;
913  double grid_max;
914  std::vector<std::vector<double> > values_of_landscapes;
915  size_t number_of_functions_for_vectorization;
916  size_t number_of_functions_for_projections_to_reals;
917 
918  void set_up_numbers_of_functions_for_vectorization_and_projections_to_reals() {
919  // warning, this function can be only called after filling in the values_of_landscapes vector.
920  this->number_of_functions_for_vectorization = this->values_of_landscapes.size();
921  this->number_of_functions_for_projections_to_reals = this->values_of_landscapes.size();
922  }
923  void set_up_values_of_landscapes(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
924  size_t number_of_points_,
925  unsigned number_of_levels = std::numeric_limits<unsigned>::max());
926  Persistence_landscape_on_grid multiply_lanscape_by_real_number_not_overwrite(double x) const;
927 };
928 
929 void Persistence_landscape_on_grid::set_up_values_of_landscapes(const std::vector<std::pair<double, double> >& p,
930  double grid_min_, double grid_max_,
931  size_t number_of_points_, unsigned number_of_levels) {
932  bool dbg = false;
933  if (dbg) {
934  std::clog << "Here is the procedure : set_up_values_of_landscapes. The parameters are : grid_min_ : " << grid_min_
935  << ", grid_max_ : " << grid_max_ << ", number_of_points_ : " << number_of_points_
936  << ", number_of_levels: " << number_of_levels << std::endl;
937  std::clog << "Here are the intervals at our disposal : \n";
938  for (size_t i = 0; i != p.size(); ++i) {
939  std::clog << p[i].first << " , " << p[i].second << std::endl;
940  }
941  }
942 
943  if ((grid_min_ == std::numeric_limits<double>::max()) || (grid_max_ == std::numeric_limits<double>::max())) {
944  // in this case, we need to find grid_min_ and grid_min_ based on the data.
945  double min = std::numeric_limits<double>::max();
946  double max = std::numeric_limits<double>::min();
947  for (size_t i = 0; i != p.size(); ++i) {
948  if (p[i].first < min) min = p[i].first;
949  if (p[i].second > max) max = p[i].second;
950  }
951  if (grid_min_ == std::numeric_limits<double>::max()) {
952  grid_min_ = min;
953  } else {
954  // in this case grid_max_ == std::numeric_limits<double>::max()
955  grid_max_ = max;
956  }
957  }
958 
959  // if number_of_levels == std::numeric_limits<size_t>::max(), then we will have all the nonzero values of landscapes,
960  // and will store them in a vector
961  // if number_of_levels != std::numeric_limits<size_t>::max(), then we will use those vectors as heaps.
962  this->values_of_landscapes = std::vector<std::vector<double> >(number_of_points_ + 1);
963 
964  this->grid_min = grid_min_;
965  this->grid_max = grid_max_;
966 
967  if (grid_max_ <= grid_min_) {
968  throw "Wrong parameters of grid_min and grid_max given to the procedure. The program will now terminate.\n";
969  }
970 
971  double dx = (grid_max_ - grid_min_) / static_cast<double>(number_of_points_);
972  // for every interval in the diagram:
973  for (size_t int_no = 0; int_no != p.size(); ++int_no) {
974  size_t grid_interval_begin = (p[int_no].first - grid_min_) / dx;
975  size_t grid_interval_end = (p[int_no].second - grid_min_) / dx;
976  size_t grid_interval_midpoint = (size_t)(0.5 * (grid_interval_begin + grid_interval_end));
977 
978  if (dbg) {
979  std::clog << "Considering an interval : " << p[int_no].first << "," << p[int_no].second << std::endl;
980 
981  std::clog << "grid_interval_begin : " << grid_interval_begin << std::endl;
982  std::clog << "grid_interval_end : " << grid_interval_end << std::endl;
983  std::clog << "grid_interval_midpoint : " << grid_interval_midpoint << std::endl;
984  }
985 
986  double landscape_value = dx;
987  for (size_t i = grid_interval_begin + 1; i < grid_interval_midpoint; ++i) {
988  if (dbg) {
989  std::clog << "Adding landscape value (going up) for a point : " << i << " equal : " << landscape_value
990  << std::endl;
991  }
992  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
993  // we have a heap of no more that number_of_levels values.
994  // Note that if we are using heaps, we want to know the shortest distance in the heap.
995  // This is achieved by putting -distance to the heap.
996  if (this->values_of_landscapes[i].size() >= number_of_levels) {
997  // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
998  // smallest element in the heap.
999  if (-landscape_value < this->values_of_landscapes[i].front()) {
1000  // if it is, we remove the largest value in the heap, and move on.
1001  std::pop_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1002  this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] = -landscape_value;
1003  std::push_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1004  }
1005  } else {
1006  // in this case we are still filling in the array.
1007  this->values_of_landscapes[i].push_back(-landscape_value);
1008  if (this->values_of_landscapes[i].size() == number_of_levels - 1) {
1009  // this->values_of_landscapes[i].size() == number_of_levels
1010  // in this case we need to create the heap.
1011  std::make_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1012  }
1013  }
1014  } else {
1015  // we have vector of all values
1016  this->values_of_landscapes[i].push_back(landscape_value);
1017  }
1018  landscape_value += dx;
1019  }
1020  for (size_t i = grid_interval_midpoint; i <= grid_interval_end; ++i) {
1021  if (landscape_value > 0) {
1022  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1023  // we have a heap of no more that number_of_levels values
1024  if (this->values_of_landscapes[i].size() >= number_of_levels) {
1025  // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
1026  // smallest element in the heap.
1027  if (-landscape_value < this->values_of_landscapes[i].front()) {
1028  // if it is, we remove the largest value in the heap, and move on.
1029  std::pop_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1030  this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] = -landscape_value;
1031  std::push_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1032  }
1033  } else {
1034  // in this case we are still filling in the array.
1035  this->values_of_landscapes[i].push_back(-landscape_value);
1036  if (this->values_of_landscapes[i].size() == number_of_levels - 1) {
1037  // this->values_of_landscapes[i].size() == number_of_levels
1038  // in this case we need to create the heap.
1039  std::make_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1040  }
1041  }
1042  } else {
1043  this->values_of_landscapes[i].push_back(landscape_value);
1044  }
1045 
1046  if (dbg) {
1047  std::clog << "Adding landscape value (going down) for a point : " << i << " equal : " << landscape_value
1048  << std::endl;
1049  }
1050  }
1051  landscape_value -= dx;
1052  }
1053  }
1054 
1055  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1056  // in this case, vectors are used as heaps. And, since we want to have the smallest element at the top of
1057  // each heap, we store minus distances. To get if right at the end, we need to multiply each value
1058  // in the heap by -1 to get real vector of distances.
1059  for (size_t pt = 0; pt != this->values_of_landscapes.size(); ++pt) {
1060  for (size_t j = 0; j != this->values_of_landscapes[pt].size(); ++j) {
1061  this->values_of_landscapes[pt][j] *= -1;
1062  }
1063  }
1064  }
1065 
1066  // and now we need to sort the values:
1067  for (size_t pt = 0; pt != this->values_of_landscapes.size(); ++pt) {
1068  std::sort(this->values_of_landscapes[pt].begin(), this->values_of_landscapes[pt].end(), std::greater<double>());
1069  }
1070 } // set_up_values_of_landscapes
1071 
1072 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
1073  double grid_min_, double grid_max_,
1074  size_t number_of_points_) {
1075  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_);
1076 } // Persistence_landscape_on_grid
1077 
1078 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
1079  double grid_min_, double grid_max_,
1080  size_t number_of_points_,
1081  unsigned number_of_levels_of_landscape) {
1082  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1083 }
1084 
1085 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_,
1086  size_t number_of_points_, uint16_t dimension) {
1087  std::vector<std::pair<double, double> > p;
1088  if (dimension == std::numeric_limits<uint16_t>::max()) {
1089  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1090  } else {
1091  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1092  }
1093  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_);
1094 }
1095 
1096 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_,
1097  size_t number_of_points_,
1098  unsigned number_of_levels_of_landscape,
1099  uint16_t dimension) {
1100  std::vector<std::pair<double, double> > p;
1101  if (dimension == std::numeric_limits<uint16_t>::max()) {
1102  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1103  } else {
1104  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1105  }
1106  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1107 }
1108 
1109 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, size_t number_of_points_,
1110  uint16_t dimension) {
1111  std::vector<std::pair<double, double> > p;
1112  if (dimension == std::numeric_limits<uint16_t>::max()) {
1113  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1114  } else {
1115  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1116  }
1117  double grid_min_ = std::numeric_limits<double>::max();
1118  double grid_max_ = -std::numeric_limits<double>::max();
1119  for (size_t i = 0; i != p.size(); ++i) {
1120  if (p[i].first < grid_min_) grid_min_ = p[i].first;
1121  if (p[i].second > grid_max_) grid_max_ = p[i].second;
1122  }
1123  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_);
1124 }
1125 
1126 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, size_t number_of_points_,
1127  unsigned number_of_levels_of_landscape,
1128  uint16_t dimension) {
1129  std::vector<std::pair<double, double> > p;
1130  if (dimension == std::numeric_limits<uint16_t>::max()) {
1131  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1132  } else {
1133  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1134  }
1135  double grid_min_ = std::numeric_limits<double>::max();
1136  double grid_max_ = -std::numeric_limits<double>::max();
1137  for (size_t i = 0; i != p.size(); ++i) {
1138  if (p[i].first < grid_min_) grid_min_ = p[i].first;
1139  if (p[i].second > grid_max_) grid_max_ = p[i].second;
1140  }
1141  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1142 }
1143 
1145  std::ifstream in;
1146  in.open(filename);
1147  // check if the file exist.
1148  if (!in.good()) {
1149  std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n";
1150  throw "The persistence landscape file do not exist. The program will now terminate \n";
1151  }
1152 
1153  size_t number_of_points_in_the_grid = 0;
1154  in >> this->grid_min >> this->grid_max >> number_of_points_in_the_grid;
1155 
1156  std::vector<std::vector<double> > v(number_of_points_in_the_grid);
1157  std::string line;
1158  std::getline(in, line);
1159  double number;
1160  for (size_t i = 0; i != number_of_points_in_the_grid; ++i) {
1161  // read a line of a file and convert it to a vector.
1162  std::vector<double> vv;
1163  std::getline(in, line);
1164  std::istringstream stream(line);
1165  while (stream >> number) {
1166  vv.push_back(number);
1167  }
1168  v[i] = vv;
1169  }
1170  this->values_of_landscapes = v;
1171  in.close();
1172 }
1173 
1174 void Persistence_landscape_on_grid::print_to_file(const char* filename) const {
1175  std::ofstream out;
1176  out.open(filename);
1177 
1178  // first we store the parameters of the grid:
1179  out << grid_min << std::endl << grid_max << std::endl << this->values_of_landscapes.size() << std::endl;
1180 
1181  // and now in the following lines, the values of this->values_of_landscapes for the following arguments:
1182  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
1183  for (size_t j = 0; j != this->values_of_landscapes[i].size(); ++j) {
1184  out << this->values_of_landscapes[i][j] << " ";
1185  }
1186  out << std::endl;
1187  }
1188 
1189  out.close();
1190 }
1191 
1192 void Persistence_landscape_on_grid::plot(const char* filename, double min_x, double max_x, double min_y, double max_y,
1193  size_t from_, size_t to_) const {
1194  // this program create a gnuplot script file that allows to plot persistence diagram.
1195  std::ofstream out;
1196 
1197  std::ostringstream gnuplot_script;
1198  gnuplot_script << filename << "_GnuplotScript";
1199  out.open(gnuplot_script.str().c_str());
1200 
1201  if (min_x == max_x) {
1202  std::pair<double, double> min_max = compute_minimum_maximum();
1203  out << "set xrange [" << this->grid_min << " : " << this->grid_max << "]" << std::endl;
1204  out << "set yrange [" << min_max.first << " : " << min_max.second << "]" << std::endl;
1205  } else {
1206  out << "set xrange [" << min_x << " : " << max_x << "]" << std::endl;
1207  out << "set yrange [" << min_y << " : " << max_y << "]" << std::endl;
1208  }
1209 
1211  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
1212 
1213  size_t from = 0;
1214  if (from_ != std::numeric_limits<size_t>::max()) {
1215  if (from_ < number_of_nonzero_levels) {
1216  from = from_;
1217  } else {
1218  return;
1219  }
1220  }
1221  size_t to = number_of_nonzero_levels;
1222  if (to_ != std::numeric_limits<size_t>::max()) {
1223  if (to_ < number_of_nonzero_levels) {
1224  to = to_;
1225  }
1226  }
1227 
1228  out << "plot ";
1229  for (size_t lambda = from; lambda != to; ++lambda) {
1230  out << " '-' using 1:2 notitle with lp";
1231  if (lambda + 1 != to) {
1232  out << ", \\";
1233  }
1234  out << std::endl;
1235  }
1236 
1237  for (size_t lambda = from; lambda != to; ++lambda) {
1238  double point = this->grid_min;
1239  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
1240  double value = 0;
1241  if (this->values_of_landscapes[i].size() > lambda) {
1242  value = this->values_of_landscapes[i][lambda];
1243  }
1244  out << point << " " << value << std::endl;
1245  point += dx;
1246  }
1247  out << "EOF" << std::endl;
1248  }
1249  std::clog << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
1250  << gnuplot_script.str().c_str() << "\'\"" << std::endl;
1251 }
1252 
1253 template <typename T>
1254 Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid& land1,
1255  const Persistence_landscape_on_grid& land2) {
1256  // first we need to check if the domains are the same:
1257  if (!check_if_defined_on_the_same_domain(land1, land2)) throw "Two grids are not compatible";
1258 
1259  T oper;
1261  result.values_of_landscapes = std::vector<std::vector<double> >(land1.values_of_landscapes.size());
1262  result.grid_min = land1.grid_min;
1263  result.grid_max = land1.grid_max;
1264 
1265  // now we perform the operations:
1266  for (size_t grid_point = 0; grid_point != land1.values_of_landscapes.size(); ++grid_point) {
1267  result.values_of_landscapes[grid_point] = std::vector<double>(
1268  std::max(land1.values_of_landscapes[grid_point].size(), land2.values_of_landscapes[grid_point].size()));
1269  for (size_t lambda = 0; lambda != std::max(land1.values_of_landscapes[grid_point].size(),
1270  land2.values_of_landscapes[grid_point].size());
1271  ++lambda) {
1272  double value1 = 0;
1273  double value2 = 0;
1274  if (lambda < land1.values_of_landscapes[grid_point].size())
1275  value1 = land1.values_of_landscapes[grid_point][lambda];
1276  if (lambda < land2.values_of_landscapes[grid_point].size())
1277  value2 = land2.values_of_landscapes[grid_point][lambda];
1278  result.values_of_landscapes[grid_point][lambda] = oper(value1, value2);
1279  }
1280  }
1281 
1282  return result;
1283 }
1284 
1285 Persistence_landscape_on_grid Persistence_landscape_on_grid::multiply_lanscape_by_real_number_not_overwrite(
1286  double x) const {
1288  result.values_of_landscapes = std::vector<std::vector<double> >(this->values_of_landscapes.size());
1289  result.grid_min = this->grid_min;
1290  result.grid_max = this->grid_max;
1291 
1292  for (size_t grid_point = 0; grid_point != this->values_of_landscapes.size(); ++grid_point) {
1293  result.values_of_landscapes[grid_point] = std::vector<double>(this->values_of_landscapes[grid_point].size());
1294  for (size_t i = 0; i != this->values_of_landscapes[grid_point].size(); ++i) {
1295  result.values_of_landscapes[grid_point][i] = x * this->values_of_landscapes[grid_point][i];
1296  }
1297  }
1298 
1299  return result;
1300 }
1301 
1303  const Persistence_landscape_on_grid& second) {
1304  double result = 0;
1305 
1306  // first we need to check if first and second is defined on the same domain"
1307  if (!check_if_defined_on_the_same_domain(first, second)) throw "Two grids are not compatible";
1308 
1309  for (size_t i = 0; i != first.values_of_landscapes.size(); ++i) {
1310  for (size_t j = 0; j != std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size());
1311  ++j) {
1312  if (result < abs(first.values_of_landscapes[i][j] - second.values_of_landscapes[i][j])) {
1313  result = abs(first.values_of_landscapes[i][j] - second.values_of_landscapes[i][j]);
1314  }
1315  }
1316  if (first.values_of_landscapes[i].size() ==
1317  std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size())) {
1318  for (size_t j = first.values_of_landscapes[i].size(); j != second.values_of_landscapes[i].size(); ++j) {
1319  if (result < second.values_of_landscapes[i][j]) result = second.values_of_landscapes[i][j];
1320  }
1321  }
1322  if (second.values_of_landscapes[i].size() ==
1323  std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size())) {
1324  for (size_t j = second.values_of_landscapes[i].size(); j != first.values_of_landscapes[i].size(); ++j) {
1325  if (result < first.values_of_landscapes[i][j]) result = first.values_of_landscapes[i][j];
1326  }
1327  }
1328  }
1329  return result;
1330 }
1331 
1332 } // namespace Persistence_representations
1333 } // namespace Gudhi
1334 
1335 #endif // PERSISTENCE_LANDSCAPE_ON_GRID_H_
friend double compute_distance_of_landscapes_on_grid(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second, double p)
Definition: Persistence_landscape_on_grid.h:699
std::pair< double, double > get_x_range(size_t level=0) const
Definition: Persistence_landscape_on_grid.h:508
bool operator!=(const Persistence_landscape_on_grid &rhs) const
Definition: Persistence_landscape_on_grid.h:463
double distance(const Persistence_landscape_on_grid &second, double power=1) const
Definition: Persistence_landscape_on_grid.h:864
friend Persistence_landscape_on_grid operator*(const Persistence_landscape_on_grid &first, double con)
Definition: Persistence_landscape_on_grid.h:376
std::vector< double > vectorize(int number_of_function) const
Definition: Persistence_landscape_on_grid.h:777
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:1302
void print_to_file(const char *filename) const
Definition: Persistence_landscape_on_grid.h:1174
void compute_average(const std::vector< Persistence_landscape_on_grid *> &to_average)
Definition: Persistence_landscape_on_grid.h:802
void plot(const char *filename, size_t from_, size_t to_) const
Definition: Persistence_landscape_on_grid.h:897
friend Persistence_landscape_on_grid operator*(double con, const Persistence_landscape_on_grid &first)
Definition: Persistence_landscape_on_grid.h:383
Definition: SimplicialComplexForAlpha.h:14
double compute_integral_of_landscape() const
Definition: Persistence_landscape_on_grid.h:140
double operator()(unsigned level, double x) const
Definition: Persistence_landscape_on_grid.h:546
void load_landscape_from_file(const char *filename)
Definition: Persistence_landscape_on_grid.h:1144
Persistence_landscape_on_grid operator-=(const Persistence_landscape_on_grid &rhs)
Definition: Persistence_landscape_on_grid.h:406
double compute_integral_of_landscape(double p) const
Definition: Persistence_landscape_on_grid.h:193
double compute_value_at_a_given_point(unsigned level, double x) const
Definition: Persistence_landscape_on_grid.h:291
Persistence_landscape_on_grid()
Definition: Persistence_landscape_on_grid.h:64
void abs()
Definition: Persistence_landscape_on_grid.h:560
size_t number_of_nonzero_levels() const
Definition: Persistence_landscape_on_grid.h:521
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:344
friend Persistence_landscape_on_grid operator-(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:368
A class implementing persistence landscapes by approximating them on a collection of grid points...
Definition: Persistence_landscape_on_grid.h:59
Persistence_landscape_on_grid operator+=(const Persistence_landscape_on_grid &rhs)
Definition: Persistence_landscape_on_grid.h:398
friend double compute_inner_product(const Persistence_landscape_on_grid &l1, const Persistence_landscape_on_grid &l2)
Definition: Persistence_landscape_on_grid.h:589
size_t size() const
Definition: Persistence_landscape_on_grid.h:571
std::pair< double, double > compute_minimum_maximum() const
Definition: Persistence_landscape_on_grid.h:485
friend std::ostream & operator<<(std::ostream &out, const Persistence_landscape_on_grid &land)
Definition: Persistence_landscape_on_grid.h:268
friend double compute_inner_product(const Persistence_landscape_on_grid &l1, const Persistence_landscape_on_grid &l2, size_t level)
Definition: Persistence_landscape_on_grid.h:604
double compute_norm_of_landscape(double i) const
Definition: Persistence_landscape_on_grid.h:532
size_t number_of_vectorize_functions() const
Definition: Persistence_landscape_on_grid.h:796
friend Persistence_landscape_on_grid operator+(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:360
std::pair< double, double > get_y_range(size_t level=0) const
Definition: Persistence_landscape_on_grid.h:516
std::vector< std::vector< double > > output_for_visualization() const
Definition: Persistence_landscape_on_grid.h:886
double compute_maximum() const
Definition: Persistence_landscape_on_grid.h:468
double compute_scalar_product(const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:877
double project_to_R(int number_of_function) const
Definition: Persistence_landscape_on_grid.h:763
Persistence_landscape_on_grid operator/=(double x)
Definition: Persistence_landscape_on_grid.h:423
double compute_integral_of_landscape(double p, size_t level) const
Definition: Persistence_landscape_on_grid.h:206
size_t number_of_projections_to_R() const
Definition: Persistence_landscape_on_grid.h:771
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:352
double compute_integral_of_landscape(size_t level) const
Definition: Persistence_landscape_on_grid.h:152
Persistence_landscape_on_grid operator*=(double x)
Definition: Persistence_landscape_on_grid.h:415
double find_max(unsigned lambda) const
Definition: Persistence_landscape_on_grid.h:576
bool operator==(const Persistence_landscape_on_grid &rhs) const
Definition: Persistence_landscape_on_grid.h:432
GUDHI  Version 3.4.1  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Fri Jan 22 2021 09:41:15 for GUDHI by Doxygen 1.8.13