Persistence_landscape_on_grid.h
1 
24 #ifndef PERSISTENCE_LANDSCAPE_ON_GRID_H_
25 #define PERSISTENCE_LANDSCAPE_ON_GRID_H_
26 
27 // gudhi include
28 #include <gudhi/read_persistence_from_file.h>
29 #include <gudhi/common_persistence_representations.h>
30 
31 // standard include
32 #include <iostream>
33 #include <vector>
34 #include <limits>
35 #include <fstream>
36 #include <sstream>
37 #include <algorithm>
38 #include <cmath>
39 #include <functional>
40 #include <utility>
41 #include <string>
42 #include <cstdint>
43 
44 namespace Gudhi {
45 namespace Persistence_representations {
46 
47 // pre declaration
49 template <typename operation>
50 Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid& land1,
51  const Persistence_landscape_on_grid& land2);
52 
70 // this class implements the following concepts: Vectorized_topological_data, Topological_data_with_distances,
71 // Real_valued_topological_data, Topological_data_with_averages, Topological_data_with_scalar_product
73  public:
78  this->set_up_numbers_of_functions_for_vectorization_and_projections_to_reals();
79  this->grid_min = this->grid_max = 0;
80  }
81 
85  Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
86  size_t number_of_points_);
87 
92  Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
93  size_t number_of_points_, unsigned number_of_levels_of_landscape);
94 
103  Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_,
104  unsigned number_of_levels_of_landscape,
105  uint16_t dimension_ = std::numeric_limits<uint16_t>::max());
106 
114  Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_, size_t number_of_points_,
115  uint16_t dimension_ = std::numeric_limits<uint16_t>::max());
116 
124  Persistence_landscape_on_grid(const char* filename, size_t number_of_points, unsigned number_of_levels_of_landscape,
125  uint16_t dimension = std::numeric_limits<uint16_t>::max());
126 
136  Persistence_landscape_on_grid(const char* filename, size_t number_of_points,
137  uint16_t dimension = std::numeric_limits<uint16_t>::max());
138 
142  void load_landscape_from_file(const char* filename);
143 
147  void print_to_file(const char* filename) const;
148 
154  size_t maximal_level = this->number_of_nonzero_levels();
155  double result = 0;
156  for (size_t i = 0; i != maximal_level; ++i) {
157  result += this->compute_integral_of_landscape(i);
158  }
159  return result;
160  }
161 
165  double compute_integral_of_landscape(size_t level) const {
166  bool dbg = false;
167  double result = 0;
168  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
169 
170  if (dbg) {
171  std::cerr << "this->grid_max : " << this->grid_max << std::endl;
172  std::cerr << "this->grid_min : " << this->grid_min << std::endl;
173  std::cerr << "this->values_of_landscapes.size() : " << this->values_of_landscapes.size() << std::endl;
174  getchar();
175  }
176 
177  double previous_x = this->grid_min - dx;
178  double previous_y = 0;
179  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
180  double current_x = previous_x + dx;
181  double current_y = 0;
182  if (this->values_of_landscapes[i].size() > level) current_y = this->values_of_landscapes[i][level];
183 
184  if (dbg) {
185  std::cerr << "this->values_of_landscapes[i].size() : " << this->values_of_landscapes[i].size()
186  << " , level : " << level << std::endl;
187  if (this->values_of_landscapes[i].size() > level)
188  std::cerr << "this->values_of_landscapes[i][level] : " << this->values_of_landscapes[i][level] << std::endl;
189  std::cerr << "previous_y : " << previous_y << std::endl;
190  std::cerr << "current_y : " << current_y << std::endl;
191  std::cerr << "dx : " << dx << std::endl;
192  std::cerr << "0.5*dx*( previous_y + current_y ); " << 0.5 * dx * (previous_y + current_y) << std::endl;
193  }
194 
195  result += 0.5 * dx * (previous_y + current_y);
196  previous_x = current_x;
197  previous_y = current_y;
198  }
199  return result;
200  }
201 
206  double compute_integral_of_landscape(double p) const {
207  size_t maximal_level = this->number_of_nonzero_levels();
208  double result = 0;
209  for (size_t i = 0; i != maximal_level; ++i) {
210  result += this->compute_integral_of_landscape(p, i);
211  }
212  return result;
213  }
214 
219  double compute_integral_of_landscape(double p, size_t level) const {
220  bool dbg = false;
221 
222  double result = 0;
223  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
224  double previous_x = this->grid_min;
225  double previous_y = 0;
226  if (this->values_of_landscapes[0].size() > level) previous_y = this->values_of_landscapes[0][level];
227 
228  if (dbg) {
229  std::cerr << "dx : " << dx << std::endl;
230  std::cerr << "previous_x : " << previous_x << std::endl;
231  std::cerr << "previous_y : " << previous_y << std::endl;
232  std::cerr << "power : " << p << std::endl;
233  getchar();
234  }
235 
236  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
237  double current_x = previous_x + dx;
238  double current_y = 0;
239  if (this->values_of_landscapes[i].size() > level) current_y = this->values_of_landscapes[i][level];
240 
241  if (dbg) std::cerr << "current_y : " << current_y << std::endl;
242 
243  if (current_y == previous_y) continue;
244 
245  std::pair<double, double> coef =
246  compute_parameters_of_a_line(std::make_pair(previous_x, previous_y), std::make_pair(current_x, current_y));
247  double a = coef.first;
248  double b = coef.second;
249 
250  if (dbg) {
251  std::cerr << "A line passing through points : (" << previous_x << "," << previous_y << ") and (" << current_x
252  << "," << current_y << ") is : " << a << "x+" << b << std::endl;
253  }
254 
255  // In this interval, the landscape has a form f(x) = ax+b. We want to compute integral of (ax+b)^p = 1/a *
256  // (ax+b)^{p+1}/(p+1)
257  double value_to_add = 0;
258  if (a != 0) {
259  value_to_add = 1 / (a * (p + 1)) * (pow((a * current_x + b), p + 1) - pow((a * previous_x + b), p + 1));
260  } else {
261  value_to_add = (current_x - previous_x) * (pow(b, p));
262  }
263  result += value_to_add;
264  if (dbg) {
265  std::cerr << "Increasing result by : " << value_to_add << std::endl;
266  std::cerr << "result : " << result << std::endl;
267  getchar();
268  }
269  previous_x = current_x;
270  previous_y = current_y;
271  }
272  if (dbg) std::cerr << "The total result is : " << result << std::endl;
273  return result;
274  }
275 
281  friend std::ostream& operator<<(std::ostream& out, const Persistence_landscape_on_grid& land) {
282  double dx = (land.grid_max - land.grid_min) / static_cast<double>(land.values_of_landscapes.size() - 1);
283  double x = land.grid_min;
284  for (size_t i = 0; i != land.values_of_landscapes.size(); ++i) {
285  out << x << " : ";
286  for (size_t j = 0; j != land.values_of_landscapes[i].size(); ++j) {
287  out << land.values_of_landscapes[i][j] << " ";
288  }
289  out << std::endl;
290  x += dx;
291  }
292  return out;
293  }
294 
295  template <typename oper>
296  friend Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(
298 
304  double compute_value_at_a_given_point(unsigned level, double x) const {
305  bool dbg = false;
306  if ((x < this->grid_min) || (x > this->grid_max)) return 0;
307 
308  // find a position of a vector closest to x:
309  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
310  size_t position = size_t((x - this->grid_min) / dx);
311 
312  if (dbg) {
313  std::cerr << "This is a procedure compute_value_at_a_given_point \n";
314  std::cerr << "level : " << level << std::endl;
315  std::cerr << "x : " << x << std::endl;
316  std::cerr << "position : " << position << std::endl;
317  }
318  // check if we are not exactly in the grid point:
319  if (almost_equal(position * dx + this->grid_min, x)) {
320  if (this->values_of_landscapes[position].size() < level) {
321  return this->values_of_landscapes[position][level];
322  } else {
323  return 0;
324  }
325  }
326  // in the other case, approximate with a line:
327  std::pair<double, double> line;
328  if ((this->values_of_landscapes[position].size() > level) &&
329  (this->values_of_landscapes[position + 1].size() > level)) {
330  line = compute_parameters_of_a_line(
331  std::make_pair(position * dx + this->grid_min, this->values_of_landscapes[position][level]),
332  std::make_pair((position + 1) * dx + this->grid_min, this->values_of_landscapes[position + 1][level]));
333  } else {
334  if ((this->values_of_landscapes[position].size() > level) ||
335  (this->values_of_landscapes[position + 1].size() > level)) {
336  if ((this->values_of_landscapes[position].size() > level)) {
337  line = compute_parameters_of_a_line(
338  std::make_pair(position * dx + this->grid_min, this->values_of_landscapes[position][level]),
339  std::make_pair((position + 1) * dx + this->grid_min, 0));
340  } else {
341  line = compute_parameters_of_a_line(
342  std::make_pair(position * dx + this->grid_min, 0),
343  std::make_pair((position + 1) * dx + this->grid_min, this->values_of_landscapes[position + 1][level]));
344  }
345  } else {
346  return 0;
347  }
348  }
349  // compute the value of the linear function parametrized by line on a point x:
350  return line.first * x + line.second;
351  }
352 
353  public:
358  const Persistence_landscape_on_grid& land2) {
359  return operation_on_pair_of_landscapes_on_grid<std::plus<double> >(land1, land2);
360  }
361 
366  const Persistence_landscape_on_grid& land2) {
367  return operation_on_pair_of_landscapes_on_grid<std::minus<double> >(land1, land2);
368  }
369 
374  const Persistence_landscape_on_grid& second) {
375  return add_two_landscapes(first, second);
376  }
377 
382  const Persistence_landscape_on_grid& second) {
383  return subtract_two_landscapes(first, second);
384  }
385 
390  return first.multiply_lanscape_by_real_number_not_overwrite(con);
391  }
392 
397  return first.multiply_lanscape_by_real_number_not_overwrite(con);
398  }
399 
400  friend bool check_if_defined_on_the_same_domain(const Persistence_landscape_on_grid& land1,
401  const Persistence_landscape_on_grid& land2) {
402  if (land1.values_of_landscapes.size() != land2.values_of_landscapes.size()) return false;
403  if (land1.grid_min != land2.grid_min) return false;
404  if (land1.grid_max != land2.grid_max) return false;
405  return true;
406  }
407 
412  *this = *this + rhs;
413  return *this;
414  }
415 
420  *this = *this - rhs;
421  return *this;
422  }
423 
429  *this = *this * x;
430  return *this;
431  }
432 
437  if (x == 0) throw("In operator /=, division by 0. Program terminated.");
438  *this = *this * (1 / x);
439  return *this;
440  }
441 
445  bool operator==(const Persistence_landscape_on_grid& rhs) const {
446  bool dbg = true;
447  if (this->values_of_landscapes.size() != rhs.values_of_landscapes.size()) {
448  if (dbg) std::cerr << "values_of_landscapes of incompatible sizes\n";
449  return false;
450  }
451  if (!almost_equal(this->grid_min, rhs.grid_min)) {
452  if (dbg) std::cerr << "grid_min not equal\n";
453  return false;
454  }
455  if (!almost_equal(this->grid_max, rhs.grid_max)) {
456  if (dbg) std::cerr << "grid_max not equal\n";
457  return false;
458  }
459  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
460  for (size_t aa = 0; aa != this->values_of_landscapes[i].size(); ++aa) {
461  if (!almost_equal(this->values_of_landscapes[i][aa], rhs.values_of_landscapes[i][aa])) {
462  if (dbg) {
463  std::cerr << "Problem in the position : " << i << " of values_of_landscapes. \n";
464  std::cerr << this->values_of_landscapes[i][aa] << " " << rhs.values_of_landscapes[i][aa] << std::endl;
465  }
466  return false;
467  }
468  }
469  }
470  return true;
471  }
472 
476  bool operator!=(const Persistence_landscape_on_grid& rhs) const { return !((*this) == rhs); }
477 
481  double compute_maximum() const {
482  // since the function can only be entirely positive or negative, the maximal value will be an extremal value in the
483  // arrays:
484  double max_value = -std::numeric_limits<double>::max();
485  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
486  if (this->values_of_landscapes[i].size()) {
487  if (this->values_of_landscapes[i][0] > max_value) max_value = this->values_of_landscapes[i][0];
488  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] > max_value)
489  max_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
490  }
491  }
492  return max_value;
493  }
494 
498  std::pair<double, double> compute_minimum_maximum() const {
499  // since the function can only be entirely positive or negative, the maximal value will be an extremal value in the
500  // arrays:
501  double max_value = -std::numeric_limits<double>::max();
502  double min_value = 0;
503  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
504  if (this->values_of_landscapes[i].size()) {
505  if (this->values_of_landscapes[i][0] > max_value) max_value = this->values_of_landscapes[i][0];
506  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] > max_value)
507  max_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
508 
509  if (this->values_of_landscapes[i][0] < min_value) min_value = this->values_of_landscapes[i][0];
510  if (this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] < min_value)
511  min_value = this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1];
512  }
513  }
514  return std::make_pair(min_value, max_value);
515  }
516 
521  std::pair<double, double> get_x_range(size_t level = 0) const {
522  return std::make_pair(this->grid_min, this->grid_max);
523  }
524 
529  std::pair<double, double> get_y_range(size_t level = 0) const { return this->compute_minimum_maximum(); }
530 
534  size_t number_of_nonzero_levels() const {
535  size_t result = 0;
536  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
537  if (this->values_of_landscapes[i].size() > result) result = this->values_of_landscapes[i].size();
538  }
539  return result;
540  }
541 
545  double compute_norm_of_landscape(double i) const {
546  std::vector<std::pair<double, double> > p;
547  Persistence_landscape_on_grid l(p, this->grid_min, this->grid_max, this->values_of_landscapes.size() - 1);
548 
549  if (i < std::numeric_limits<double>::max()) {
550  return compute_distance_of_landscapes_on_grid(*this, l, i);
551  } else {
553  }
554  }
555 
559  double operator()(unsigned level, double x) const { return this->compute_value_at_a_given_point(level, x); }
560 
565  const Persistence_landscape_on_grid& second);
566 
573  void abs() {
574  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
575  for (size_t j = 0; j != this->values_of_landscapes[i].size(); ++j) {
576  this->values_of_landscapes[i][j] = std::abs(this->values_of_landscapes[i][j]);
577  }
578  }
579  }
580 
584  size_t size() const { return this->number_of_nonzero_levels(); }
585 
589  double find_max(unsigned lambda) const {
590  double max_value = -std::numeric_limits<double>::max();
591  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
592  if (this->values_of_landscapes[i].size() > lambda) {
593  if (this->values_of_landscapes[i][lambda] > max_value) max_value = this->values_of_landscapes[i][lambda];
594  }
595  }
596  return max_value;
597  }
598 
603  const Persistence_landscape_on_grid& l2) {
604  if (!check_if_defined_on_the_same_domain(l1, l2))
605  throw "Landscapes are not defined on the same grid, the program will now terminate";
606  size_t maximal_level = l1.number_of_nonzero_levels();
607  double result = 0;
608  for (size_t i = 0; i != maximal_level; ++i) {
609  result += compute_inner_product(l1, l2, i);
610  }
611  return result;
612  }
613 
618  size_t level) {
619  bool dbg = false;
620 
621  if (!check_if_defined_on_the_same_domain(l1, l2))
622  throw "Landscapes are not defined on the same grid, the program will now terminate";
623  double result = 0;
624 
625  double dx = (l1.grid_max - l1.grid_min) / static_cast<double>(l1.values_of_landscapes.size() - 1);
626 
627  double previous_x = l1.grid_min - dx;
628  double previous_y_l1 = 0;
629  double previous_y_l2 = 0;
630  for (size_t i = 0; i != l1.values_of_landscapes.size(); ++i) {
631  if (dbg) std::cerr << "i : " << i << std::endl;
632 
633  double current_x = previous_x + dx;
634  double current_y_l1 = 0;
635  if (l1.values_of_landscapes[i].size() > level) current_y_l1 = l1.values_of_landscapes[i][level];
636 
637  double current_y_l2 = 0;
638  if (l2.values_of_landscapes[i].size() > level) current_y_l2 = l2.values_of_landscapes[i][level];
639 
640  if (dbg) {
641  std::cerr << "previous_x : " << previous_x << std::endl;
642  std::cerr << "previous_y_l1 : " << previous_y_l1 << std::endl;
643  std::cerr << "current_y_l1 : " << current_y_l1 << std::endl;
644  std::cerr << "previous_y_l2 : " << previous_y_l2 << std::endl;
645  std::cerr << "current_y_l2 : " << current_y_l2 << std::endl;
646  }
647 
648  std::pair<double, double> l1_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l1),
649  std::make_pair(current_x, current_y_l1));
650  std::pair<double, double> l2_coords = compute_parameters_of_a_line(std::make_pair(previous_x, previous_y_l2),
651  std::make_pair(current_x, current_y_l2));
652 
653  // 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
654  // are a,b,c,d:
655  double a = l1_coords.first;
656  double b = l1_coords.second;
657 
658  double c = l2_coords.first;
659  double d = l2_coords.second;
660 
661  if (dbg) {
662  std::cerr << "Here are the formulas for a line: \n";
663  std::cerr << "a : " << a << std::endl;
664  std::cerr << "b : " << b << std::endl;
665  std::cerr << "c : " << c << std::endl;
666  std::cerr << "d : " << d << std::endl;
667  }
668 
669  // now, to compute the inner product in this interval we need to compute the integral of (ax+b)(cx+d) = acx^2 +
670  // (ad+bc)x + bd in the interval from previous_x to current_x:
671  // The integral is ac/3*x^3 + (ac+bd)/2*x^2 + bd*x
672 
673  double added_value = (a * c / 3 * current_x * current_x * current_x +
674  (a * d + b * c) / 2 * current_x * current_x + b * d * current_x) -
675  (a * c / 3 * previous_x * previous_x * previous_x +
676  (a * d + b * c) / 2 * previous_x * previous_x + b * d * previous_x);
677 
678  if (dbg) {
679  std::cerr << "Value of the integral on the left end i.e. : " << previous_x << " is : "
680  << a * c / 3 * previous_x * previous_x * previous_x + (a * d + b * c) / 2 * previous_x * previous_x +
681  b * d * previous_x
682  << std::endl;
683  std::cerr << "Value of the integral on the right end i.e. : " << current_x << " is "
684  << a * c / 3 * current_x * current_x * current_x + (a * d + b * c) / 2 * current_x * current_x +
685  b * d * current_x
686  << std::endl;
687  }
688 
689  result += added_value;
690 
691  if (dbg) {
692  std::cerr << "added_value : " << added_value << std::endl;
693  std::cerr << "result : " << result << std::endl;
694  getchar();
695  }
696 
697  previous_x = current_x;
698  previous_y_l1 = current_y_l1;
699  previous_y_l2 = current_y_l2;
700  }
701  return result;
702  }
703 
713  const Persistence_landscape_on_grid& second, double p) {
714  bool dbg = false;
715  // This is what we want to compute: (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p). We will do it one step at a
716  // time:
717 
718  if (dbg) {
719  std::cerr << "first : " << first << std::endl;
720  std::cerr << "second : " << second << std::endl;
721  getchar();
722  }
723 
724  // first-second :
725  Persistence_landscape_on_grid lan = first - second;
726 
727  if (dbg) {
728  std::cerr << "Difference : " << lan << std::endl;
729  }
730 
731  //| first-second |:
732  lan.abs();
733 
734  if (dbg) {
735  std::cerr << "Abs : " << lan << std::endl;
736  }
737 
738  if (p < std::numeric_limits<double>::max()) {
739  // \int_{- \infty}^{+\infty}| first-second |^p
740  double result;
741  if (p != 1) {
742  if (dbg) {
743  std::cerr << "p : " << p << std::endl;
744  getchar();
745  }
746  result = lan.compute_integral_of_landscape(p);
747  if (dbg) {
748  std::cerr << "integral : " << result << std::endl;
749  getchar();
750  }
751  } else {
752  result = lan.compute_integral_of_landscape();
753  if (dbg) {
754  std::cerr << "integral, without power : " << result << std::endl;
755  getchar();
756  }
757  }
758  // (\int_{- \infty}^{+\infty}| first-second |^p)^(1/p)
759  return pow(result, 1.0 / p);
760  } else {
761  // p == infty
762  return lan.compute_maximum();
763  }
764  }
765 
766  // Functions that are needed for that class to implement the concept.
767 
776  double project_to_R(int number_of_function) const {
777  return this->compute_integral_of_landscape((size_t)number_of_function);
778  }
779 
784  size_t number_of_projections_to_R() const { return number_of_functions_for_projections_to_reals; }
785 
790  std::vector<double> vectorize(int number_of_function) const {
791  // TODO(PD) think of something smarter over here
792  if ((number_of_function < 0) || ((size_t)number_of_function >= this->values_of_landscapes.size())) {
793  throw "Wrong number of function\n";
794  }
795  std::vector<double> v(this->values_of_landscapes.size());
796  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
797  v[i] = 0;
798  if (this->values_of_landscapes[i].size() > (size_t)number_of_function) {
799  v[i] = this->values_of_landscapes[i][number_of_function];
800  }
801  }
802  return v;
803  }
804 
809  size_t number_of_vectorize_functions() const { return number_of_functions_for_vectorization; }
810 
815  void compute_average(const std::vector<Persistence_landscape_on_grid*>& to_average) {
816  bool dbg = false;
817  // After execution of this procedure, the average is supposed to be in the current object. To make sure that this is
818  // the case, we need to do some cleaning first.
819  this->values_of_landscapes.clear();
820  this->grid_min = this->grid_max = 0;
821 
822  // if there is nothing to average, then the average is a zero landscape.
823  if (to_average.size() == 0) return;
824 
825  // now we need to check if the grids in all objects of to_average are the same:
826  for (size_t i = 0; i != to_average.size(); ++i) {
827  if (!check_if_defined_on_the_same_domain(*(to_average[0]), *(to_average[i])))
828  throw "Two grids are not compatible";
829  }
830 
831  this->values_of_landscapes = std::vector<std::vector<double> >((to_average[0])->values_of_landscapes.size());
832  this->grid_min = (to_average[0])->grid_min;
833  this->grid_max = (to_average[0])->grid_max;
834 
835  if (dbg) {
836  std::cerr << "Computations of average. The data from the current landscape have been cleared. We are ready to do "
837  "the computations. \n";
838  }
839 
840  // for every point in the grid:
841  for (size_t grid_point = 0; grid_point != (to_average[0])->values_of_landscapes.size(); ++grid_point) {
842  // set up a vector of the correct size:
843  size_t maximal_size_of_vector = 0;
844  for (size_t land_no = 0; land_no != to_average.size(); ++land_no) {
845  if ((to_average[land_no])->values_of_landscapes[grid_point].size() > maximal_size_of_vector)
846  maximal_size_of_vector = (to_average[land_no])->values_of_landscapes[grid_point].size();
847  }
848  this->values_of_landscapes[grid_point] = std::vector<double>(maximal_size_of_vector);
849 
850  if (dbg) {
851  std::cerr << "We are considering the point : " << grid_point
852  << " of the grid. In this point, there are at most : " << maximal_size_of_vector
853  << " nonzero landscape functions \n";
854  }
855 
856  // and compute an arithmetic average:
857  for (size_t land_no = 0; land_no != to_average.size(); ++land_no) {
858  // summing:
859  for (size_t i = 0; i != (to_average[land_no])->values_of_landscapes[grid_point].size(); ++i) {
860  // compute the average in a smarter way.
861  this->values_of_landscapes[grid_point][i] += (to_average[land_no])->values_of_landscapes[grid_point][i];
862  }
863  }
864  // normalizing:
865  for (size_t i = 0; i != this->values_of_landscapes[grid_point].size(); ++i) {
866  this->values_of_landscapes[grid_point][i] /= static_cast<double>(to_average.size());
867  }
868  }
869  } // compute_average
870 
877  double distance(const Persistence_landscape_on_grid& second, double power = 1) const {
878  if (power < std::numeric_limits<double>::max()) {
879  return compute_distance_of_landscapes_on_grid(*this, second, power);
880  } else {
881  return compute_max_norm_distance_of_landscapes(*this, second);
882  }
883  }
884 
891  return compute_inner_product((*this), second);
892  }
893 
894  // end of implementation of functions needed for concepts.
895 
899  std::vector<std::vector<double> > output_for_visualization() const { return this->values_of_landscapes; }
900 
910  void plot(const char* filename, size_t from_, size_t to_) const {
911  this->plot(filename, std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
912  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), from_, to_);
913  }
914 
919  void plot(const char* filename, double min_x = std::numeric_limits<double>::max(),
920  double max_x = std::numeric_limits<double>::max(), double min_y = std::numeric_limits<double>::max(),
921  double max_y = std::numeric_limits<double>::max(), size_t from_ = std::numeric_limits<size_t>::max(),
922  size_t to_ = std::numeric_limits<size_t>::max()) const;
923 
924  protected:
925  double grid_min;
926  double grid_max;
927  std::vector<std::vector<double> > values_of_landscapes;
928  size_t number_of_functions_for_vectorization;
929  size_t number_of_functions_for_projections_to_reals;
930 
931  void set_up_numbers_of_functions_for_vectorization_and_projections_to_reals() {
932  // warning, this function can be only called after filling in the values_of_landscapes vector.
933  this->number_of_functions_for_vectorization = this->values_of_landscapes.size();
934  this->number_of_functions_for_projections_to_reals = this->values_of_landscapes.size();
935  }
936  void set_up_values_of_landscapes(const std::vector<std::pair<double, double> >& p, double grid_min_, double grid_max_,
937  size_t number_of_points_,
938  unsigned number_of_levels = std::numeric_limits<unsigned>::max());
939  Persistence_landscape_on_grid multiply_lanscape_by_real_number_not_overwrite(double x) const;
940 };
941 
942 void Persistence_landscape_on_grid::set_up_values_of_landscapes(const std::vector<std::pair<double, double> >& p,
943  double grid_min_, double grid_max_,
944  size_t number_of_points_, unsigned number_of_levels) {
945  bool dbg = false;
946  if (dbg) {
947  std::cerr << "Here is the procedure : set_up_values_of_landscapes. The parameters are : grid_min_ : " << grid_min_
948  << ", grid_max_ : " << grid_max_ << ", number_of_points_ : " << number_of_points_
949  << ", number_of_levels: " << number_of_levels << std::endl;
950  std::cerr << "Here are the intervals at our disposal : \n";
951  for (size_t i = 0; i != p.size(); ++i) {
952  std::cerr << p[i].first << " , " << p[i].second << std::endl;
953  }
954  }
955 
956  if ((grid_min_ == std::numeric_limits<double>::max()) || (grid_max_ == std::numeric_limits<double>::max())) {
957  // in this case, we need to find grid_min_ and grid_min_ based on the data.
958  double min = std::numeric_limits<double>::max();
959  double max = std::numeric_limits<double>::min();
960  for (size_t i = 0; i != p.size(); ++i) {
961  if (p[i].first < min) min = p[i].first;
962  if (p[i].second > max) max = p[i].second;
963  }
964  if (grid_min_ == std::numeric_limits<double>::max()) {
965  grid_min_ = min;
966  } else {
967  // in this case grid_max_ == std::numeric_limits<double>::max()
968  grid_max_ = max;
969  }
970  }
971 
972  // if number_of_levels == std::numeric_limits<size_t>::max(), then we will have all the nonzero values of landscapes,
973  // and will store them in a vector
974  // if number_of_levels != std::numeric_limits<size_t>::max(), then we will use those vectors as heaps.
975  this->values_of_landscapes = std::vector<std::vector<double> >(number_of_points_ + 1);
976 
977  this->grid_min = grid_min_;
978  this->grid_max = grid_max_;
979 
980  if (grid_max_ <= grid_min_) {
981  throw "Wrong parameters of grid_min and grid_max given to the procedure. The program will now terminate.\n";
982  }
983 
984  double dx = (grid_max_ - grid_min_) / static_cast<double>(number_of_points_);
985  // for every interval in the diagram:
986  for (size_t int_no = 0; int_no != p.size(); ++int_no) {
987  size_t grid_interval_begin = (p[int_no].first - grid_min_) / dx;
988  size_t grid_interval_end = (p[int_no].second - grid_min_) / dx;
989  size_t grid_interval_midpoint = (size_t)(0.5 * (grid_interval_begin + grid_interval_end));
990 
991  if (dbg) {
992  std::cerr << "Considering an interval : " << p[int_no].first << "," << p[int_no].second << std::endl;
993 
994  std::cerr << "grid_interval_begin : " << grid_interval_begin << std::endl;
995  std::cerr << "grid_interval_end : " << grid_interval_end << std::endl;
996  std::cerr << "grid_interval_midpoint : " << grid_interval_midpoint << std::endl;
997  }
998 
999  double landscape_value = dx;
1000  for (size_t i = grid_interval_begin + 1; i < grid_interval_midpoint; ++i) {
1001  if (dbg) {
1002  std::cerr << "Adding landscape value (going up) for a point : " << i << " equal : " << landscape_value
1003  << std::endl;
1004  }
1005  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1006  // we have a heap of no more that number_of_levels values.
1007  // Note that if we are using heaps, we want to know the shortest distance in the heap.
1008  // This is achieved by putting -distance to the heap.
1009  if (this->values_of_landscapes[i].size() >= number_of_levels) {
1010  // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
1011  // smallest element in the heap.
1012  if (-landscape_value < this->values_of_landscapes[i].front()) {
1013  // if it is, we remove the largest value in the heap, and move on.
1014  std::pop_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1015  this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] = -landscape_value;
1016  std::push_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1017  }
1018  } else {
1019  // in this case we are still filling in the array.
1020  this->values_of_landscapes[i].push_back(-landscape_value);
1021  if (this->values_of_landscapes[i].size() == number_of_levels - 1) {
1022  // this->values_of_landscapes[i].size() == number_of_levels
1023  // in this case we need to create the heap.
1024  std::make_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1025  }
1026  }
1027  } else {
1028  // we have vector of all values
1029  this->values_of_landscapes[i].push_back(landscape_value);
1030  }
1031  landscape_value += dx;
1032  }
1033  for (size_t i = grid_interval_midpoint; i <= grid_interval_end; ++i) {
1034  if (landscape_value > 0) {
1035  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1036  // we have a heap of no more that number_of_levels values
1037  if (this->values_of_landscapes[i].size() >= number_of_levels) {
1038  // in this case, the full heap is build, and we need to check if the landscape_value is not larger than the
1039  // smallest element in the heap.
1040  if (-landscape_value < this->values_of_landscapes[i].front()) {
1041  // if it is, we remove the largest value in the heap, and move on.
1042  std::pop_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1043  this->values_of_landscapes[i][this->values_of_landscapes[i].size() - 1] = -landscape_value;
1044  std::push_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1045  }
1046  } else {
1047  // in this case we are still filling in the array.
1048  this->values_of_landscapes[i].push_back(-landscape_value);
1049  if (this->values_of_landscapes[i].size() == number_of_levels - 1) {
1050  // this->values_of_landscapes[i].size() == number_of_levels
1051  // in this case we need to create the heap.
1052  std::make_heap(this->values_of_landscapes[i].begin(), this->values_of_landscapes[i].end());
1053  }
1054  }
1055  } else {
1056  this->values_of_landscapes[i].push_back(landscape_value);
1057  }
1058 
1059  if (dbg) {
1060  std::cerr << "Adding landscape value (going down) for a point : " << i << " equal : " << landscape_value
1061  << std::endl;
1062  }
1063  }
1064  landscape_value -= dx;
1065  }
1066  }
1067 
1068  if (number_of_levels != std::numeric_limits<unsigned>::max()) {
1069  // in this case, vectors are used as heaps. And, since we want to have the smallest element at the top of
1070  // each heap, we store minus distances. To get if right at the end, we need to multiply each value
1071  // in the heap by -1 to get real vector of distances.
1072  for (size_t pt = 0; pt != this->values_of_landscapes.size(); ++pt) {
1073  for (size_t j = 0; j != this->values_of_landscapes[pt].size(); ++j) {
1074  this->values_of_landscapes[pt][j] *= -1;
1075  }
1076  }
1077  }
1078 
1079  // and now we need to sort the values:
1080  for (size_t pt = 0; pt != this->values_of_landscapes.size(); ++pt) {
1081  std::sort(this->values_of_landscapes[pt].begin(), this->values_of_landscapes[pt].end(), std::greater<double>());
1082  }
1083 } // set_up_values_of_landscapes
1084 
1085 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
1086  double grid_min_, double grid_max_,
1087  size_t number_of_points_) {
1088  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_);
1089 } // Persistence_landscape_on_grid
1090 
1091 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const std::vector<std::pair<double, double> >& p,
1092  double grid_min_, double grid_max_,
1093  size_t number_of_points_,
1094  unsigned number_of_levels_of_landscape) {
1095  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1096 }
1097 
1098 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_,
1099  size_t number_of_points_, 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_);
1107 }
1108 
1109 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, double grid_min_, double grid_max_,
1110  size_t number_of_points_,
1111  unsigned number_of_levels_of_landscape,
1112  uint16_t dimension) {
1113  std::vector<std::pair<double, double> > p;
1114  if (dimension == std::numeric_limits<uint16_t>::max()) {
1115  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1116  } else {
1117  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1118  }
1119  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1120 }
1121 
1122 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, size_t number_of_points_,
1123  uint16_t dimension) {
1124  std::vector<std::pair<double, double> > p;
1125  if (dimension == std::numeric_limits<uint16_t>::max()) {
1126  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1127  } else {
1128  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1129  }
1130  double grid_min_ = std::numeric_limits<double>::max();
1131  double grid_max_ = -std::numeric_limits<double>::max();
1132  for (size_t i = 0; i != p.size(); ++i) {
1133  if (p[i].first < grid_min_) grid_min_ = p[i].first;
1134  if (p[i].second > grid_max_) grid_max_ = p[i].second;
1135  }
1136  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_);
1137 }
1138 
1139 Persistence_landscape_on_grid::Persistence_landscape_on_grid(const char* filename, size_t number_of_points_,
1140  unsigned number_of_levels_of_landscape,
1141  uint16_t dimension) {
1142  std::vector<std::pair<double, double> > p;
1143  if (dimension == std::numeric_limits<uint16_t>::max()) {
1144  p = read_persistence_intervals_in_one_dimension_from_file(filename);
1145  } else {
1146  p = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
1147  }
1148  double grid_min_ = std::numeric_limits<double>::max();
1149  double grid_max_ = -std::numeric_limits<double>::max();
1150  for (size_t i = 0; i != p.size(); ++i) {
1151  if (p[i].first < grid_min_) grid_min_ = p[i].first;
1152  if (p[i].second > grid_max_) grid_max_ = p[i].second;
1153  }
1154  this->set_up_values_of_landscapes(p, grid_min_, grid_max_, number_of_points_, number_of_levels_of_landscape);
1155 }
1156 
1158  std::ifstream in;
1159  in.open(filename);
1160  // check if the file exist.
1161  if (!in.good()) {
1162  std::cerr << "The file : " << filename << " do not exist. The program will now terminate \n";
1163  throw "The persistence landscape file do not exist. The program will now terminate \n";
1164  }
1165 
1166  size_t number_of_points_in_the_grid = 0;
1167  in >> this->grid_min >> this->grid_max >> number_of_points_in_the_grid;
1168 
1169  std::vector<std::vector<double> > v(number_of_points_in_the_grid);
1170  std::string line;
1171  std::getline(in, line);
1172  double number;
1173  for (size_t i = 0; i != number_of_points_in_the_grid; ++i) {
1174  // read a line of a file and convert it to a vector.
1175  std::vector<double> vv;
1176  std::getline(in, line);
1177  std::istringstream stream(line);
1178  while (stream >> number) {
1179  vv.push_back(number);
1180  }
1181  v[i] = vv;
1182  }
1183  this->values_of_landscapes = v;
1184  in.close();
1185 }
1186 
1187 void Persistence_landscape_on_grid::print_to_file(const char* filename) const {
1188  std::ofstream out;
1189  out.open(filename);
1190 
1191  // first we store the parameters of the grid:
1192  out << grid_min << std::endl << grid_max << std::endl << this->values_of_landscapes.size() << std::endl;
1193 
1194  // and now in the following lines, the values of this->values_of_landscapes for the following arguments:
1195  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
1196  for (size_t j = 0; j != this->values_of_landscapes[i].size(); ++j) {
1197  out << this->values_of_landscapes[i][j] << " ";
1198  }
1199  out << std::endl;
1200  }
1201 
1202  out.close();
1203 }
1204 
1205 void Persistence_landscape_on_grid::plot(const char* filename, double min_x, double max_x, double min_y, double max_y,
1206  size_t from_, size_t to_) const {
1207  // this program create a gnuplot script file that allows to plot persistence diagram.
1208  std::ofstream out;
1209 
1210  std::ostringstream gnuplot_script;
1211  gnuplot_script << filename << "_GnuplotScript";
1212  out.open(gnuplot_script.str().c_str());
1213 
1214  if (min_x == max_x) {
1215  std::pair<double, double> min_max = compute_minimum_maximum();
1216  out << "set xrange [" << this->grid_min << " : " << this->grid_max << "]" << std::endl;
1217  out << "set yrange [" << min_max.first << " : " << min_max.second << "]" << std::endl;
1218  } else {
1219  out << "set xrange [" << min_x << " : " << max_x << "]" << std::endl;
1220  out << "set yrange [" << min_y << " : " << max_y << "]" << std::endl;
1221  }
1222 
1224  double dx = (this->grid_max - this->grid_min) / static_cast<double>(this->values_of_landscapes.size() - 1);
1225 
1226  size_t from = 0;
1227  if (from_ != std::numeric_limits<size_t>::max()) {
1228  if (from_ < number_of_nonzero_levels) {
1229  from = from_;
1230  } else {
1231  return;
1232  }
1233  }
1234  size_t to = number_of_nonzero_levels;
1235  if (to_ != std::numeric_limits<size_t>::max()) {
1236  if (to_ < number_of_nonzero_levels) {
1237  to = to_;
1238  }
1239  }
1240 
1241  out << "plot ";
1242  for (size_t lambda = from; lambda != to; ++lambda) {
1243  out << " '-' using 1:2 notitle with lp";
1244  if (lambda + 1 != to) {
1245  out << ", \\";
1246  }
1247  out << std::endl;
1248  }
1249 
1250  for (size_t lambda = from; lambda != to; ++lambda) {
1251  double point = this->grid_min;
1252  for (size_t i = 0; i != this->values_of_landscapes.size(); ++i) {
1253  double value = 0;
1254  if (this->values_of_landscapes[i].size() > lambda) {
1255  value = this->values_of_landscapes[i][lambda];
1256  }
1257  out << point << " " << value << std::endl;
1258  point += dx;
1259  }
1260  out << "EOF" << std::endl;
1261  }
1262  std::cout << "To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'"
1263  << gnuplot_script.str().c_str() << "\'\"" << std::endl;
1264 }
1265 
1266 template <typename T>
1267 Persistence_landscape_on_grid operation_on_pair_of_landscapes_on_grid(const Persistence_landscape_on_grid& land1,
1268  const Persistence_landscape_on_grid& land2) {
1269  // first we need to check if the domains are the same:
1270  if (!check_if_defined_on_the_same_domain(land1, land2)) throw "Two grids are not compatible";
1271 
1272  T oper;
1274  result.values_of_landscapes = std::vector<std::vector<double> >(land1.values_of_landscapes.size());
1275  result.grid_min = land1.grid_min;
1276  result.grid_max = land1.grid_max;
1277 
1278  // now we perform the operations:
1279  for (size_t grid_point = 0; grid_point != land1.values_of_landscapes.size(); ++grid_point) {
1280  result.values_of_landscapes[grid_point] = std::vector<double>(
1281  std::max(land1.values_of_landscapes[grid_point].size(), land2.values_of_landscapes[grid_point].size()));
1282  for (size_t lambda = 0; lambda != std::max(land1.values_of_landscapes[grid_point].size(),
1283  land2.values_of_landscapes[grid_point].size());
1284  ++lambda) {
1285  double value1 = 0;
1286  double value2 = 0;
1287  if (lambda < land1.values_of_landscapes[grid_point].size())
1288  value1 = land1.values_of_landscapes[grid_point][lambda];
1289  if (lambda < land2.values_of_landscapes[grid_point].size())
1290  value2 = land2.values_of_landscapes[grid_point][lambda];
1291  result.values_of_landscapes[grid_point][lambda] = oper(value1, value2);
1292  }
1293  }
1294 
1295  return result;
1296 }
1297 
1298 Persistence_landscape_on_grid Persistence_landscape_on_grid::multiply_lanscape_by_real_number_not_overwrite(
1299  double x) const {
1301  result.values_of_landscapes = std::vector<std::vector<double> >(this->values_of_landscapes.size());
1302  result.grid_min = this->grid_min;
1303  result.grid_max = this->grid_max;
1304 
1305  for (size_t grid_point = 0; grid_point != this->values_of_landscapes.size(); ++grid_point) {
1306  result.values_of_landscapes[grid_point] = std::vector<double>(this->values_of_landscapes[grid_point].size());
1307  for (size_t i = 0; i != this->values_of_landscapes[grid_point].size(); ++i) {
1308  result.values_of_landscapes[grid_point][i] = x * this->values_of_landscapes[grid_point][i];
1309  }
1310  }
1311 
1312  return result;
1313 }
1314 
1316  const Persistence_landscape_on_grid& second) {
1317  double result = 0;
1318 
1319  // first we need to check if first and second is defined on the same domain"
1320  if (!check_if_defined_on_the_same_domain(first, second)) throw "Two grids are not compatible";
1321 
1322  for (size_t i = 0; i != first.values_of_landscapes.size(); ++i) {
1323  for (size_t j = 0; j != std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size());
1324  ++j) {
1325  if (result < abs(first.values_of_landscapes[i][j] - second.values_of_landscapes[i][j])) {
1326  result = abs(first.values_of_landscapes[i][j] - second.values_of_landscapes[i][j]);
1327  }
1328  }
1329  if (first.values_of_landscapes[i].size() ==
1330  std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size())) {
1331  for (size_t j = first.values_of_landscapes[i].size(); j != second.values_of_landscapes[i].size(); ++j) {
1332  if (result < second.values_of_landscapes[i][j]) result = second.values_of_landscapes[i][j];
1333  }
1334  }
1335  if (second.values_of_landscapes[i].size() ==
1336  std::min(first.values_of_landscapes[i].size(), second.values_of_landscapes[i].size())) {
1337  for (size_t j = second.values_of_landscapes[i].size(); j != first.values_of_landscapes[i].size(); ++j) {
1338  if (result < first.values_of_landscapes[i][j]) result = first.values_of_landscapes[i][j];
1339  }
1340  }
1341  }
1342  return result;
1343 }
1344 
1345 } // namespace Persistence_representations
1346 } // namespace Gudhi
1347 
1348 #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:712
std::pair< double, double > get_x_range(size_t level=0) const
Definition: Persistence_landscape_on_grid.h:521
bool operator!=(const Persistence_landscape_on_grid &rhs) const
Definition: Persistence_landscape_on_grid.h:476
double distance(const Persistence_landscape_on_grid &second, double power=1) const
Definition: Persistence_landscape_on_grid.h:877
friend Persistence_landscape_on_grid operator*(const Persistence_landscape_on_grid &first, double con)
Definition: Persistence_landscape_on_grid.h:389
std::vector< double > vectorize(int number_of_function) const
Definition: Persistence_landscape_on_grid.h:790
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:1315
void print_to_file(const char *filename) const
Definition: Persistence_landscape_on_grid.h:1187
void compute_average(const std::vector< Persistence_landscape_on_grid *> &to_average)
Definition: Persistence_landscape_on_grid.h:815
void plot(const char *filename, size_t from_, size_t to_) const
Definition: Persistence_landscape_on_grid.h:910
friend Persistence_landscape_on_grid operator*(double con, const Persistence_landscape_on_grid &first)
Definition: Persistence_landscape_on_grid.h:396
Definition: SimplicialComplexForAlpha.h:26
double compute_integral_of_landscape() const
Definition: Persistence_landscape_on_grid.h:153
double operator()(unsigned level, double x) const
Definition: Persistence_landscape_on_grid.h:559
void load_landscape_from_file(const char *filename)
Definition: Persistence_landscape_on_grid.h:1157
Persistence_landscape_on_grid operator-=(const Persistence_landscape_on_grid &rhs)
Definition: Persistence_landscape_on_grid.h:419
double compute_integral_of_landscape(double p) const
Definition: Persistence_landscape_on_grid.h:206
double compute_value_at_a_given_point(unsigned level, double x) const
Definition: Persistence_landscape_on_grid.h:304
Persistence_landscape_on_grid()
Definition: Persistence_landscape_on_grid.h:77
void abs()
Definition: Persistence_landscape_on_grid.h:573
size_t number_of_nonzero_levels() const
Definition: Persistence_landscape_on_grid.h:534
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:357
friend Persistence_landscape_on_grid operator-(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:381
A class implementing persistence landscapes by approximating them on a collection of grid points...
Definition: Persistence_landscape_on_grid.h:72
Persistence_landscape_on_grid operator+=(const Persistence_landscape_on_grid &rhs)
Definition: Persistence_landscape_on_grid.h:411
friend double compute_inner_product(const Persistence_landscape_on_grid &l1, const Persistence_landscape_on_grid &l2)
Definition: Persistence_landscape_on_grid.h:602
size_t size() const
Definition: Persistence_landscape_on_grid.h:584
std::pair< double, double > compute_minimum_maximum() const
Definition: Persistence_landscape_on_grid.h:498
friend std::ostream & operator<<(std::ostream &out, const Persistence_landscape_on_grid &land)
Definition: Persistence_landscape_on_grid.h:281
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:617
double compute_norm_of_landscape(double i) const
Definition: Persistence_landscape_on_grid.h:545
size_t number_of_vectorize_functions() const
Definition: Persistence_landscape_on_grid.h:809
friend Persistence_landscape_on_grid operator+(const Persistence_landscape_on_grid &first, const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:373
std::pair< double, double > get_y_range(size_t level=0) const
Definition: Persistence_landscape_on_grid.h:529
std::vector< std::vector< double > > output_for_visualization() const
Definition: Persistence_landscape_on_grid.h:899
double compute_maximum() const
Definition: Persistence_landscape_on_grid.h:481
double compute_scalar_product(const Persistence_landscape_on_grid &second)
Definition: Persistence_landscape_on_grid.h:890
double project_to_R(int number_of_function) const
Definition: Persistence_landscape_on_grid.h:776
Persistence_landscape_on_grid operator/=(double x)
Definition: Persistence_landscape_on_grid.h:436
double compute_integral_of_landscape(double p, size_t level) const
Definition: Persistence_landscape_on_grid.h:219
size_t number_of_projections_to_R() const
Definition: Persistence_landscape_on_grid.h:784
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:365
double compute_integral_of_landscape(size_t level) const
Definition: Persistence_landscape_on_grid.h:165
Persistence_landscape_on_grid operator*=(double x)
Definition: Persistence_landscape_on_grid.h:428
double find_max(unsigned lambda) const
Definition: Persistence_landscape_on_grid.h:589
bool operator==(const Persistence_landscape_on_grid &rhs) const
Definition: Persistence_landscape_on_grid.h:445
GUDHI  Version 2.2.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Thu Jun 14 2018 15:00:54 for GUDHI by Doxygen 1.8.13