60 std::vector<ttk::DiagramType> &inputPersistenceDiagrams,
61 std::vector<std::vector<MatchingType>> &outputMatchings,
62 const std::string &algorithm,
63 const std::string &wasserstein,
71#ifdef TTK_ENABLE_OPENMP
72#pragma omp parallel for num_threads(threadNumber_)
74 for(
int i = 0; i < numInputs - 1; ++i) {
75 performSingleMatching(
76 i, inputPersistenceDiagrams, outputMatchings,
78 wasserstein, tolerance, px, py, pz, ps, pe
88 std::vector<ttk::DiagramType> &allDiagrams,
89 std::vector<std::vector<MatchingType>> &allMatchings,
90 std::vector<trackingTuple> &trackings) {
91 auto numPersistenceDiagramsInput = (int)allDiagrams.size();
93 for(
int in = 1; in < numPersistenceDiagramsInput - 1; ++in) {
94 std::vector<MatchingType> matchings1 = allMatchings[in - 1];
95 std::vector<MatchingType> matchings2 = allMatchings[in];
97 auto matchingsSize1 = (int)matchings1.size();
98 auto matchingsSize2 = (int)matchings2.size();
99 int const endIndex = numPersistenceDiagramsInput - 2;
101 for(
int i = 0; i < matchingsSize1; ++i) {
102 const auto m1ai0 = std::get<0>(matchings1[i]);
103 const auto m1ai1 = std::get<1>(matchings1[i]);
105 for(
int j = 0; j < matchingsSize2; ++j) {
106 const auto m2aj0 = std::get<0>(matchings2[j]);
107 const auto m2aj1 = std::get<1>(matchings2[j]);
115 int const chainStart = std::get<0>(tt);
116 int const chainEnd = std::get<1>(tt);
117 std::vector<SimplexId> &chain = std::get<2>(tt);
120 auto chainSize = (int)chain.size();
123 this->printErr(
"Brain error.");
124 }
else if(chainStart + chainSize == in
125 && chain.at((
unsigned long)chainSize - 1) == m1ai0) {
127 chain.push_back(m1ai1);
128 int const numEnd = in == endIndex ? endIndex : -1;
130 chain.push_back(m2aj1);
131 std::get<1>(tt) = numEnd;
133 std::get<2>(tt) = chain;
136 tt = std::make_tuple(chainStart, chainEnd, chain);
140 std::vector<SimplexId> chain;
141 chain.push_back(m1ai0);
142 chain.push_back(m1ai1);
144 chain.push_back(m2aj1);
146 int const numEnd = in == endIndex ? endIndex : -1;
147 trackingTuple const tt = std::make_tuple(in - 1, numEnd, chain);
148 trackings.push_back(tt);
156 int const chainStart = std::get<0>(tt);
157 int const chainEnd = std::get<1>(tt);
159 std::vector<SimplexId>
const &chain = std::get<2>(tt);
160 auto chainSize = (int)chain.size();
161 if(chainStart + chainSize - 1 < in)
162 std::get<1>(tt) = in - 1;
168 std::sort(trackings.begin(), trackings.end(),
170 return std::get<0>(a) < std::get<0>(b);
177 const std::vector<ttk::DiagramType> &allDiagrams,
178 const std::vector<trackingTuple> &trackings,
179 std::vector<std::set<int>> &trackingTupleToMerged,
180 const double postProcThresh) {
182 const int numPersistenceDiagramsInput = allDiagrams.size();
185 for(
size_t k = 0; k < trackings.size(); ++k) {
186 const auto &tk = trackings[k];
187 int const startK = std::get<0>(tk);
188 int endK = std::get<1>(tk);
190 endK = numPersistenceDiagramsInput - 1;
191 const std::vector<SimplexId> &chainK = std::get<2>(tk);
195 const auto n1 = chainK.front();
196 const auto n2 = chainK.back();
197 const auto &tuple1 = diagramStartK[n1];
198 const auto &tuple2 = diagramEndK[n2];
200 double x1, y1, z1, x2, y2, z2;
202 const auto point1Type1 = tuple1.birth.type;
203 const auto point1Type2 = tuple1.death.type;
209 bool const t1Max = t11Max || t12Max;
210 bool const t1Min = !t1Max && (t11Min || t12Min);
212 x1 = t1Max ? tuple1.death.coords[0] : t1Min ? tuple1.birth.coords[0] : 0;
213 y1 = t1Max ? tuple1.death.coords[1] : t1Min ? tuple1.birth.coords[1] : 0;
214 z1 = t1Max ? tuple1.death.coords[2] : t1Min ? tuple1.birth.coords[2] : 0;
216 const auto point2Type1 = tuple2.birth.type;
217 const auto point2Type2 = tuple2.death.type;
223 bool const t2Max = t21Max || t22Max;
224 bool const t2Min = !t2Max && (t21Min || t22Min);
227 x2 = t2Max ? tuple2.death.coords[0] : t2Min ? tuple2.birth.coords[0] : 0;
228 y2 = t2Max ? tuple2.death.coords[1] : t2Min ? tuple2.birth.coords[1] : 0;
229 z2 = t2Max ? tuple2.death.coords[2] : t2Min ? tuple2.birth.coords[2] : 0;
235 if(!t1Min && !t2Min && !t1Max && !t2Max)
239 for(
size_t m = k + 1; m < trackings.size(); ++m) {
240 const auto &tm = trackings[m];
241 int const startM = std::get<0>(tm);
242 int const endM = std::get<1>(tm);
243 const std::vector<SimplexId> &chainM = std::get<2>(tm);
244 if((endK > 0 && startM > endK) || (endM > 0 && startK > endM))
247 for(
int c = 0; c < (int)chainM.size(); ++c) {
248 bool const doMatch1 = startM + c == startK;
249 bool const doMatch2 = startM + c == endK;
252 if(!doMatch1 && !doMatch2)
256 const auto n3 = chainM[c];
258 const auto &tuple3 = diagramM[n3];
260 const auto point3Type1 = tuple3.birth.type;
261 const auto point3Type2 = tuple3.death.type;
269 bool const t3Max = t31Max || t32Max;
270 bool const t3Min = !t3Max && (t31Min || t32Min);
272 x3 = t3Max ? tuple3.death.coords[0]
273 : t3Min ? tuple3.birth.coords[0]
275 y3 = t3Max ? tuple3.death.coords[1]
276 : t3Min ? tuple3.birth.coords[1]
278 z3 = t3Max ? tuple3.death.coords[2]
279 : t3Min ? tuple3.birth.coords[2]
283 bool hasMatched =
false;
284 const auto square = [](
const double a) {
return a * a; };
285 if(doMatch1 && ((t3Max && t1Max) || (t3Min && t1Min))) {
287 = std::sqrt(square(x1 - x3) + square(y1 - y3) + square(z1 - z3));
289 if(dist13 >= postProcThresh)
294 if(doMatch2 && ((t3Max && t2Max) || (t3Min && t2Min))) {
296 = std::sqrt(square(x2 - x3) + square(y2 - y3) + square(z2 - z3));
298 if(dist23 >= postProcThresh)
307 std::stringstream msg;
308 msg <<
"Merged " << m <<
" with " << k <<
": d = " << dist <<
".";
312 std::set<int> &mergedM = trackingTupleToMerged[m];
int performSingleMatching(int i, std::vector< ttk::DiagramType > &inputPersistenceDiagrams, std::vector< std::vector< MatchingType > > &outputMatchings, const std::string &algorithm, const std::string &wasserstein, double tolerance, double px, double py, double pz, double ps, double pe)
int performMatchings(int numInputs, std::vector< ttk::DiagramType > &inputPersistenceDiagrams, std::vector< std::vector< MatchingType > > &outputMatchings, const std::string &algorithm, const std::string &wasserstein, double tolerance, double px, double py, double pz, double ps, double pe)