10 class TriangulationType,
11 typename SparseMatrixType = Eigen::SparseMatrix<T>>
14 const TriangulationType &triangulation) {
18 using Triplet = Eigen::Triplet<T>;
19 const auto vertexNumber = triangulation.getNumberOfVertices();
20 const auto edgeNumber = triangulation.getNumberOfEdges();
23 if(vertexNumber <= 0) {
27 const auto threadNumber = dbg.getThreadNumber();
30 output.resize(vertexNumber, vertexNumber);
35 std::vector<Triplet> triplets(vertexNumber + 2 * edgeNumber);
38#ifdef TTK_ENABLE_OPENMP
39#pragma omp parallel for num_threads(threadNumber)
41 for(SimplexId i = 0; i < vertexNumber; ++i) {
42 const auto nneigh = triangulation.getVertexNeighborNumber(i);
43 triplets[i] = Triplet(i, i, T(nneigh));
47#ifdef TTK_ENABLE_OPENMP
48#pragma omp parallel for num_threads(threadNumber)
50 for(SimplexId i = 0; i < edgeNumber; ++i) {
52 std::vector<SimplexId> edgeVertices(2);
53 for(SimplexId j = 0; j < 2; ++j) {
54 triangulation.getEdgeVertex(i, j, edgeVertices[j]);
57 triplets[vertexNumber + 2 * i]
58 = Triplet(edgeVertices[0], edgeVertices[1], T(-1.0));
59 triplets[vertexNumber + 2 * i + 1]
60 = Triplet(edgeVertices[1], edgeVertices[0], T(-1.0));
63#ifndef __clang_analyzer__
64 output.setFromTriplets(triplets.begin(), triplets.end());
68 "Computed Discrete Laplacian", 1.0, tm.getElapsedTime(), threadNumber);
74 class TriangulationType,
75 typename SparseMatrixType = Eigen::SparseMatrix<T>>
78 const TriangulationType &triangulation) {
82 using Triplet = Eigen::Triplet<T>;
83 const auto vertexNumber = triangulation.getNumberOfVertices();
84 const auto edgeNumber = triangulation.getNumberOfEdges();
86 const auto threadNumber = dbg.getThreadNumber();
89 if(vertexNumber <= 0) {
94 output.resize(vertexNumber, vertexNumber);
99 std::vector<Triplet> triplets(vertexNumber + 2 * edgeNumber);
101 std::vector<SimplexId> edgeTriangles{};
102 std::vector<T> angles{};
105#ifdef TTK_ENABLE_OPENMP
106#pragma omp parallel for num_threads(threadNumber) \
107 firstprivate(edgeTriangles, angles)
109 for(SimplexId i = 0; i < edgeNumber; ++i) {
111 edgeTriangles.clear();
115 std::array<SimplexId, 3> edgeVertices{};
116 for(SimplexId j = 0; j < 2; ++j) {
117 triangulation.getEdgeVertex(i, j, edgeVertices[j]);
122 const auto trianglesNumber = triangulation.getEdgeTriangleNumber(i);
124 edgeTriangles.resize(trianglesNumber);
125 for(SimplexId j = 0; j < trianglesNumber; ++j) {
126 triangulation.getEdgeTriangle(i, j, edgeTriangles[j]);
130 angles.reserve(trianglesNumber);
132 for(
const auto &j : edgeTriangles) {
137 for(SimplexId k = 0; k < 3; ++k) {
138 triangulation.getTriangleVertex(j, k, thirdNeigh);
139 if(thirdNeigh != edgeVertices[0] && thirdNeigh != edgeVertices[1]) {
142 edgeVertices[2] = thirdNeigh;
147 std::array<float, 9> coords{};
148 for(SimplexId k = 0; k < 3; ++k) {
149 triangulation.getVertexPoint(
150 edgeVertices[k], coords[3 * k], coords[3 * k + 1], coords[3 * k + 2]);
162 for(
auto &angle : angles) {
163 cotan_weight += T(1.0) / std::tan(angle);
168 triplets[2 * i] = Triplet(edgeVertices[0], edgeVertices[1], -cotan_weight);
170 = Triplet(edgeVertices[1], edgeVertices[0], -cotan_weight);
174#ifdef TTK_ENABLE_OPENMP
175#pragma omp parallel for num_threads(threadNumber)
177 for(SimplexId i = 0; i < vertexNumber; ++i) {
179 const auto nEdges{triangulation.getVertexEdgeNumber(i)};
181 for(SimplexId j = 0; j < nEdges; ++j) {
183 triangulation.getVertexEdge(i, j, e);
184 vertWeightSum += triplets[2 * e].value();
187 triplets[2 * edgeNumber + i] = Triplet(i, i, -vertWeightSum);
190#ifndef __clang_analyzer__
191 output.setFromTriplets(triplets.begin(), triplets.end());
194 dbg.printMsg(
"Computed Laplacian with Cotan Weights", 1.0,
195 tm.getElapsedTime(), threadNumber);
200#define LAPLACIAN_SPECIALIZE(TYPE) \
201 template int ttk::Laplacian::discreteLaplacian<TYPE>( \
202 Eigen::SparseMatrix<TYPE> &, const Debug &dbg, const Triangulation &); \
203 template int ttk::Laplacian::cotanWeights<TYPE>( \
204 Eigen::SparseMatrix<TYPE> &, const Debug &dbg, const Triangulation &)
207LAPLACIAN_SPECIALIZE(
float);
208LAPLACIAN_SPECIALIZE(
double);
T angle(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
int discreteLaplacian(SparseMatrixType &output, const Debug &dbg, const TriangulationType &triangulation)
Compute the Laplacian matrix of the graph.
int cotanWeights(SparseMatrixType &output, const Debug &dbg, const TriangulationType &triangulation)
Compute the Laplacian matrix of the graph using the cotangente weights method.
int SimplexId
Identifier type for simplices of any dimension.