16 T *
const outputFieldPointer,
17 const unsigned int eigenNumber,
18 bool computeStatistics,
19 T *
const outputStatistics)
const {
21#if defined(TTK_ENABLE_EIGEN) && defined(TTK_ENABLE_SPECTRA)
26 this->
printMsg(
"Beginning computation...");
28#ifdef TTK_ENABLE_OPENMP
32 using SpMat = Eigen::SparseMatrix<T>;
33 using DMat = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
36 const auto vertexNumber = triangulation.getNumberOfVertices();
41 Laplacian::cotanWeights<T>(lap, *
this, triangulation);
43 eigen_plain_assert(lap.cols() == lap.rows());
48 const size_t minEigenNumber = 20;
50 if(eigenNumber == 0) {
53 }
else if(eigenNumber < minEigenNumber) {
57 Spectra::SparseSymMatProd<T> op(lap);
58 Spectra::SymEigsSolver<
decltype(op)> solver(op, m, 2 * m);
63 int const nconv = solver.compute(Spectra::SortRule::LargestAlge);
65 switch(solver.info()) {
66 case Spectra::CompInfo::NumericalIssue:
69 case Spectra::CompInfo::NotConverging:
70 this->
printMsg(
"No Convergence! (" + std::to_string(nconv) +
" out of "
71 + std::to_string(eigenNumber) +
" values computed)",
74 case Spectra::CompInfo::NotComputed:
81 DMat eigenvectors = solver.eigenvectors();
83 auto outputEigenFunctions =
static_cast<T *
>(outputFieldPointer);
85#ifdef TTK_ENABLE_OPENMP
86#pragma omp parallel for num_threads(threadNumber_)
88 for(
SimplexId i = 0; i < vertexNumber; ++i) {
89 for(
size_t j = 0; j < eigenNumber; ++j) {
91 outputEigenFunctions[i * eigenNumber + j] = eigenvectors(i, j);
95 if(computeStatistics && outputStatistics !=
nullptr) {
98 const int statsComp = 4;
100 auto outputStats =
static_cast<T *
>(outputStatistics);
103#ifdef TTK_ENABLE_OPENMP
104#pragma omp parallel for num_threads(threadNumber_)
106 for(
SimplexId i = 0; i < vertexNumber; ++i) {
107 const auto k = i * statsComp;
109 outputStats[k] = outputEigenFunctions[i * eigenNumber];
110 outputStats[k + 1] = outputEigenFunctions[i * eigenNumber];
111 outputStats[k + 2] = outputEigenFunctions[i * eigenNumber];
112 outputStats[k + 3] = outputEigenFunctions[i * eigenNumber]
113 * outputEigenFunctions[i * eigenNumber];
115 for(
size_t j = 1; j < eigenNumber; ++j) {
116 outputStats[k] = std::min<T>(
117 outputEigenFunctions[i * eigenNumber + j], outputStats[k]);
118 outputStats[k + 1] = std::max<T>(
119 outputEigenFunctions[i * eigenNumber + j], outputStats[k]);
120 outputStats[k + 2] += outputEigenFunctions[i * eigenNumber + j];
121 outputStats[k + 3] += outputEigenFunctions[i * eigenNumber + j]
122 * outputEigenFunctions[i * eigenNumber + j];
139 std::vector<std::string>{
"Spectra support disabled, computation skipped!",
140 "Please re-compile TTK with Eigen AND Spectra "
141 "support to enable this feature."},
int execute(const TriangulationType &triangulation, T *const outputFieldPointer, const unsigned int eigenNumber=500, bool computeStatistics=false, T *const outputStatistics=nullptr) const
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)