TTK
Loading...
Searching...
No Matches
PersistenceDiagramAuctionActor.h
Go to the documentation of this file.
1#pragma once
2
3#include <Debug.h>
4#include <KDTree.h>
6
7#include <array>
8#include <cmath>
9#include <queue>
10
11namespace ttk {
12
13 struct Compare {
14 constexpr bool operator()(std::pair<int, double> const &a,
15 std::pair<int, double> const &b) const noexcept {
16 return a.second > b.second;
17 }
18 };
19
21 public:
23
24 PersistenceDiagramAuctionActor(double x, double y, bool is_diagonal, int id)
25 : x_{x}, y_{y}, id_{id}, is_diagonal_{is_diagonal} {
26 }
27
28 void SetCoordinates(const double x, const double y) {
29 this->x_ = x;
30 this->y_ = y;
31 }
32
33 void SetCriticalCoordinates(const float coords_x,
34 const float coords_y,
35 const float coords_z) {
36 this->coords_ = {coords_x, coords_y, coords_z};
37 }
38
39 void SetCriticalCoordinates(const std::array<float, 3> coords) {
40 this->coords_ = coords;
41 }
42
43 std::array<float, 3> GetCriticalCoordinates() const {
44 return this->coords_;
45 }
46
47 void GetKDTCoordinates(double geometricalFactor,
48 std::array<double, 5> &coordinates) const {
49 coordinates[0] = geometricalFactor * this->x_;
50 coordinates[1] = geometricalFactor * this->y_;
51 if(geometricalFactor < 1) {
52 coordinates[2] = (1 - geometricalFactor) * this->coords_[0];
53 coordinates[3] = (1 - geometricalFactor) * this->coords_[1];
54 coordinates[4] = (1 - geometricalFactor) * this->coords_[2];
55 } else {
56 coordinates[2] = 0;
57 coordinates[3] = 0;
58 coordinates[4] = 0;
59 }
60 }
61
63 x_ = (x_ + y_) / 2;
64 y_ = x_;
65 is_diagonal_ = true;
66 }
67
68 int getId() const {
69 return id_;
70 };
71
72 double getPersistence() const {
73 return this->y_ - this->x_;
74 }
75
76 bool isDiagonal() const {
77 return this->is_diagonal_;
78 }
79
81 const int wasserstein,
82 const double geometricalFactor) const;
83
84 inline double cost(const PersistenceDiagramAuctionActor *g,
85 const int wasserstein,
86 const double geometricalFactor) const {
87 return this->cost(*g, wasserstein, geometricalFactor);
88 }
89
90 double getPairGeometricalLength(const int wasserstein) const {
91 return Geometry::pow(geom_pair_length_[0], wasserstein)
92 + Geometry::pow(geom_pair_length_[1], wasserstein)
93 + Geometry::pow(geom_pair_length_[2], wasserstein);
94 }
95
96 // data members
97 double x_{}, y_{};
98 int id_{};
99 std::array<float, 3> coords_{};
100
101 protected:
102 bool is_diagonal_{false};
103 std::array<double, 3> geom_pair_length_{};
104 };
105
107 public:
108 Good() = default;
109 Good(const Good &) = default;
110 Good(double x, double y, bool is_diagonal, int id)
111 : PersistenceDiagramAuctionActor(x, y, is_diagonal, id) {
112 }
113
114 // lambda : 0<=lambda<=1
115 // parametrizes the point used for the physical (critical) coordinates of
116 // the persistence paired lambda = 1 : extremum (min if pair min-sad, max if
117 // pair sad-max) lambda = 0 : saddle (bad stability) lambda = 1/2 : middle
118 // of the 2 critical points of the pair
119 Good(const PersistencePair &pair, const int id, const double lambda) {
120
121 this->id_ = id;
122 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
123 this->geom_pair_length_ = {
124 std::abs(pair.birth.coords[0] - pair.death.coords[0]),
125 std::abs(pair.birth.coords[1] - pair.death.coords[1]),
126 std::abs(pair.birth.coords[2] - pair.death.coords[2]),
127 };
128
129 std::array<float, 3> coords{};
130 const float lb = lambda;
131
133 coords = {
134 (1.0f - lb) * pair.birth.coords[0] + lb * pair.death.coords[0],
135 (1.0f - lb) * pair.birth.coords[1] + lb * pair.death.coords[1],
136 (1.0f - lb) * pair.birth.coords[2] + lb * pair.death.coords[2],
137 };
138 } else if(pair.birth.type == CriticalType::Local_minimum) {
139 coords = {
140 lb * pair.birth.coords[0] + (1.0f - lb) * pair.death.coords[0],
141 lb * pair.birth.coords[1] + (1.0f - lb) * pair.death.coords[1],
142 lb * pair.birth.coords[2] + (1.0f - lb) * pair.death.coords[2],
143 };
144 } else { // pair saddle-saddle
145 coords = {
146 (pair.birth.coords[0] + pair.death.coords[0]) / 2.0f,
147 (pair.birth.coords[1] + pair.death.coords[1]) / 2.0f,
148 (pair.birth.coords[2] + pair.death.coords[2]) / 2.0f,
149 };
150 }
151
152 this->SetCriticalCoordinates(coords);
153 this->is_diagonal_ = (pair.birth.sfValue == pair.death.sfValue);
154 }
155
156 Good(const PersistencePair &pair, const int id) {
157 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
158 this->id_ = id;
159 this->is_diagonal_ = (pair.birth.sfValue == pair.death.sfValue);
160 }
161
162 inline void setPrice(const double price) {
163 price_ = price;
164 }
165
166 inline double getPrice() const {
167 return price_;
168 }
169
170 inline void assign(const int b, const double price) {
171 price_ = price;
172 owner_ = b;
173 }
174
175 inline int getOwner() const {
176 return owner_;
177 }
178
179 inline void setOwner(const int idx) {
180 owner_ = idx;
181 }
182
183 Good &operator=(const Good &) = default;
184
185 protected:
186 double price_{0};
187 // Position in Auction.bidders_ of the owner of this good.
188 // If the good is not owned, owner_ is set to -1
189 int owner_{-1};
190 };
191
192 using GoodDiagram = std::vector<Good>;
193
195 public:
197
198 Bidder() = default;
199 Bidder(const double x, const double y, const bool is_diagonal, const int id)
200 : PersistenceDiagramAuctionActor{x, y, is_diagonal, id} {
201 price_paid_ = 0;
202 diagonal_price_ = 0;
203 this->is_diagonal_ = is_diagonal;
204 this->id_ = id;
205 }
206
207 Bidder(const PersistencePair &pair, const int id, const double lambda)
209
210 this->id_ = id;
211 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
212 this->geom_pair_length_ = {
213 std::abs(pair.birth.coords[0] - pair.death.coords[0]),
214 std::abs(pair.birth.coords[1] - pair.death.coords[1]),
215 std::abs(pair.birth.coords[2] - pair.death.coords[2]),
216 };
217
218 std::array<float, 3> coords{};
219 const float lb = lambda;
220
222 coords = {
223 (1.0f - lb) * pair.birth.coords[0] + lb * pair.death.coords[0],
224 (1.0f - lb) * pair.birth.coords[1] + lb * pair.death.coords[1],
225 (1.0f - lb) * pair.birth.coords[2] + lb * pair.death.coords[2],
226 };
227 } else if(pair.birth.type == CriticalType::Local_minimum) {
228 coords = {
229 lb * pair.birth.coords[0] + (1.0f - lb) * pair.death.coords[0],
230 lb * pair.birth.coords[1] + (1.0f - lb) * pair.death.coords[1],
231 lb * pair.birth.coords[2] + (1.0f - lb) * pair.death.coords[2],
232 };
233 } else { // pair saddle-saddle
234 coords = {
235 (pair.birth.coords[0] + pair.death.coords[0]) / 2.0f,
236 (pair.birth.coords[1] + pair.death.coords[1]) / 2.0f,
237 (pair.birth.coords[2] + pair.death.coords[2]) / 2.0f,
238 };
239 }
240
241 this->SetCriticalCoordinates(coords);
242 this->is_diagonal_ = std::abs(pair.birth.sfValue - pair.death.sfValue)
243 < Geometry::powIntTen<double>(-12);
244 }
245
247
248 // Off-diagonal Bidding (with or without the use of a KD-Tree
249 int runBidding(GoodDiagram *goods,
250 Good &diagonalGood,
251 int wasserstein,
252 double epsilon,
253 double geometricalFactor);
254 int runKDTBidding(GoodDiagram *goods,
255 Good &diagonalGood,
256 int wasserstein,
257 double epsilon,
258 double geometricalFactor,
259 KDT *kdt,
260 const int kdt_index = 0);
261
262 // Diagonal Bidding (with or without the use of a KD-Tree
264 GoodDiagram *goods,
265 Good &twinGood,
266 int wasserstein,
267 double epsilon,
268 double geometricalFactor,
269 std::priority_queue<std::pair<int, double>,
270 std::vector<std::pair<int, double>>,
271 Compare> &diagonal_queue);
273 GoodDiagram *goods,
274 Good &diagonalGood,
275 int wasserstein,
276 double epsilon,
277 double geometricalFactor,
278 std::vector<KDT *> &correspondence_kdt_map,
279 std::priority_queue<std::pair<int, double>,
280 std::vector<std::pair<int, double>>,
281 Compare> &diagonal_queue,
282 const int kdt_index = 0);
283
284 // Utility wrapper functions
285 const Good &getProperty() const {
286 return this->property_;
287 }
288 void setDiagonalPrice(const double price) {
289 this->diagonal_price_ = price;
290 }
291 void setPricePaid(const double price) {
292 this->price_paid_ = price;
293 }
294 void setProperty(const Good &g) {
295 this->property_ = g;
296 }
298 this->property_ = {};
299 }
300 void setPositionInAuction(const int pos) {
301 this->position_in_auction_ = pos;
302 }
304 return this->position_in_auction_;
305 }
306
307 protected:
309 double price_paid_{};
311
312 private:
313 // Attribute stating at which position in Auction.bidders_ this bidder can
314 // be found In a single Auction, this attribute could be deducted from id_,
315 // but with the use of Barycenter Goods will be added and deleted, which
316 // would add and delete diagonal bidders.
317 int position_in_auction_{};
318 };
319
320 using BidderDiagram = std::vector<Bidder>;
321
322} // namespace ttk
int runKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, KDT *kdt, const int kdt_index=0)
void setDiagonalPrice(const double price)
void setPricePaid(const double price)
int runBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor)
int runDiagonalKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, std::vector< KDT * > &correspondence_kdt_map, std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > &diagonal_queue, const int kdt_index=0)
int runDiagonalBidding(GoodDiagram *goods, Good &twinGood, int wasserstein, double epsilon, double geometricalFactor, std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > &diagonal_queue)
void setPositionInAuction(const int pos)
void setProperty(const Good &g)
Bidder(const PersistencePair &pair, const int id, const double lambda)
const Good & getProperty() const
Bidder(const double x, const double y, const bool is_diagonal, const int id)
Bidder()=default
Good(double x, double y, bool is_diagonal, int id)
Good()=default
void setOwner(const int idx)
Good(const PersistencePair &pair, const int id, const double lambda)
Good & operator=(const Good &)=default
void assign(const int b, const double price)
void setPrice(const double price)
Good(const PersistencePair &pair, const int id)
Good(const Good &)=default
TTK KD-Tree.
Definition: KDTree.h:21
double cost(const PersistenceDiagramAuctionActor &g, const int wasserstein, const double geometricalFactor) const
void SetCriticalCoordinates(const float coords_x, const float coords_y, const float coords_z)
PersistenceDiagramAuctionActor(double x, double y, bool is_diagonal, int id)
double getPairGeometricalLength(const int wasserstein) const
std::array< float, 3 > GetCriticalCoordinates() const
void GetKDTCoordinates(double geometricalFactor, std::array< double, 5 > &coordinates) const
double cost(const PersistenceDiagramAuctionActor *g, const int wasserstein, const double geometricalFactor) const
void SetCriticalCoordinates(const std::array< float, 3 > coords)
void SetCoordinates(const double x, const double y)
T1 pow(const T1 val, const T2 n)
Definition: Geometry.h:411
The Topology ToolKit.
std::vector< Bidder > BidderDiagram
std::vector< Good > GoodDiagram
constexpr bool operator()(std::pair< int, double > const &a, std::pair< int, double > const &b) const noexcept
std::array< float, 3 > coords
ttk::CriticalVertex birth
ttk::CriticalVertex death