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,
83 const double nonMatchingWeight) const;
84
85 inline double cost(const PersistenceDiagramAuctionActor *g,
86 const int wasserstein,
87 const double geometricalFactor,
88 const double nonMatchingWeight) const {
89 return this->cost(*g, wasserstein, geometricalFactor, nonMatchingWeight);
90 }
91
92 double getPairGeometricalLength(const int wasserstein) const {
93 return Geometry::pow(geom_pair_length_[0], wasserstein)
94 + Geometry::pow(geom_pair_length_[1], wasserstein)
95 + Geometry::pow(geom_pair_length_[2], wasserstein);
96 }
97
98 // data members
99 double x_{}, y_{};
100 int id_{};
101 std::array<float, 3> coords_{};
102
103 protected:
104 bool is_diagonal_{false};
105 std::array<double, 3> geom_pair_length_{};
106 };
107
109 public:
110 Good() = default;
111 Good(const Good &) = default;
112 Good(double x, double y, bool is_diagonal, int id)
113 : PersistenceDiagramAuctionActor(x, y, is_diagonal, id) {
114 }
115
116 // lambda : 0<=lambda<=1
117 // parametrizes the point used for the physical (critical) coordinates of
118 // the persistence paired lambda = 1 : extremum (min if pair min-sad, max if
119 // pair sad-max) lambda = 0 : saddle (bad stability) lambda = 1/2 : middle
120 // of the 2 critical points of the pair
121 Good(const PersistencePair &pair, const int id, const double lambda) {
122
123 this->id_ = id;
124 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
125 this->geom_pair_length_ = {
126 std::abs(pair.birth.coords[0] - pair.death.coords[0]),
127 std::abs(pair.birth.coords[1] - pair.death.coords[1]),
128 std::abs(pair.birth.coords[2] - pair.death.coords[2]),
129 };
130
131 std::array<float, 3> coords{};
132 const float lb = lambda;
133
135 coords = {
136 (1.0f - lb) * pair.birth.coords[0] + lb * pair.death.coords[0],
137 (1.0f - lb) * pair.birth.coords[1] + lb * pair.death.coords[1],
138 (1.0f - lb) * pair.birth.coords[2] + lb * pair.death.coords[2],
139 };
140 } else if(pair.birth.type == CriticalType::Local_minimum) {
141 coords = {
142 lb * pair.birth.coords[0] + (1.0f - lb) * pair.death.coords[0],
143 lb * pair.birth.coords[1] + (1.0f - lb) * pair.death.coords[1],
144 lb * pair.birth.coords[2] + (1.0f - lb) * pair.death.coords[2],
145 };
146 } else { // pair saddle-saddle
147 coords = {
148 (pair.birth.coords[0] + pair.death.coords[0]) / 2.0f,
149 (pair.birth.coords[1] + pair.death.coords[1]) / 2.0f,
150 (pair.birth.coords[2] + pair.death.coords[2]) / 2.0f,
151 };
152 }
153
154 this->SetCriticalCoordinates(coords);
155 this->is_diagonal_ = (pair.birth.sfValue == pair.death.sfValue);
156 }
157
158 Good(const PersistencePair &pair, const int id) {
159 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
160 this->id_ = id;
161 this->is_diagonal_ = (pair.birth.sfValue == pair.death.sfValue);
162 }
163
164 inline void setPrice(const double price) {
165 price_ = price;
166 }
167
168 inline double getPrice() const {
169 return price_;
170 }
171
172 inline void assign(const int b, const double price) {
173 price_ = price;
174 owner_ = b;
175 }
176
177 inline int getOwner() const {
178 return owner_;
179 }
180
181 inline void setOwner(const int idx) {
182 owner_ = idx;
183 }
184
185 Good &operator=(const Good &) = default;
186
187 protected:
188 double price_{0};
189 // Position in Auction.bidders_ of the owner of this good.
190 // If the good is not owned, owner_ is set to -1
191 int owner_{-1};
192 };
193
194 using GoodDiagram = std::vector<Good>;
195
197 public:
199
200 Bidder() = default;
201 Bidder(const double x, const double y, const bool is_diagonal, const int id)
202 : PersistenceDiagramAuctionActor{x, y, is_diagonal, id} {
203 price_paid_ = 0;
204 diagonal_price_ = 0;
205 this->is_diagonal_ = is_diagonal;
206 this->id_ = id;
207 }
208
209 Bidder(const PersistencePair &pair, const int id, const double lambda)
211
212 this->id_ = id;
213 this->SetCoordinates(pair.birth.sfValue, pair.death.sfValue);
214 this->geom_pair_length_ = {
215 std::abs(pair.birth.coords[0] - pair.death.coords[0]),
216 std::abs(pair.birth.coords[1] - pair.death.coords[1]),
217 std::abs(pair.birth.coords[2] - pair.death.coords[2]),
218 };
219
220 std::array<float, 3> coords{};
221 const float lb = lambda;
222
224 coords = {
225 (1.0f - lb) * pair.birth.coords[0] + lb * pair.death.coords[0],
226 (1.0f - lb) * pair.birth.coords[1] + lb * pair.death.coords[1],
227 (1.0f - lb) * pair.birth.coords[2] + lb * pair.death.coords[2],
228 };
229 } else if(pair.birth.type == CriticalType::Local_minimum) {
230 coords = {
231 lb * pair.birth.coords[0] + (1.0f - lb) * pair.death.coords[0],
232 lb * pair.birth.coords[1] + (1.0f - lb) * pair.death.coords[1],
233 lb * pair.birth.coords[2] + (1.0f - lb) * pair.death.coords[2],
234 };
235 } else { // pair saddle-saddle
236 coords = {
237 (pair.birth.coords[0] + pair.death.coords[0]) / 2.0f,
238 (pair.birth.coords[1] + pair.death.coords[1]) / 2.0f,
239 (pair.birth.coords[2] + pair.death.coords[2]) / 2.0f,
240 };
241 }
242
243 this->SetCriticalCoordinates(coords);
244 this->is_diagonal_ = std::abs(pair.birth.sfValue - pair.death.sfValue)
245 < Geometry::powIntTen<double>(-12);
246 }
247
249
250 // Off-diagonal Bidding (with or without the use of a KD-Tree
251 int runBidding(GoodDiagram *goods,
252 Good &diagonalGood,
253 int wasserstein,
254 double epsilon,
255 double geometricalFactor,
256 double nonMatchingWeight);
257 int runKDTBidding(GoodDiagram *goods,
258 Good &diagonalGood,
259 int wasserstein,
260 double epsilon,
261 double geometricalFactor,
262 double nonMatchingWeight,
263 KDT *kdt,
264 const int kdt_index = 0);
265
266 // Diagonal Bidding (with or without the use of a KD-Tree
268 GoodDiagram *goods,
269 Good &twinGood,
270 int wasserstein,
271 double epsilon,
272 double geometricalFactor,
273 double nonMatchingWeight,
274 std::priority_queue<std::pair<int, double>,
275 std::vector<std::pair<int, double>>,
276 Compare> &diagonal_queue);
278 GoodDiagram *goods,
279 Good &diagonalGood,
280 int wasserstein,
281 double epsilon,
282 double geometricalFactor,
283 double nonMatchingWeight,
284 std::vector<KDT *> &correspondence_kdt_map,
285 std::priority_queue<std::pair<int, double>,
286 std::vector<std::pair<int, double>>,
287 Compare> &diagonal_queue,
288 const int kdt_index = 0);
289
290 // Utility wrapper functions
291 const Good &getProperty() const {
292 return this->property_;
293 }
294 void setDiagonalPrice(const double price) {
295 this->diagonal_price_ = price;
296 }
297 void setPricePaid(const double price) {
298 this->price_paid_ = price;
299 }
300 void setProperty(const Good &g) {
301 this->property_ = g;
302 }
304 this->property_ = {};
305 }
306 void setPositionInAuction(const int pos) {
307 this->position_in_auction_ = pos;
308 }
310 return this->position_in_auction_;
311 }
312
313 protected:
315 double price_paid_{};
317
318 private:
319 // Attribute stating at which position in Auction.bidders_ this bidder can
320 // be found In a single Auction, this attribute could be deducted from id_,
321 // but with the use of Barycenter Goods will be added and deleted, which
322 // would add and delete diagonal bidders.
323 int position_in_auction_{};
324 };
325
326 using BidderDiagram = std::vector<Bidder>;
327
328} // namespace ttk
int runDiagonalBidding(GoodDiagram *goods, Good &twinGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > &diagonal_queue)
void setDiagonalPrice(const double price)
int runKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, KDT *kdt, const int kdt_index=0)
void setPricePaid(const double price)
int runBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight)
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
int runDiagonalKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, 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)
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
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 cost(const PersistenceDiagramAuctionActor *g, const int wasserstein, const double geometricalFactor, const double nonMatchingWeight) const
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 double nonMatchingWeight) 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:456
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