181 template <
typename scalarType,
typename triangulationType>
184 const scalarType *
const scalars,
185 const triangulationType *triangulation);
194 template <
typename scalarType>
198 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
199 std::vector<PersistencePair> &diagram)
const;
209 template <
typename scalarType,
class triangulationType>
210 int execute(std::vector<PersistencePair> &CTDiagram,
211 const scalarType *inputScalars,
212 const size_t scalarsMTime,
214 const triangulationType *triangulation);
216 template <
typename scalarType,
class triangulationType>
217 int executeFTM(std::vector<PersistencePair> &CTDiagram,
218 const scalarType *inputScalars,
220 const triangulationType *triangulation);
222 template <
class triangulationType>
225 const triangulationType *triangulation);
226 template <
typename scalarType,
class triangulationType>
228 const scalarType *inputScalars,
229 const triangulationType *triangulation);
231 template <
class triangulationType>
234 const triangulationType *triangulation);
236 template <
typename scalarType,
class triangulationType>
238 const scalarType *inputScalars,
239 const size_t scalarsMTime,
241 const triangulationType *triangulation);
243 template <
class triangulationType>
246 template <
class triangulationType>
247 void checkManifold(
const triangulationType *
const triangulation);
312template <
typename scalarType>
316 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
317 std::vector<PersistencePair> &diagram)
const {
320 diagram.resize(numberOfPairs);
324 const bool type = std::get<3>(pairs[i]);
349 diagram.back().isFinite =
false;
354template <
typename scalarType,
typename triangulationType>
356 std::vector<PersistencePair> &persistencePairs,
357 const scalarType *
const scalars,
358 const triangulationType *triangulation) {
360#ifdef TTK_ENABLE_OPENMP
361#pragma omp parallel for num_threads(threadNumber_)
363 for(std::size_t i = 0; i < persistencePairs.size(); ++i) {
364 auto &pair{persistencePairs[i]};
365 triangulation->getVertexPoint(pair.birth.id, pair.birth.coords[0],
366 pair.birth.coords[1], pair.birth.coords[2]);
367 pair.birth.
sfValue = scalars[pair.birth.id];
368 triangulation->getVertexPoint(pair.death.id, pair.death.coords[0],
369 pair.death.coords[1], pair.death.coords[2]);
370 pair.death.sfValue = scalars[pair.death.id];
374template <
typename scalarType,
class triangulationType>
376 const scalarType *inputScalars,
377 const size_t scalarsMTime,
379 const triangulationType *triangulation) {
383 checkProgressivityRequirement(triangulation);
384 checkManifold(triangulation);
389 case BACKEND::PERSISTENT_SIMPLEX:
390 executePersistentSimplex(CTDiagram, inputOffsets, triangulation);
392 case BACKEND::DISCRETE_MORSE_SANDWICH:
393 executeDiscreteMorseSandwich(
394 CTDiagram, inputScalars, scalarsMTime, inputOffsets, triangulation);
396 case BACKEND::PROGRESSIVE_TOPOLOGY:
397 executeProgressiveTopology(CTDiagram, inputOffsets, triangulation);
399 case BACKEND::APPROXIMATE_TOPOLOGY:
400 executeApproximateTopology(CTDiagram, inputScalars, triangulation);
403 executeFTM(CTDiagram, inputScalars, inputOffsets, triangulation);
406 printErr(
"No method was selected");
409 this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), this->threadNumber_);
412 augmentPersistenceDiagram(CTDiagram, inputScalars, triangulation);
415 sortPersistenceDiagram(CTDiagram, inputOffsets);
422template <
class triangulationType>
424 std::vector<PersistencePair> &CTDiagram,
426 const triangulationType *triangulation) {
429 const auto dim = triangulation->getDimensionality();
431 std::vector<ttk::PersistentSimplexPairs::PersistencePair> pairs{};
433 psp_.setDebugLevel(this->debugLevel_);
434 psp_.setThreadNumber(this->threadNumber_);
435 psp_.computePersistencePairs(pairs, inputOffsets, *triangulation);
436 dms_.setInputOffsets(inputOffsets);
441#ifdef TTK_ENABLE_OPENMP
442#pragma omp parallel for num_threads(threadNumber_)
444 for(
size_t i = 0; i < pairs.size(); ++i) {
445 auto &pair{pairs[i]};
447 pair.birth = dms_.getCellGreaterVertex(
448 Cell{pair.type, pair.birth}, *triangulation);
450 if(pair.death != -1) {
451 pair.death = dms_.getCellGreaterVertex(
452 Cell{pair.type + 1, pair.death}, *triangulation);
456 CTDiagram.reserve(pairs.size() + 1);
459 const auto nVerts = triangulation->getNumberOfVertices();
461 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
464 for(
const auto &p : pairs) {
465 const auto isFinite = (p.death >= 0);
466 const auto death = isFinite ? p.death : globmax;
468 const auto deathType = (isFinite && dim > 1)
474 }
else if(p.type == 1) {
477 const auto deathType = (isFinite && dim == 3)
483 }
else if(p.type == 2) {
494template <
typename scalarType,
class triangulationType>
496 std::vector<PersistencePair> &CTDiagram,
497 const scalarType *inputScalars,
498 const size_t scalarsMTime,
500 const triangulationType *triangulation) {
503 const auto dim = triangulation->getDimensionality();
505 dms_.buildGradient(inputScalars, scalarsMTime, inputOffsets, *triangulation);
506 std::vector<DiscreteMorseSandwich::PersistencePair> dms_pairs{};
507 dms_.computePersistencePairs(
508 dms_pairs, inputOffsets, *triangulation, this->IgnoreBoundary);
509 CTDiagram.resize(dms_pairs.size());
513#ifdef TTK_ENABLE_OPENMP
514#pragma omp parallel for num_threads(threadNumber_)
516 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
517 auto &pair{dms_pairs[i]};
519 pair.birth = dms_.getCellGreaterVertex(
520 Cell{pair.type, pair.birth}, *triangulation);
522 if(pair.death != -1) {
523 pair.death = dms_.getCellGreaterVertex(
524 Cell{pair.type + 1, pair.death}, *triangulation);
529 const auto nVerts = triangulation->getNumberOfVertices();
531 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
534#ifdef TTK_ENABLE_OPENMP
535#pragma omp parallel for num_threads(threadNumber_)
537 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
538 const auto &p{dms_pairs[i]};
539 const auto isFinite = (p.death >= 0);
540 const auto death = isFinite ? p.death : globmax;
548 }
else if(p.type == 1) {
556 }
else if(p.type == 2) {
569template <
typename scalarType,
class triangulationType>
571 std::vector<PersistencePair> &CTDiagram,
572 const scalarType *inputScalars,
573 const triangulationType *triangulation) {
575 approxT_.setDebugLevel(debugLevel_);
576 approxT_.setThreadNumber(threadNumber_);
579 approxT_.setStartingResolutionLevel(StartingResolutionLevel);
580 approxT_.setStoppingResolutionLevel(StoppingResolutionLevel);
581 approxT_.setPreallocateMemory(
true);
582 approxT_.setEpsilon(Epsilon);
584 std::vector<ApproximateTopology::PersistencePair> resultDiagram{};
586 approxT_.computeApproximatePD(
587 resultDiagram, inputScalars, (scalarType *)outputScalars_,
588 (
SimplexId *)outputOffsets_, (
int *)outputMonotonyOffsets_);
591 for(
const auto &p : resultDiagram) {
592 if(p.pairType == 0) {
597 }
else if(p.pairType == 2) {
602 }
else if(p.pairType == -1) {
613template <
class triangulationType>
615 std::vector<PersistencePair> &CTDiagram,
617 const triangulationType *triangulation) {
619 progT_.setDebugLevel(debugLevel_);
620 progT_.setThreadNumber(threadNumber_);
623 progT_.setStartingResolutionLevel(StartingResolutionLevel);
624 progT_.setStoppingResolutionLevel(StoppingResolutionLevel);
625 progT_.setTimeLimit(TimeLimit);
626 progT_.setIsResumable(IsResumable);
627 progT_.setPreallocateMemory(
true);
629 std::vector<ProgressiveTopology::PersistencePair> resultDiagram{};
631 progT_.computeProgressivePD(resultDiagram, inputOffsets);
634 for(
const auto &p : resultDiagram) {
635 if(p.pairType == 0) {
640 }
else if(p.pairType == 2) {
645 }
else if(p.pairType == -1) {
656template <
typename scalarType,
class triangulationType>
658 std::vector<PersistencePair> &CTDiagram,
659 const scalarType *inputScalars,
661 const triangulationType *triangulation) {
663 contourTree_.setVertexScalars(inputScalars);
665 contourTree_.setVertexSoSoffsets(inputOffsets);
666 contourTree_.setSegmentation(
false);
667 contourTree_.build<scalarType>(triangulation);
670 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> JTPairs;
671 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> STPairs;
672 contourTree_.computePersistencePairs<scalarType>(JTPairs,
true);
673 contourTree_.computePersistencePairs<scalarType>(STPairs,
false);
676 const auto JTSize = JTPairs.size();
677 const auto STSize = STPairs.size();
678 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>>
679 CTPairs(JTSize + STSize);
680 for(
size_t i = 0; i < JTSize; ++i) {
681 const auto &x = JTPairs[i];
683 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
true);
685 for(
size_t i = 0; i < STSize; ++i) {
686 const auto &x = STPairs[i];
688 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
false);
692 if(!CTPairs.empty()) {
695 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &a,
696 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &b) {
697 return std::get<2>(a) < std::get<2>(b);
700 std::sort(CTPairs.begin(), CTPairs.end(), cmp);
701 CTPairs.erase(CTPairs.end() - 1);
705 computeCTPersistenceDiagram<scalarType>(contourTree_, CTPairs, CTDiagram);
710template <
class triangulationType>
712 const triangulationType *
ttkNotUsed(triangulation)) {
714 if((BackEnd == BACKEND::PROGRESSIVE_TOPOLOGY
715 || BackEnd == BACKEND::APPROXIMATE_TOPOLOGY)
716 && !std::is_same<ttk::ImplicitWithPreconditions, triangulationType>::value
717 && !std::is_same<ttk::ImplicitNoPreconditions, triangulationType>::value) {
719 printWrn(
"Explicit, Compact or Periodic triangulation detected.");
720 printWrn(
"Defaulting to the FTM backend.");
722 BackEnd = BACKEND::FTM;
726template <
class triangulationType>
728 const triangulationType *
const triangulation) {
730 if(this->BackEnd != BACKEND::DISCRETE_MORSE_SANDWICH) {
734 if(!triangulation->isManifold()) {
735 this->printWrn(
"Non-manifold data-set detected.");
736 this->printWrn(
"Defaulting to the Persistence Simplex backend.");
738 this->BackEnd = BACKEND::PERSISTENT_SIMPLEX;
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionBoundaryVertices()
virtual int preconditionManifold()
TTK processing package for progressive Topological Data Analysis.
void setDelta(double data)
virtual int setThreadNumber(const int threadNumber)
Minimalist debugging class.
virtual int setDebugLevel(const int &debugLevel)
TTK DiscreteMorseSandwich processing package.
void setComputeSadMax(const bool data)
void setComputeMinSad(const bool data)
void preconditionTriangulation(AbstractTriangulation *const data)
void setComputeSadSad(const bool data)
ImplicitTriangulation is a class that provides time and memory efficient traversal methods on triangu...
TTK processing package for the computation of persistence diagrams.
int execute(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation)
int executePersistentSimplex(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
int StoppingResolutionLevel
int executeDiscreteMorseSandwich(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation)
ftm::FTMTreePP contourTree_
void setComputeSadSad(const bool data)
void setOutputMonotonyOffsets(void *data)
void sortPersistenceDiagram(std::vector< PersistencePair > &diagram, const SimplexId *const offsets) const
void preconditionTriangulation(AbstractTriangulation *triangulation)
ttk::ProgressiveTopology progT_
void setDeltaApproximate(double data)
void setBackend(const BACKEND be)
ttk::CriticalType getNodeType(ftm::FTMTree_MT *tree, ftm::TreeType treeType, const SimplexId vertexId) const
void checkProgressivityRequirement(const triangulationType *triangulation)
void setOutputScalars(void *data)
@ DISCRETE_MORSE_SANDWICH
int executeFTM(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const SimplexId *inputOffsets, const triangulationType *triangulation)
dcg::DiscreteGradient dcg_
int executeProgressiveTopology(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
ttk::ApproximateTopology approxT_
DiscreteMorseSandwich dms_
void setComputeMinSad(const bool data)
void setOutputOffsets(void *data)
void augmentPersistenceDiagram(std::vector< PersistencePair > &persistencePairs, const scalarType *const scalars, const triangulationType *triangulation)
Complete a ttk::DiagramType instance with scalar field values (useful for persistence) and 3D coordin...
void setComputeSadMax(const bool data)
void * outputMonotonyOffsets_
int executeApproximateTopology(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const triangulationType *triangulation)
PersistentSimplexPairs psp_
void checkManifold(const triangulationType *const triangulation)
int StartingResolutionLevel
int computeCTPersistenceDiagram(ftm::FTMTreePP &tree, const std::vector< std::tuple< ttk::SimplexId, ttk::SimplexId, scalarType, bool > > &pairs, std::vector< PersistencePair > &diagram) const
Textbook algorithm to find persistence pairs.
void preconditionTriangulation(AbstractTriangulation *const data)
Preprocess all the required connectivity requests on the triangulation.
TTK processing package for progressive Topological Data Analysis.
TTK discreteGradient processing package.
int setThreadNumber(const int n) override
FTMTree_MT * getSplitTree()
int setDebugLevel(const int &d) override
FTMTree_MT * getJoinTree()
void preconditionTriangulation(AbstractTriangulation *tri, const bool preproc=true)
CriticalType
default value for critical index
int SimplexId
Identifier type for simplices of any dimension.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)