Loading...
Searching...
No Matches
PSSK.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): Pawel Dlotko
4 *
5 * Copyright (C) 2016 Inria
6 *
7 * Modification(s):
8 * - 2025/06 Hannah Schreiber: Various small bug fixes (missing `inline`s, `DEBUG_TRACES`s etc.)
9 * - YYYY/MM Author: Description of the modification
10 */
11
12#ifndef PSSK_H_
13#define PSSK_H_
14
15// standard include
16#ifdef DEBUG_TRACES
17#include <iostream> // std::clog
18#endif
19#include <cmath> // std::fabs
20#include <limits> // std::numeric_limits
21#include <utility> // std::pair
22#include <vector>
23
24// gudhi include
25#include <gudhi/Persistence_heat_maps.h>
26#include <gudhi/Debug_utils.h>
27
28namespace Gudhi {
29namespace Persistence_representations {
30
31// TODO: none of the methods are documented and the class description is lacking.
32
43class PSSK : public Persistence_heat_maps<constant_scaling_function>
44{
45 public:
47
48 PSSK() : Base() {}
49
50 PSSK(const std::vector<std::pair<double, double> >& interval,
51 const std::vector<std::vector<double> >& filter = create_Gaussian_filter(5, 1),
52 std::size_t number_of_pixels = 1000,
53 double min = -1,
54 double max = -1)
55 : Base()
56 {
57 this->_construct(interval, filter, number_of_pixels, min, max);
58 }
59
60 PSSK(const char* filename,
61 const std::vector<std::vector<double> >& filter = create_Gaussian_filter(5, 1),
62 std::size_t number_of_pixels = 1000,
63 double min = -1,
64 double max = -1,
65 unsigned int dimension = std::numeric_limits<unsigned int>::max())
66 : Base()
67 {
68 std::vector<std::pair<double, double> > intervals;
69 if (dimension == std::numeric_limits<unsigned int>::max()) {
71 } else {
72 intervals = read_persistence_intervals_in_one_dimension_from_file(filename, dimension);
73 }
74 this->_construct(intervals, filter, number_of_pixels, min, max);
75 }
76
77 private:
78 // if min == max, then the program is requested to set up the values itself based on persistence intervals
79 void _construct(const std::vector<std::pair<double, double> >& intervals,
80 const std::vector<std::vector<double> >& filter = create_Gaussian_filter(5, 1),
81 std::size_t number_of_pixels = 1000,
82 double min = -1,
83 double max = -1)
84 {
85#ifdef DEBUG_TRACES
86 std::clog << "Entering construct procedure \n";
87#endif
88
89 if (min == max) {
90 // in this case, we want the program to set up the min and max values by itself.
91 min = std::numeric_limits<double>::max();
92 max = -std::numeric_limits<double>::max();
93
94 for (std::size_t i = 0; i != intervals.size(); ++i) {
95 if (intervals[i].first < min) min = intervals[i].first;
96 if (intervals[i].second > max) max = intervals[i].second;
97 }
98 // now we have the structure filled in, and moreover we know min and max values of the interval, so we know the
99 // range.
100
101 // add some more space:
102 auto pad = std::fabs(max - min) / 100;
103 min -= pad;
104 max += pad;
105 }
106
107#ifdef DEBUG_TRACES
108 std::clog << "min : " << min << std::endl;
109 std::clog << "max : " << max << std::endl;
110 std::clog << "number_of_pixels : " << number_of_pixels << std::endl;
111#endif
112
113 Base::min_ = min;
114 Base::max_ = max;
115
116 // initialization of the structure heat_map
117 std::vector<std::vector<double> > heat_map;
118 for (std::size_t i = 0; i != number_of_pixels; ++i) {
119 std::vector<double> v(number_of_pixels, 0);
120 heat_map.push_back(v);
121 }
122 Base::heat_map_.swap(heat_map);
123
124#ifdef DEBUG_TRACES
125 std::clog << "Done creating of the heat map, now we will fill in the structure \n";
126#endif
127
128 for (std::size_t pt_nr = 0; pt_nr != intervals.size(); ++pt_nr) {
129 // compute the value of intervals_[pt_nr] in the grid:
130 int x_grid =
131 static_cast<int>((intervals[pt_nr].first - Base::min_) / (Base::max_ - Base::min_) * number_of_pixels);
132 int y_grid =
133 static_cast<int>((intervals[pt_nr].second - Base::min_) / (Base::max_ - Base::min_) * number_of_pixels);
134
135#ifdef DEBUG_TRACES
136 std::clog << "point : " << intervals[pt_nr].first << " , " << intervals[pt_nr].second << std::endl;
137 std::clog << "x_grid : " << x_grid << std::endl;
138 std::clog << "y_grid : " << y_grid << std::endl;
139#endif
140
141 // x_grid and y_grid gives a center of the kernel. We want to have its lower left corner. To get this, we need to
142 // shift x_grid and y_grid by a grid diameter.
143 x_grid -= filter.size() / 2;
144 y_grid -= filter.size() / 2;
145 // note that the numbers x_grid and y_grid may be negative.
146
147#ifdef DEBUG_TRACES
148 std::clog << "After shift : \n";
149 std::clog << "x_grid : " << x_grid << std::endl;
150 std::clog << "y_grid : " << y_grid << std::endl;
151 std::clog << "filter.size() : " << filter.size() << std::endl;
152#endif
153
154 for (std::size_t i = 0; i != filter.size(); ++i) {
155 for (std::size_t j = 0; j != filter.size(); ++j) {
156 // if the point (x_grid+i,y_grid+j) is the correct point in the grid.
157 if (((x_grid + i) >= 0) && (x_grid + i < Base::heat_map_.size()) && ((y_grid + j) >= 0) &&
158 (y_grid + j < Base::heat_map_.size())) {
159#ifdef DEBUG_TRACES
160 std::clog << y_grid + j << " " << x_grid + i << std::endl;
161#endif
162 Base::heat_map_[y_grid + j][x_grid + i] += filter[i][j];
163 Base::heat_map_[x_grid + i][y_grid + j] += -filter[i][j];
164 }
165 }
166 }
167 }
168 } // construct
169};
170
171} // namespace Persistence_representations
172} // namespace Gudhi
173
174#endif // PSSK_H_
std::vector< std::vector< double > > create_Gaussian_filter(std::size_t pixel_radius, double sigma)
Definition Persistence_heat_maps.h:46
std::vector< std::pair< double, double > > read_persistence_intervals_in_one_dimension_from_file(std::string const &filename, int dimension=-1, double what_to_substitute_for_infinite_bar=-1)
Definition read_persistence_from_file.h:44
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14