TTK
Loading...
Searching...
No Matches
MergeTreePrincipalGeodesicsBase.h
Go to the documentation of this file.
1
10
11#pragma once
12
14#include <cmath>
15
16#define POINTS_BELOW_DIAG_TOLERANCE 1e-4
17
18namespace ttk {
19
20 class MergeTreePrincipalGeodesicsBase : virtual public Debug,
22 protected:
23 // Filled by the algorithm
24 std::vector<std::vector<std::vector<double>>> vS_, v2s_, trees2Vs_,
26 std::vector<std::vector<double>> allTs_, allScaledTs_, allTreesTs_;
27 std::vector<std::vector<double>> branchesCorrelationMatrix_,
29 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
31
32 public:
35 "MergeTreePrincipalGeodesicsBase"); // inherited from Debug: prefix will
36 // be printed at the beginning of
37 // every msg
38 }
39
40 //----------------------------------------------------------------------------
41 // Matching / Distance
42 //----------------------------------------------------------------------------
43 template <class dataType>
45 ftm::MergeTree<dataType> &barycenter,
46 std::vector<ftm::MergeTree<dataType>> &inputTrees,
47 std::vector<std::vector<double *>> &vS,
48 std::vector<std::vector<double *>> &v2s,
49 size_t vSize,
50 std::vector<std::vector<double>> &allTreesTs,
51 std::vector<double> &reconstructionErrors,
52 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
53 &matchings,
54 bool transposeVector = true) {
55 reconstructionErrors.resize(inputTrees.size());
56 matchings.resize(inputTrees.size());
57 dataType reconstructionError = 0.0;
58#ifdef TTK_ENABLE_OPENMP
59#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_) \
60 reduction(+ : reconstructionError)
61#endif
62 for(unsigned int i = 0; i < inputTrees.size(); ++i) {
63 ftm::MergeTree<dataType> reconstructedTree;
64 getMultiInterpolation<dataType>(barycenter, vS, v2s, vSize,
65 allTreesTs[i], reconstructedTree,
66 transposeVector);
67 dataType error;
69 reconstructedTree, inputTrees[i], matchings[i], error, true);
70 reconstructionError += error / inputTrees.size();
71 reconstructionErrors[i] = error;
72 }
73 return reconstructionError;
74 }
75
76 template <class dataType>
78 ftm::MergeTree<dataType> &barycenter,
79 std::vector<ftm::MergeTree<dataType>> &inputTrees,
80 std::vector<std::vector<std::vector<double>>> &vS,
81 std::vector<std::vector<std::vector<double>>> &v2s,
82 std::vector<std::vector<double>> &allTreesTs,
83 std::vector<double> &reconstructionErrors) {
84 std::vector<std::vector<double *>> pVS, pV2s;
87 std::vector<std::vector<std::tuple<ftm::idNode, ftm::idNode, double>>>
88 matchings;
89 return computeReconstructionError(barycenter, inputTrees, pVS, pV2s,
90 vS[0].size(), allTreesTs,
91 reconstructionErrors, matchings, false);
92 }
93
94 template <class dataType>
96 ftm::MergeTree<dataType> &barycenter,
97 std::vector<ftm::MergeTree<dataType>> &inputTrees,
98 std::vector<std::vector<std::vector<double>>> &vS,
99 std::vector<std::vector<std::vector<double>>> &v2s,
100 std::vector<std::vector<double>> &allTreesTs) {
101 std::vector<double> reconstructionErrors;
103 barycenter, inputTrees, vS, v2s, allTreesTs, reconstructionErrors);
104 }
105
106 //----------------------------------------------------------------------------
107 // Interpolation
108 //----------------------------------------------------------------------------
109 double getGeodesicVectorMiddle(std::vector<double> &v,
110 std::vector<double> &v2) {
111 std::vector<double> vProj, v2Proj;
112 ttk::Geometry::addVectorsProjection(v, v2, vProj, v2Proj);
113
114 double alpha = 0.0;
115 int cptDivide = 0;
116 for(unsigned int i = 0; i < vProj.size(); ++i) {
117 if(std::abs(v2Proj[i]) < Geometry::pow(10.0, -DBL_DIG))
118 continue;
119 alpha += (vProj[i] / v2Proj[i]);
120 ++cptDivide;
121 }
122 alpha /= cptDivide;
123 double const m = alpha / (1 + alpha);
124 return m;
125 }
126
127 double getAdjustedTMax(double tMin, double m) {
128 if(std::isnan(m))
129 return tMin;
130 return (m - tMin) * (1 - m) / m + m;
131 }
132
133 double getAdjustedTMin(double tMax, double m) {
134 if(std::isnan(m))
135 return tMax;
136 return (m - tMax) * m / (1 - m) + m;
137 }
138
140 double newT, double m, double &tMin, double &tMax, bool updateTMin) {
141 if(updateTMin) {
142 tMin = std::max(newT, tMin);
143 auto adjustedTMax = getAdjustedTMax(newT, m);
144 if(adjustedTMax > tMin)
145 tMax = std::min(adjustedTMax, tMax);
146 } else {
147 tMax = std::min(newT, tMax);
148 auto adjustedTMin = getAdjustedTMin(newT, m);
149 if(adjustedTMin < tMax)
150 tMin = std::max(adjustedTMin, tMin);
151 }
152 }
153
154 template <class dataType>
155 bool adjustDiagonalT(dataType baryBirth,
156 dataType baryDeath,
157 ftm::idNode node,
158 std::vector<std::vector<double>> &vNew,
159 std::vector<std::vector<double>> &v2New,
160 double &tMin,
161 double &tMax) {
162 bool shortener = false;
163
164 // Compute V1 extremity
165 auto newBirthV1 = baryBirth - vNew[node][0];
166 auto newDeathV1 = baryDeath - vNew[node][1];
167
168 // Compute V2 extremity
169 auto newBirthV2 = baryBirth + v2New[node][0];
170 auto newDeathV2 = baryDeath + v2New[node][1];
171
172 // Adjust t and v
173 if(newBirthV1 > newDeathV1 and newBirthV2 > newDeathV2) {
174 shortener = true;
175
176 double const divisor
177 = (vNew[node][1] - vNew[node][0]) / (baryDeath - baryBirth);
178 vNew[node][0] /= divisor;
179 vNew[node][1] /= divisor;
180 double const divisor2
181 = (v2New[node][0] - v2New[node][1]) / (baryDeath - baryBirth);
182 v2New[node][0] /= divisor2;
183 v2New[node][1] /= divisor2;
184 } else if(newBirthV1 > newDeathV1 or newBirthV2 > newDeathV2) {
185 double const newT
186 = (baryDeath - vNew[node][1] - baryBirth + vNew[node][0])
187 / (vNew[node][0] + v2New[node][0]
188 - (vNew[node][1] + v2New[node][1]));
189 double const m = getGeodesicVectorMiddle(vNew[node], v2New[node]);
190 if(newBirthV1 > newDeathV1)
191 updateT(newT, m, tMin, tMax, true);
192 if(newBirthV2 > newDeathV2)
193 updateT(newT, m, tMin, tMax, false);
194 }
195
196 return shortener;
197 }
198
199 template <class dataType>
201 dataType baryBirth,
202 dataType baryDeath,
203 ftm::idNode node,
204 std::vector<std::vector<double>> &vNew,
205 std::vector<std::vector<double>> &v2New,
206 double &tMin,
207 double &tMax) {
208 bool shortener = false;
209
210 dataType birthParent = 0.0;
211 dataType deathParent = 1.0;
212
213 auto interpolant = [&](int i, double t) {
214 return -vNew[node][i] + t * (vNew[node][i] + v2New[node][i]);
215 };
216
217 // Compute V1 extremity
218 auto newBirthV1 = baryBirth + interpolant(0, tMin);
219 auto newDeathV1 = baryDeath + interpolant(1, tMin);
220 auto parentBirthV1 = 0.0;
221 auto parentDeathV1 = 1.0;
222
223 // Compute V2 extremity
224 auto newBirthV2 = baryBirth + interpolant(0, tMax);
225 auto newDeathV2 = baryDeath + interpolant(1, tMax);
226 auto parentBirthV2 = 0.0;
227 auto parentDeathV2 = 1.0;
228
229 //
230 bool const extremOutPathIn
231 = ((newDeathV1 > parentDeathV1 and not(newBirthV1 < parentBirthV1)
232 and not(newDeathV2 > parentDeathV2) and newBirthV2 < parentBirthV2)
233 or (not(newDeathV1 > parentDeathV1) and newBirthV1 < parentBirthV1
234 and newDeathV2 > parentDeathV2
235 and not(newBirthV2 < parentBirthV2)));
236
237 // --- Adjust V
238 // Both extremities outside and path outside
239 if(((newDeathV1 > parentDeathV1 and newDeathV2 > parentDeathV2)
240 or (newBirthV1 < parentBirthV1 and newBirthV2 < parentBirthV2))
241 and not(extremOutPathIn)) {
242 shortener = true;
243
244 // Shorten V1
245 double coef1 = 1.0;
246 if(newDeathV1 > parentDeathV1 and newBirthV1 < parentBirthV1)
247 if(newBirthV1 < newDeathV1)
248 coef1 = (parentBirthV1 - baryBirth) / interpolant(0, tMin);
249 else
250 coef1 = (parentDeathV1 - baryDeath) / interpolant(1, tMin);
251 else if(newBirthV1 < parentBirthV1)
252 coef1 = (parentBirthV1 - baryBirth) / interpolant(0, tMin);
253 else if(newDeathV1 > parentDeathV1)
254 coef1 = (parentDeathV1 - baryDeath) / interpolant(1, tMin);
255 vNew[node][0] *= coef1;
256 vNew[node][1] *= coef1;
257
258 // Shorten V2
259 double coef2 = 1.0;
260 if(newDeathV2 > parentDeathV2 and newBirthV2 < parentBirthV2)
261 if(newBirthV2 < newDeathV2)
262 coef2 = (parentBirthV2 - baryBirth) / interpolant(0, tMax);
263 else
264 coef2 = (parentDeathV2 - baryDeath) / interpolant(1, tMax);
265 else if(newBirthV2 < parentBirthV2)
266 coef2 = (parentBirthV2 - baryBirth) / interpolant(0, tMax);
267 else if(newDeathV2 > parentDeathV2)
268 coef2 = (parentDeathV2 - baryDeath) / interpolant(1, tMax);
269 v2New[node][0] *= coef2;
270 v2New[node][1] *= coef2;
271 }
272
273 // --- Adjust T
274 // One extremity outside or both extremities outside but path inside
275 if(((newDeathV1 > parentDeathV1 or newBirthV1 < parentBirthV1)
276 != (newDeathV2 > parentDeathV2 or newBirthV2 < parentBirthV2))
277 or extremOutPathIn) {
278 double const m = getGeodesicVectorMiddle(vNew[node], v2New[node]);
279 if(newDeathV1 > parentDeathV1 or newDeathV2 > parentDeathV2) {
280 double const newT = (deathParent - baryDeath + vNew[node][1])
281 / (vNew[node][1] + v2New[node][1]);
282 if(newDeathV1 > parentDeathV1)
283 updateT(newT, m, tMin, tMax, true);
284 if(newDeathV2 > parentDeathV2)
285 updateT(newT, m, tMin, tMax, false);
286 }
287 if(newBirthV1 < parentBirthV1 or newBirthV2 < parentBirthV2) {
288 double const newT = (birthParent - baryBirth + vNew[node][0])
289 / (vNew[node][0] + v2New[node][0]);
290 if(newBirthV1 < parentBirthV1)
291 updateT(newT, m, tMin, tMax, true);
292 if(newBirthV2 < parentBirthV2)
293 updateT(newT, m, tMin, tMax, false);
294 }
295 }
296
297 return shortener;
298 }
299
300 template <class dataType>
302 dataType death,
303 std::vector<std::vector<double>> &vNew,
304 std::vector<std::vector<double>> &v2New,
305 int i,
306 double t,
307 double tMin,
308 double tMax,
309 const std::string &msg,
310 std::stringstream &ssT) {
311 double const tNew = (t * (tMax - tMin) + tMin);
312 std::streamsize const sSize = std::cout.precision();
313 ssT << std::setprecision(12) << std::endl << msg << std::endl;
314 ssT << "interBirth : "
315 << birth - vNew[i][0] + tNew * (vNew[i][0] + v2New[i][0]) << " _ "
316 << "interDeath : "
317 << death - vNew[i][1] + tNew * (vNew[i][1] + v2New[i][1])
318 << std::endl;
319 ssT << "v : " << vNew[i][0] << " _ " << vNew[i][1] << std::endl;
320 ssT << "v2 : " << v2New[i][0] << " _ " << v2New[i][1] << std::endl;
321 ssT << "ts : " << tMin << " _ " << tMax << std::endl;
322 ssT << "t : " << t << " _ tNew : " << tNew << std::endl;
323 std::cout.precision(sSize);
324 }
325
326 template <class dataType>
328 std::vector<std::vector<double>> &v,
329 std::vector<std::vector<double>> &v2,
330 int i,
331 double t) {
332 ftm::FTMTree_MT *baryTree = &(barycenter.tree);
333 double tMin = 0.0, tMax = 1.0;
334
335 // - Get node information
336 auto birthDeath = baryTree->getBirthDeath<dataType>(i);
337 auto birth = std::get<0>(birthDeath);
338 auto death = std::get<1>(birthDeath);
339
340 // - Get parent information
341 auto parent = baryTree->getParentSafe(i);
342 auto parentBirthDeath = baryTree->getBirthDeath<dataType>(parent);
343 auto parentBirth = std::get<0>(parentBirthDeath);
344 auto parentDeath = std::get<1>(parentBirthDeath);
345
346 if(normalizedWasserstein_ and !baryTree->notNeedToNormalize(i)) {
347 birth = (birth - parentBirth) / (parentDeath - parentBirth);
348 death = (death - parentBirth) / (parentDeath - parentBirth);
349 }
350
351 // - Adjust Diagonal T
352 bool diagonalShortener
353 = adjustDiagonalT(birth, death, i, v, v2, tMin, tMax);
354
355 // - Adjust Nesting T
356 bool nestingShortener = false;
357 if(normalizedWasserstein_ and !baryTree->notNeedToNormalize(i)) {
358 nestingShortener
359 = adjustNestingT(barycenter, birth, death, i, v, v2, tMin, tMax);
360 }
361
362 // - Compute new t
363 double const tNew = t * (tMax - tMin) + tMin;
364
365 if(diagonalShortener or nestingShortener)
366 printWrn("[getTNew] shortener");
367
368 return tNew;
369 }
370
371 template <class dataType>
373 std::vector<double *> &v,
374 std::vector<double *> &v2,
375 size_t vSize,
376 double t,
377 std::vector<dataType> &interpolationVectorT,
378 bool transposeVector) {
379 // --- Init
380 ftm::FTMTree_MT *baryTree = &(barycenter.tree);
381 std::vector<dataType> scalarsVector;
382 ttk::ftm::getTreeScalars<dataType>(barycenter, scalarsVector);
383 std::vector<double> interpolationVector(scalarsVector.size());
384 std::vector<std::vector<double>> vNew, v2New;
385 pointersToVectors(v, vSize, vNew);
386 pointersToVectors(v2, vSize, v2New);
387 if(transposeVector) {
388 std::vector<std::vector<double>> out;
390 vNew = out;
392 v2New = out;
393 }
394
395 // --- Tree traversal
396 int cptBelowDiagonal = 0, cptNotNesting = 0;
397 std::queue<ftm::idNode> queue;
398 queue.emplace(baryTree->getRoot());
399 int noNestingShortener = 0, noDiagonalShortener = 0;
400 while(!queue.empty()) {
401 ftm::idNode const i = queue.front();
402 queue.pop();
403
404 // - Get node information
405 auto nodeBirthDeath = baryTree->getBirthDeathNode<dataType>(i);
406 auto nodeBirth = std::get<0>(nodeBirthDeath);
407 auto nodeDeath = std::get<1>(nodeBirthDeath);
408 auto birth = scalarsVector[nodeBirth];
409 auto death = scalarsVector[nodeDeath];
410
411 // - Get parent information
412 auto parent = baryTree->getParentSafe(i);
413 auto parentNodeBirthDeath
414 = baryTree->getBirthDeathNode<dataType>(parent);
415 auto parentNodeBirth = std::get<0>(parentNodeBirthDeath);
416 auto parentNodeDeath = std::get<1>(parentNodeBirthDeath);
417 auto parentBirth = scalarsVector[parentNodeBirth];
418 auto parentDeath = scalarsVector[parentNodeDeath];
419 auto interParentBirth = interpolationVector[parentNodeBirth];
420 auto interParentDeath = interpolationVector[parentNodeDeath];
421
422 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
423 std::stringstream ssT;
424 std::streamsize const sSize2 = std::cout.precision();
425 ssT << std::setprecision(12);
426 ssT << "info" << std::endl;
427 ssT << "birth death : " << birth << " ___ " << death << std::endl;
428 ssT << "par. birth death : " << parentBirth << " ___ " << parentDeath
429 << std::endl;
430 ssT << "par. inter birth death : " << interParentBirth << " ___ "
431 << interParentDeath << std::endl;
432
433 if(normalizedWasserstein_ and !baryTree->notNeedToNormalize(i)) {
434 birth = (birth - parentBirth) / (parentDeath - parentBirth);
435 death = (death - parentBirth) / (parentDeath - parentBirth);
436 ssT << "norm. birth death : " << birth << " ___ " << death
437 << std::endl;
438 }
439 std::cout.precision(sSize2);
440 // --------------------------------------------------------------------
441
442 // - Adjust tMin and tMax
443 double tMin = 0.0, tMax = 1.0;
444
445 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
446 getInterpolationVectorDebugMsg<dataType>(birth, death, vNew, v2New, i,
447 t, tMin, tMax,
448 "before adjustDiagonalT", ssT);
449 // --------------------------------------------------------------------
450
451 // - Adjust Diagonal T
452 bool const diagonalShortener
453 = adjustDiagonalT(birth, death, i, vNew, v2New, tMin, tMax);
454 noDiagonalShortener += diagonalShortener;
455
456 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458 birth, death, vNew, v2New, i, t, tMin, tMax,
459 "after adjustDiagonalT/before adjustNestingT", ssT);
460 // --------------------------------------------------------------------
461
462 // - Adjust Nesting T
463 if(normalizedWasserstein_ and !baryTree->notNeedToNormalize(i)) {
464 bool const nestingShortener = adjustNestingT(
465 barycenter, birth, death, i, vNew, v2New, tMin, tMax);
466 noNestingShortener += nestingShortener;
467
468 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
469 getInterpolationVectorDebugMsg<dataType>(birth, death, vNew, v2New, i,
470 t, tMin, tMax,
471 "after adjustNestingT", ssT);
472 // ------------------------------------------------------------------
473 }
474
475 // - Compute interpolation
476 double const tNew = t * (tMax - tMin) + tMin;
477 double interBirth
478 = birth - vNew[i][0] + tNew * (vNew[i][0] + v2New[i][0]);
479 double interDeath
480 = death - vNew[i][1] + tNew * (vNew[i][1] + v2New[i][1]);
481 if(normalizedWasserstein_ and !baryTree->notNeedToNormalize(i)) {
482 double const coef = (interParentDeath - interParentBirth);
483 interBirth *= coef;
484 interBirth += interParentBirth;
485 interDeath *= coef;
486 interDeath += interParentBirth;
487 }
488 interpolationVector[nodeBirth] = interBirth;
489 interpolationVector[nodeDeath] = interDeath;
490
491 // - Verify NaN
492 if(std::isnan(interpolationVector[nodeBirth])
493 or std::isnan(interpolationVector[nodeDeath])) {
494 printMsg(ssT.str());
495 printErr("NOT A NUMBER");
496 }
497 // - Verify points below diagonal
498 double const eps = POINTS_BELOW_DIAG_TOLERANCE;
499 if(interpolationVector[nodeBirth] > interpolationVector[nodeDeath]
500 and interpolationVector[nodeBirth] - interpolationVector[nodeDeath]
501 < eps) {
502 interpolationVector[nodeBirth] = interpolationVector[nodeDeath];
503 }
504 if(interpolationVector[nodeBirth] > interpolationVector[nodeDeath]) {
505 ++cptBelowDiagonal;
506 printMsg(ssT.str());
507 std::streamsize const sSize = std::cout.precision();
508 std::stringstream ss;
509 ss << std::setprecision(12) << interpolationVector[nodeBirth] << " > "
510 << interpolationVector[nodeDeath];
511 printErr(ss.str());
512 std::cout.precision(sSize);
513 }
514 // - Verify nesting condition
515 bool const verifyNesting = !baryTree->notNeedToNormalize(i);
516 if(normalizedWasserstein_ and verifyNesting) {
517 if(interpolationVector[nodeBirth] < interParentBirth
518 and (interParentBirth - interpolationVector[nodeBirth]) < eps)
519 interpolationVector[nodeBirth] = interParentBirth;
520 if(interpolationVector[nodeBirth] > interParentDeath
521 and (interpolationVector[nodeBirth] - interParentDeath) < eps) {
522 interpolationVector[nodeBirth] = interParentDeath;
523 }
524 if(interpolationVector[nodeDeath] < interParentBirth
525 and (interParentBirth - interpolationVector[nodeDeath]) < eps) {
526 interpolationVector[nodeDeath] = interParentBirth;
527 }
528 if(interpolationVector[nodeDeath] > interParentDeath
529 and (interpolationVector[nodeDeath] - interParentDeath) < eps)
530 interpolationVector[nodeDeath] = interParentDeath;
531 }
532 if(normalizedWasserstein_ and verifyNesting
533 and (interpolationVector[nodeBirth] < interParentBirth
534 or interpolationVector[nodeBirth] > interParentDeath
535 or interpolationVector[nodeDeath] < interParentBirth
536 or interpolationVector[nodeDeath] > interParentDeath)) {
537 ++cptNotNesting;
538 printMsg(ssT.str());
539 std::streamsize const sSize = std::cout.precision();
540 std::stringstream ss;
541 ss << std::setprecision(12) << interpolationVector[nodeBirth] << " _ "
542 << interpolationVector[nodeDeath] << " --- " << interParentBirth
543 << " _ " << interParentDeath;
544 printErr(ss.str());
545 std::cout.precision(sSize);
546 }
547
548 // - Push children to the queue
549 std::vector<ftm::idNode> children;
550 baryTree->getChildren(i, children);
551 for(auto child : children)
552 queue.emplace(child);
553 }
554 if(noNestingShortener != 0)
555 printWrn("[getInterpolationVector] "
556 + std::to_string(noNestingShortener)
557 + " nesting vector shortener.");
558 if(noDiagonalShortener != 0)
559 printMsg("[getInterpolationVector] "
560 + std::to_string(noDiagonalShortener)
561 + " diagonal vector shortener.",
563 if(cptBelowDiagonal != 0)
564 printErr("[getInterpolationVector] point below diagonal.");
565 if(cptNotNesting != 0)
566 printErr("[getInterpolationVector] nesting condition not ok.");
567
568 interpolationVectorT.resize(scalarsVector.size());
569 for(unsigned int i = 0; i < interpolationVectorT.size(); ++i)
570 interpolationVectorT[i] = interpolationVector[i];
571 }
572
573 template <class dataType>
575 std::vector<double *> &v,
576 std::vector<double *> &v2,
577 size_t vSize,
578 double t,
579 ftm::MergeTree<dataType> &interpolated,
580 bool transposeVector = true) {
581 ftm::FTMTree_MT *barycenterTree = &(barycenter.tree);
582
583 // Compute new scalars vector
584 std::vector<dataType> newScalarsVector;
586 barycenter, v, v2, vSize, t, newScalarsVector, transposeVector);
587
588 // Create new tree
589 interpolated
590 = ttk::ftm::createEmptyMergeTree<dataType>(newScalarsVector.size());
591 ttk::ftm::setTreeScalars<dataType>(interpolated, newScalarsVector);
592 ftm::FTMTree_MT *treeNew = &(interpolated.tree);
593
594 // Copy the barycenter tree structure
595 treeNew->copyMergeTreeStructure(barycenterTree);
596
597 // Delete diagonal and almost-diagonal points
598 persistenceThresholding<dataType>(treeNew, 0.001); // 0.001 %
599 }
600
601 template <class dataType>
603 std::vector<std::vector<double>> &v,
604 std::vector<std::vector<double>> &v2,
605 double t,
606 ftm::MergeTree<dataType> &interpolated) {
607 std::vector<double *> pV, pV2;
608 vectorsToPointers(v, pV);
609 vectorsToPointers(v2, pV2);
611 barycenter, pV, pV2, v[0].size(), t, interpolated, false);
612 }
613
614 template <class dataType>
616 std::vector<std::vector<double *>> &vS,
617 std::vector<std::vector<double *>> &v2s,
618 size_t vSize,
619 std::vector<double> &ts,
620 ftm::MergeTree<dataType> &interpolated,
621 bool transposeVector = true) {
623 barycenter, vS[0], v2s[0], vSize, ts[0], interpolated, transposeVector);
624 for(unsigned int i = 1; i < vS.size(); ++i) {
625 ftm::MergeTree<dataType> newInterpolated;
626 getInterpolation<dataType>(interpolated, vS[i], v2s[i], vSize, ts[i],
627 newInterpolated, transposeVector);
628 interpolated = newInterpolated;
629 }
630 }
631
632 template <class dataType>
633 void
635 std::vector<std::vector<std::vector<double>>> &vS,
636 std::vector<std::vector<std::vector<double>>> &v2s,
637 std::vector<double> &ts,
638 ftm::MergeTree<dataType> &interpolated) {
639 std::vector<std::vector<double *>> pVS, pV2s;
641 vectorOfVectorsToPointers(v2s, pV2s);
643 barycenter, pVS, pV2s, vS[0][0].size(), ts, interpolated, false);
644 }
645
646 template <class dataType>
647 void
649 std::vector<std::vector<std::vector<double>>> &vS,
650 std::vector<std::vector<std::vector<double>>> &v2s,
651 std::vector<std::vector<double>> &v,
652 std::vector<std::vector<double>> &v2,
653 std::vector<double> &ts,
654 double t,
655 ftm::MergeTree<dataType> &interpolated) {
656 std::vector<std::vector<std::vector<double>>> vSTemp = vS, v2sTemp = v2s;
657 vSTemp.push_back(v);
658 v2sTemp.push_back(v2);
659 std::vector<double> tsTemp = ts;
660 if(tsTemp.size() != 0)
661 tsTemp[vSTemp.size() - 1] = t;
662 else
663 tsTemp.push_back(t);
664 getMultiInterpolation(barycenter, vSTemp, v2sTemp, tsTemp, interpolated);
665 }
666
667 // ----------------------------------------------------------------------------
668 // Vector Utils
669 // ----------------------------------------------------------------------------
670 void callGramSchmidt(std::vector<std::vector<double>> &vS,
671 std::vector<double> &v,
672 std::vector<double> &newV);
673
674 void vectorToPointer(std::vector<double> &vec, double *&pVec);
675
676 void vectorsToPointers(std::vector<std::vector<double>> &vec,
677 std::vector<double *> &pVec);
678
680 std::vector<std::vector<std::vector<double>>> &vS,
681 std::vector<std::vector<double *>> &pVS);
682
683 void pointerToVector(double *pVec, size_t size, std::vector<double> &vec);
684
685 void pointersToVectors(std::vector<double *> &pVec,
686 std::vector<size_t> sizes,
687 std::vector<std::vector<double>> &vec);
688
689 void pointersToVectors(std::vector<double *> &pVec,
690 size_t size,
691 std::vector<std::vector<double>> &vec);
692 }; // MergeTreePrincipalGeodesicsBase class
693
694} // namespace ttk
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
#define POINTS_BELOW_DIAG_TOLERANCE
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:159
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
void computeOneDistance(const ftm::MergeTree< dataType > &tree1, const ftm::MergeTree< dataType > &tree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &matching, dataType &distance, bool isCalled=false, bool useDoubleInput=false, bool isFirstInput=true)
void persistenceThresholding(ftm::FTMTree_MT *tree, double persistenceThresholdT, std::vector< ftm::idNode > &deletedNodes)
double getGeodesicVectorMiddle(std::vector< double > &v, std::vector< double > &v2)
dataType computeReconstructionError(ftm::MergeTree< dataType > &barycenter, std::vector< ftm::MergeTree< dataType > > &inputTrees, std::vector< std::vector< std::vector< double > > > &vS, std::vector< std::vector< std::vector< double > > > &v2s, std::vector< std::vector< double > > &allTreesTs)
void getInterpolationVectorDebugMsg(dataType birth, dataType death, std::vector< std::vector< double > > &vNew, std::vector< std::vector< double > > &v2New, int i, double t, double tMin, double tMax, const std::string &msg, std::stringstream &ssT)
std::vector< std::vector< double > > allTreesTs_
std::vector< std::vector< std::vector< double > > > v2s_
void vectorToPointer(std::vector< double > &vec, double *&pVec)
void pointersToVectors(std::vector< double * > &pVec, std::vector< size_t > sizes, std::vector< std::vector< double > > &vec)
double getTNew(ftm::MergeTree< dataType > &barycenter, std::vector< std::vector< double > > &v, std::vector< std::vector< double > > &v2, int i, double t)
std::vector< std::vector< std::vector< double > > > trees2V2s_
void getMultiInterpolation(ftm::MergeTree< dataType > &barycenter, std::vector< std::vector< double * > > &vS, std::vector< std::vector< double * > > &v2s, size_t vSize, std::vector< double > &ts, ftm::MergeTree< dataType > &interpolated, bool transposeVector=true)
std::vector< std::vector< std::vector< double > > > vS_
void getInterpolation(ftm::MergeTree< dataType > &barycenter, std::vector< double * > &v, std::vector< double * > &v2, size_t vSize, double t, ftm::MergeTree< dataType > &interpolated, bool transposeVector=true)
void vectorsToPointers(std::vector< std::vector< double > > &vec, std::vector< double * > &pVec)
bool adjustNestingT(ftm::MergeTree< dataType > &ttkNotUsed(barycenter), dataType baryBirth, dataType baryDeath, ftm::idNode node, std::vector< std::vector< double > > &vNew, std::vector< std::vector< double > > &v2New, double &tMin, double &tMax)
std::vector< std::vector< double > > allTs_
std::vector< std::vector< double > > branchesCorrelationMatrix_
void getMultiInterpolation(ftm::MergeTree< dataType > &barycenter, std::vector< std::vector< std::vector< double > > > &vS, std::vector< std::vector< std::vector< double > > > &v2s, std::vector< double > &ts, ftm::MergeTree< dataType > &interpolated)
std::vector< std::vector< double > > persCorrelationMatrix_
std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > baryMatchings_
std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > baryMatchings2_
bool adjustDiagonalT(dataType baryBirth, dataType baryDeath, ftm::idNode node, std::vector< std::vector< double > > &vNew, std::vector< std::vector< double > > &v2New, double &tMin, double &tMax)
void getMultiInterpolation(ftm::MergeTree< dataType > &barycenter, std::vector< std::vector< std::vector< double > > > &vS, std::vector< std::vector< std::vector< double > > > &v2s, std::vector< std::vector< double > > &v, std::vector< std::vector< double > > &v2, std::vector< double > &ts, double t, ftm::MergeTree< dataType > &interpolated)
void pointerToVector(double *pVec, size_t size, std::vector< double > &vec)
void getInterpolation(ftm::MergeTree< dataType > &barycenter, std::vector< std::vector< double > > &v, std::vector< std::vector< double > > &v2, double t, ftm::MergeTree< dataType > &interpolated)
void getInterpolationVector(ftm::MergeTree< dataType > &barycenter, std::vector< double * > &v, std::vector< double * > &v2, size_t vSize, double t, std::vector< dataType > &interpolationVectorT, bool transposeVector)
std::vector< std::vector< std::vector< double > > > trees2Vs_
std::vector< std::vector< double > > allScaledTs_
void vectorOfVectorsToPointers(std::vector< std::vector< std::vector< double > > > &vS, std::vector< std::vector< double * > > &pVS)
dataType computeReconstructionError(ftm::MergeTree< dataType > &barycenter, std::vector< ftm::MergeTree< dataType > > &inputTrees, std::vector< std::vector< double * > > &vS, std::vector< std::vector< double * > > &v2s, size_t vSize, std::vector< std::vector< double > > &allTreesTs, std::vector< double > &reconstructionErrors, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &matchings, bool transposeVector=true)
void updateT(double newT, double m, double &tMin, double &tMax, bool updateTMin)
dataType computeReconstructionError(ftm::MergeTree< dataType > &barycenter, std::vector< ftm::MergeTree< dataType > > &inputTrees, std::vector< std::vector< std::vector< double > > > &vS, std::vector< std::vector< std::vector< double > > > &v2s, std::vector< std::vector< double > > &allTreesTs, std::vector< double > &reconstructionErrors)
void callGramSchmidt(std::vector< std::vector< double > > &vS, std::vector< double > &v, std::vector< double > &newV)
void getChildren(idNode nodeId, std::vector< idNode > &res) const
std::tuple< ftm::idNode, ftm::idNode > getBirthDeathNode(idNode nodeId) const
void copyMergeTreeStructure(const FTMTree_MT *tree)
idNode getRoot() const
idNode getParentSafe(idNode nodeId) const
std::tuple< dataType, dataType > getBirthDeath(idNode nodeId) const
bool notNeedToNormalize(idNode nodeId) const
T1 pow(const T1 val, const T2 n)
Definition Geometry.h:456
void addVectorsProjection(const std::vector< T > &a, const std::vector< T > &b, std::vector< T > &a_out, std::vector< T > &b_out)
Definition Geometry.cpp:690
void transposeMatrix(const std::vector< std::vector< T > > &a, std::vector< std::vector< T > > &out)
Definition Geometry.cpp:818
void setTreeScalars(MergeTree< dataType > &mergeTree, std::vector< dataType > &scalarsVector)
void getTreeScalars(const ftm::FTMTree_MT *tree, std::vector< dataType > &scalarsVector)
MergeTree< dataType > createEmptyMergeTree(int scalarSize)
unsigned int idNode
Node index in vect_nodes_.
TTK base package defining the standard types.
ftm::FTMTree_MT tree
Definition FTMTree_MT.h:906
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)