23 #ifndef PERSISTENCE_HEAT_MAPS_H_ 24 #define PERSISTENCE_HEAT_MAPS_H_ 27 #include <gudhi/read_persistence_from_file.h> 28 #include <gudhi/common_persistence_representations.h> 42 namespace Persistence_representations {
48 std::vector<std::vector<double> > create_Gaussian_filter(
size_t pixel_radius,
double sigma) {
54 double sigma_sqr = sigma * sigma;
60 std::vector<std::vector<double> > kernel(2 * pixel_radius + 1);
61 for (
size_t i = 0; i != kernel.size(); ++i) {
62 std::vector<double> v(2 * pixel_radius + 1, 0);
67 std::cerr <<
"Kernel initialize \n";
68 std::cerr <<
"pixel_radius : " << pixel_radius << std::endl;
69 std::cerr <<
"kernel.size() : " << kernel.size() << std::endl;
73 for (
int x = -pixel_radius; x <= static_cast<int>(pixel_radius); x++) {
74 for (
int y = -pixel_radius; y <= static_cast<int>(pixel_radius); y++) {
75 double real_x = 2 * sigma * x / pixel_radius;
76 double real_y = 2 * sigma * y / pixel_radius;
77 r = sqrt(real_x * real_x + real_y * real_y);
78 kernel[x + pixel_radius][y + pixel_radius] = (exp(-(r * r) / sigma_sqr)) / (3.141592 * sigma_sqr);
79 sum += kernel[x + pixel_radius][y + pixel_radius];
84 for (
size_t i = 0; i != kernel.size(); ++i) {
85 for (
size_t j = 0; j != kernel[i].size(); ++j) {
91 std::cerr <<
"Here is the kernel : \n";
92 for (
size_t i = 0; i != kernel.size(); ++i) {
93 for (
size_t j = 0; j != kernel[i].size(); ++j) {
94 std::cerr << kernel[i][j] <<
" ";
96 std::cerr << std::endl;
117 double operator()(
const std::pair<double, double>& point_in_diagram) {
return 1; }
127 double operator()(
const std::pair<double, double>& point_in_diagram) {
129 return sqrt(pow((point_in_diagram.first - (point_in_diagram.first + point_in_diagram.second) / 2.0), 2) +
130 pow((point_in_diagram.second - (point_in_diagram.first + point_in_diagram.second) / 2.0), 2));
141 double operator()(
const std::pair<double, double>& point_in_diagram) {
142 return pow((point_in_diagram.first - (point_in_diagram.first + point_in_diagram.second) / 2.0), 2) +
143 pow((point_in_diagram.second - (point_in_diagram.first + point_in_diagram.second) / 2.0), 2);
154 double operator()(
const std::pair<double, double>& point_in_diagram) {
155 return atan(point_in_diagram.second - point_in_diagram.first);
169 double operator()(
const std::pair<double, double>& point_in_diagram) {
170 return (point_in_diagram.second - point_in_diagram.first) / this->letngth_of_maximal_interval;
174 double letngth_of_maximal_interval;
186 template <
typename Scalling_of_kernels = constant_scaling_function>
194 Scalling_of_kernels f;
196 this->erase_below_diagonal =
false;
197 this->min_ = this->max_ = 0;
198 this->set_up_parameters_for_basic_classes();
215 std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1),
216 bool erase_below_diagonal =
false,
size_t number_of_pixels = 1000,
217 double min_ = std::numeric_limits<double>::max(),
218 double max_ = std::numeric_limits<double>::max());
241 Persistence_heat_maps(
const char* filename, std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1),
242 bool erase_below_diagonal =
false,
size_t number_of_pixels = 1000,
243 double min_ = std::numeric_limits<double>::max(),
244 double max_ = std::numeric_limits<double>::max(),
245 unsigned dimension = std::numeric_limits<unsigned>::max());
252 void compute_mean(
const std::vector<Persistence_heat_maps*>& maps);
259 void compute_median(
const std::vector<Persistence_heat_maps*>& maps);
264 void compute_percentage_of_active(
const std::vector<Persistence_heat_maps*>& maps,
size_t cutoff = 1);
272 void print_to_file(
const char* filename)
const;
278 void load_from_file(
const char* filename);
285 if (this->heat_map.size() != second.heat_map.size()) {
287 std::cerr <<
"this->heat_map.size() : " << this->heat_map.size()
288 <<
" \n second.heat_map.size() : " << second.heat_map.size() << std::endl;
291 if (this->min_ != second.min_) {
292 if (dbg) std::cerr <<
"this->min_ : " << this->min_ <<
", second.min_ : " << second.min_ << std::endl;
295 if (this->max_ != second.max_) {
296 if (dbg) std::cerr <<
"this->max_ : " << this->max_ <<
", second.max_ : " << second.max_ << std::endl;
306 inline double get_min()
const {
return this->min_; }
311 inline double get_max()
const {
return this->max_; }
318 if (!this->check_if_the_same(rhs)) {
319 if (dbg) std::cerr <<
"The domains are not the same \n";
322 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
323 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
324 if (!almost_equal(this->heat_map[i][j], rhs.heat_map[i][j])) {
326 std::cerr <<
"this->heat_map[" << i <<
"][" << j <<
"] = " << this->heat_map[i][j] << std::endl;
327 std::cerr <<
"rhs.heat_map[" << i <<
"][" << j <<
"] = " << rhs.heat_map[i][j] << std::endl;
344 void plot(
const char* filename)
const;
346 template <
typename Operation_type>
349 Operation_type operation) {
352 std::cerr <<
"Sizes of the heat maps are not compatible. The program will now terminate \n";
353 throw "Sizes of the heat maps are not compatible. The program will now terminate \n";
356 result.min_ = first.min_;
357 result.max_ = first.max_;
358 result.heat_map.reserve(first.heat_map.size());
359 for (
size_t i = 0; i != first.heat_map.size(); ++i) {
360 std::vector<double> v;
361 v.reserve(first.heat_map[i].size());
362 for (
size_t j = 0; j != first.heat_map[i].size(); ++j) {
363 v.push_back(operation(first.heat_map[i][j], second.heat_map[i][j]));
365 result.heat_map.push_back(v);
376 result.min_ = this->min_;
377 result.max_ = this->max_;
378 result.heat_map.reserve(this->heat_map.size());
379 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
380 std::vector<double> v;
381 v.reserve(this->heat_map[i].size());
382 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
383 v.push_back(this->heat_map[i][j] * scalar);
385 result.heat_map.push_back(v);
394 return operation_on_pair_of_heat_maps(first, second, std::plus<double>());
400 return operation_on_pair_of_heat_maps(first, second, std::minus<double>());
443 if (x == 0)
throw(
"In operator /=, division by 0. Program terminated.");
444 *
this = *
this * (1 / x);
454 std::vector<double> vectorize(
int number_of_function)
const;
468 double project_to_R(
int number_of_function)
const;
487 void compute_average(
const std::vector<Persistence_heat_maps*>& to_average);
501 std::pair<double, double>
get_x_range()
const {
return std::make_pair(this->min_, this->max_); }
506 std::pair<double, double>
get_y_range()
const {
return this->get_x_range(); }
510 std::vector<std::vector<double> > check_and_initialize_maps(
const std::vector<Persistence_heat_maps*>& maps);
511 size_t number_of_functions_for_vectorization;
512 size_t number_of_functions_for_projections_to_reals;
513 void construct(
const std::vector<std::pair<double, double> >& intervals_,
514 std::vector<std::vector<double> > filter = create_Gaussian_filter(5, 1),
516 bool erase_below_diagonal =
false,
size_t number_of_pixels = 1000,
517 double min_ = std::numeric_limits<double>::max(),
double max_ = std::numeric_limits<double>::max());
519 void set_up_parameters_for_basic_classes() {
520 this->number_of_functions_for_vectorization = 1;
521 this->number_of_functions_for_projections_to_reals = 1;
525 Scalling_of_kernels f;
526 bool erase_below_diagonal;
529 std::vector<std::vector<double> > heat_map;
533 template <
typename Scalling_of_kernels>
535 std::vector<std::vector<double> > filter,
536 bool erase_below_diagonal,
size_t number_of_pixels,
537 double min_,
double max_) {
539 if (dbg) std::cerr <<
"Entering construct procedure \n";
540 Scalling_of_kernels f;
543 if (dbg) std::cerr <<
"min and max passed to construct() procedure: " << min_ <<
" " << max_ << std::endl;
546 if (dbg) std::cerr <<
"min and max parameters will be determined based on intervals \n";
548 min_ = std::numeric_limits<int>::max();
549 max_ = -std::numeric_limits<int>::max();
551 for (
size_t i = 0; i != intervals_.size(); ++i) {
552 if (intervals_[i].first < min_) min_ = intervals_[i].first;
553 if (intervals_[i].second > max_) max_ = intervals_[i].second;
559 min_ -= fabs(max_ - min_) / 100;
560 max_ += fabs(max_ - min_) / 100;
564 std::cerr <<
"min_ : " << min_ << std::endl;
565 std::cerr <<
"max_ : " << max_ << std::endl;
566 std::cerr <<
"number_of_pixels : " << number_of_pixels << std::endl;
574 std::vector<std::vector<double> > heat_map_;
575 for (
size_t i = 0; i != number_of_pixels; ++i) {
576 std::vector<double> v(number_of_pixels, 0);
577 heat_map_.push_back(v);
579 this->heat_map = heat_map_;
581 if (dbg) std::cerr <<
"Done creating of the heat map, now we will fill in the structure \n";
583 for (
size_t pt_nr = 0; pt_nr != intervals_.size(); ++pt_nr) {
586 static_cast<int>((intervals_[pt_nr].first - this->min_) / (this->max_ - this->min_) * number_of_pixels);
588 static_cast<int>((intervals_[pt_nr].second - this->min_) / (this->max_ - this->min_) * number_of_pixels);
591 std::cerr <<
"point : " << intervals_[pt_nr].first <<
" , " << intervals_[pt_nr].second << std::endl;
592 std::cerr <<
"x_grid : " << x_grid << std::endl;
593 std::cerr <<
"y_grid : " << y_grid << std::endl;
598 x_grid -= filter.size() / 2;
599 y_grid -= filter.size() / 2;
603 std::cerr <<
"After shift : \n";
604 std::cerr <<
"x_grid : " << x_grid << std::endl;
605 std::cerr <<
"y_grid : " << y_grid << std::endl;
608 double scaling_value = this->f(intervals_[pt_nr]);
610 for (
size_t i = 0; i != filter.size(); ++i) {
611 for (
size_t j = 0; j != filter.size(); ++j) {
613 if (((x_grid + i) >= 0) && (x_grid + i < this->heat_map.size()) && ((y_grid + j) >= 0) &&
614 (y_grid + j < this->heat_map.size())) {
616 std::cerr << y_grid + j <<
" " << x_grid + i << std::endl;
618 this->heat_map[y_grid + j][x_grid + i] += scaling_value * filter[i][j];
620 std::cerr <<
"Position : (" << x_grid + i <<
"," << y_grid + j
621 <<
") got increased by the value : " << filter[i][j] << std::endl;
629 if (erase_below_diagonal) {
630 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
631 for (
size_t j = i; j != this->heat_map.size(); ++j) {
632 this->heat_map[i][j] = 0;
638 template <
typename Scalling_of_kernels>
640 const std::vector<std::pair<double, double> >& interval, std::vector<std::vector<double> > filter,
641 bool erase_below_diagonal,
size_t number_of_pixels,
double min_,
double max_) {
642 this->construct(interval, filter, erase_below_diagonal, number_of_pixels, min_, max_);
643 this->set_up_parameters_for_basic_classes();
646 template <
typename Scalling_of_kernels>
648 std::vector<std::vector<double> > filter,
649 bool erase_below_diagonal,
size_t number_of_pixels,
650 double min_,
double max_,
unsigned dimension) {
651 std::vector<std::pair<double, double> > intervals_;
652 if (dimension == std::numeric_limits<unsigned>::max()) {
653 intervals_ = read_persistence_intervals_in_one_dimension_from_file(filename);
655 intervals_ = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
657 this->construct(intervals_, filter, erase_below_diagonal, number_of_pixels, min_, max_);
658 this->set_up_parameters_for_basic_classes();
661 template <
typename Scalling_of_kernels>
663 const std::vector<Persistence_heat_maps*>& maps) {
665 for (
size_t i = 0; i != maps.size(); ++i) {
666 if (maps[i]->heat_map.size() != maps[0]->heat_map.size()) {
667 std::cerr <<
"Sizes of Persistence_heat_maps are not compatible. The program will terminate now \n";
668 throw "Sizes of Persistence_heat_maps are not compatible. The program will terminate now \n";
670 if (maps[i]->heat_map[0].size() != maps[0]->heat_map[0].size()) {
671 std::cerr <<
"Sizes of Persistence_heat_maps are not compatible. The program will terminate now \n";
672 throw "Sizes of Persistence_heat_maps are not compatible. The program will terminate now \n";
675 std::vector<std::vector<double> > heat_maps(maps[0]->heat_map.size());
676 for (
size_t i = 0; i != maps[0]->heat_map.size(); ++i) {
677 std::vector<double> v(maps[0]->heat_map[0].size(), 0);
683 template <
typename Scalling_of_kernels>
685 std::vector<std::vector<double> > heat_maps = this->check_and_initialize_maps(maps);
687 std::vector<double> to_compute_median(maps.size());
688 for (
size_t i = 0; i != heat_maps.size(); ++i) {
689 for (
size_t j = 0; j != heat_maps[i].size(); ++j) {
690 for (
size_t map_no = 0; map_no != maps.size(); ++map_no) {
691 to_compute_median[map_no] = maps[map_no]->heat_map[i][j];
693 std::nth_element(to_compute_median.begin(), to_compute_median.begin() + to_compute_median.size() / 2,
694 to_compute_median.end());
695 heat_maps[i][j] = to_compute_median[to_compute_median.size() / 2];
698 this->heat_map = heat_maps;
699 this->min_ = maps[0]->min_;
700 this->max_ = maps[0]->max_;
703 template <
typename Scalling_of_kernels>
705 std::vector<std::vector<double> > heat_maps = this->check_and_initialize_maps(maps);
706 for (
size_t i = 0; i != heat_maps.size(); ++i) {
707 for (
size_t j = 0; j != heat_maps[i].size(); ++j) {
709 for (
size_t map_no = 0; map_no != maps.size(); ++map_no) {
710 mean += maps[map_no]->heat_map[i][j];
712 heat_maps[i][j] = mean /
static_cast<double>(maps.size());
715 this->heat_map = heat_maps;
716 this->min_ = maps[0]->min_;
717 this->max_ = maps[0]->max_;
720 template <
typename Scalling_of_kernels>
722 const std::vector<Persistence_heat_maps*>& maps,
size_t cutoff) {
723 std::vector<std::vector<double> > heat_maps = this->check_and_initialize_maps(maps);
725 for (
size_t i = 0; i != heat_maps.size(); ++i) {
726 for (
size_t j = 0; j != heat_maps[i].size(); ++j) {
727 size_t number_of_active_levels = 0;
728 for (
size_t map_no = 0; map_no != maps.size(); ++map_no) {
729 if (maps[map_no]->heat_map[i][j]) number_of_active_levels++;
731 if (number_of_active_levels > cutoff) {
732 heat_maps[i][j] = number_of_active_levels;
738 this->heat_map = heat_maps;
739 this->min_ = maps[0]->min_;
740 this->max_ = maps[0]->max_;
743 template <
typename Scalling_of_kernels>
746 std::stringstream gnuplot_script;
747 gnuplot_script << filename <<
"_GnuplotScript";
749 out.open(gnuplot_script.str().c_str());
750 out <<
"plot '-' matrix with image" << std::endl;
751 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
752 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
753 out << this->heat_map[i][j] <<
" ";
758 std::cout <<
"To visualize, install gnuplot and type the command: gnuplot -persist -e \"load \'" 759 << gnuplot_script.str().c_str() <<
"\'\"" << std::endl;
762 template <
typename Scalling_of_kernels>
768 out << this->min_ <<
" " << this->max_ << std::endl;
769 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
770 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
771 out << this->heat_map[i][j] <<
" ";
778 template <
typename Scalling_of_kernels>
787 std::cerr <<
"The file : " << filename <<
" do not exist. The program will now terminate \n";
788 throw "The persistence landscape file do not exist. The program will now terminate \n";
793 in >> this->min_ >> this->max_;
795 std::cerr <<
"Reading the following values of min and max : " << this->min_ <<
" , " << this->max_ << std::endl;
799 std::getline(in, temp);
801 std::getline(in, temp);
802 std::stringstream lineSS;
805 std::vector<double> line_of_heat_map;
806 while (lineSS.good()) {
810 line_of_heat_map.push_back(point);
812 std::cout << point <<
" ";
816 std::cout << std::endl;
820 if (in.good()) this->heat_map.push_back(line_of_heat_map);
823 if (dbg) std::cout <<
"Done \n";
827 template <
typename Scalling_of_kernels>
830 size_t size_of_result = 0;
831 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
832 size_of_result += this->heat_map[i].size();
835 std::vector<double> result;
836 result.reserve(size_of_result);
838 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
839 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
840 result.push_back(this->heat_map[i][j]);
847 template <
typename Scalling_of_kernels>
850 if (!this->check_if_the_same(second)) {
851 std::cerr <<
"The persistence images are of non compatible sizes. We cannot therefore compute distance between " 852 "them. The program will now terminate";
853 throw "The persistence images are of non compatible sizes. The program will now terminate";
860 if (power < std::numeric_limits<double>::max()) {
861 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
862 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
863 distance += pow(fabs(this->heat_map[i][j] - second.heat_map[i][j]), power);
868 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
869 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
870 if (distance < fabs(this->heat_map[i][j] - second.heat_map[i][j])) {
871 distance = fabs(this->heat_map[i][j] - second.heat_map[i][j]);
879 template <
typename Scalling_of_kernels>
882 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
883 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
884 result += this->heat_map[i][j];
890 template <
typename Scalling_of_kernels>
892 const std::vector<Persistence_heat_maps*>& to_average) {
893 this->compute_mean(to_average);
896 template <
typename Scalling_of_kernels>
899 if (!this->check_if_the_same(second)) {
900 std::cerr <<
"The persistence images are of non compatible sizes. We cannot therefore compute distance between " 901 "them. The program will now terminate";
902 throw "The persistence images are of non compatible sizes. The program will now terminate";
907 double scalar_prod = 0;
908 for (
size_t i = 0; i != this->heat_map.size(); ++i) {
909 for (
size_t j = 0; j != this->heat_map[i].size(); ++j) {
910 scalar_prod += this->heat_map[i][j] * second.heat_map[i][j];
919 #endif // PERSISTENCE_HEAT_MAPS_H_ size_t number_of_vectorize_functions() const
Definition: Persistence_heat_maps.h:459
void compute_percentage_of_active(const std::vector< Persistence_heat_maps *> &maps, size_t cutoff=1)
Definition: Persistence_heat_maps.h:721
size_t number_of_projections_to_R() const
Definition: Persistence_heat_maps.h:473
bool check_if_the_same(const Persistence_heat_maps &second) const
Definition: Persistence_heat_maps.h:283
double get_min() const
Definition: Persistence_heat_maps.h:306
std::pair< double, double > get_x_range() const
Definition: Persistence_heat_maps.h:501
void compute_average(const std::vector< Persistence_heat_maps *> &to_average)
Definition: Persistence_heat_maps.h:891
void load_from_file(const char *filename)
Definition: Persistence_heat_maps.h:779
bool operator==(const Persistence_heat_maps &rhs) const
Definition: Persistence_heat_maps.h:316
Definition: Persistence_heat_maps.h:152
A class implementing persistence heat maps.
Definition: Persistence_heat_maps.h:187
Persistence_heat_maps multiply_by_scalar(double scalar) const
Definition: Persistence_heat_maps.h:374
std::vector< double > vectorize(int number_of_function) const
Definition: Persistence_heat_maps.h:828
Persistence_heat_maps operator/=(double x)
Definition: Persistence_heat_maps.h:442
double project_to_R(int number_of_function) const
Definition: Persistence_heat_maps.h:880
std::pair< double, double > get_y_range() const
Definition: Persistence_heat_maps.h:506
Persistence_heat_maps operator*=(double x)
Definition: Persistence_heat_maps.h:435
Persistence_heat_maps operator*(double scalar)
Definition: Persistence_heat_maps.h:417
friend Persistence_heat_maps operator-(const Persistence_heat_maps &first, const Persistence_heat_maps &second)
Definition: Persistence_heat_maps.h:399
Definition: SimplicialComplexForAlpha.h:26
void compute_median(const std::vector< Persistence_heat_maps *> &maps)
Definition: Persistence_heat_maps.h:684
void plot(const char *filename) const
Definition: Persistence_heat_maps.h:744
friend Persistence_heat_maps operator*(const Persistence_heat_maps &A, double scalar)
Definition: Persistence_heat_maps.h:411
void print_to_file(const char *filename) const
Definition: Persistence_heat_maps.h:763
double compute_scalar_product(const Persistence_heat_maps &second_) const
Definition: Persistence_heat_maps.h:897
Definition: Persistence_heat_maps.h:139
friend Persistence_heat_maps operator+(const Persistence_heat_maps &first, const Persistence_heat_maps &second)
Definition: Persistence_heat_maps.h:393
double distance(const Persistence_heat_maps &second_, double power=1) const
Definition: Persistence_heat_maps.h:848
friend Persistence_heat_maps operator*(double scalar, const Persistence_heat_maps &A)
Definition: Persistence_heat_maps.h:405
Definition: Persistence_heat_maps.h:125
Persistence_heat_maps()
Definition: Persistence_heat_maps.h:193
void compute_mean(const std::vector< Persistence_heat_maps *> &maps)
Definition: Persistence_heat_maps.h:704
Definition: Persistence_heat_maps.h:166
Definition: Persistence_heat_maps.h:115
Persistence_heat_maps operator+=(const Persistence_heat_maps &rhs)
Definition: Persistence_heat_maps.h:421
bool operator!=(const Persistence_heat_maps &rhs) const
Definition: Persistence_heat_maps.h:339
double get_max() const
Definition: Persistence_heat_maps.h:311
Persistence_heat_maps operator-=(const Persistence_heat_maps &rhs)
Definition: Persistence_heat_maps.h:428