Loading...
Searching...
No Matches
Freudenthal_triangulation.h
1/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2 * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3 * Author(s): Siargey Kachanovich
4 *
5 * Copyright (C) 2019 Inria
6 *
7 * Modification(s):
8 * - YYYY/MM Author: Description of the modification
9 */
10
11#ifndef FREUDENTHAL_TRIANGULATION_H_
12#define FREUDENTHAL_TRIANGULATION_H_
13
14#include <vector>
15#include <algorithm> // for std::sort
16#include <cmath> // for std::floor
17#include <numeric> // for std::iota
18#include <cstdlib> // for std::size_t
19
20#include <Eigen/Eigenvalues>
21#include <Eigen/SVD>
22
23#include <gudhi/Permutahedral_representation.h>
24#include <gudhi/Debug_utils.h> // for GUDHI_CHECK
25
26namespace Gudhi {
27
28namespace coxeter_triangulation {
29
44template <class Permutahedral_representation_ =
45 Permutahedral_representation<std::vector<int>, std::vector<std::vector<std::size_t> > > >
47 using Matrix = Eigen::MatrixXd;
48 using Vector = Eigen::VectorXd;
49
50 public:
52 using Simplex_handle = Permutahedral_representation_;
53
55 using Vertex_handle = typename Permutahedral_representation_::Vertex;
56
61 : Freudenthal_triangulation(dimension, Matrix::Identity(dimension, dimension), Vector::Zero(dimension)) {
62 is_freudenthal_ = true;
63 }
64
71 Freudenthal_triangulation(std::size_t dimension, const Matrix& matrix)
73
83 Freudenthal_triangulation(unsigned dimension, const Matrix& matrix, const Vector& offset)
84 : dimension_(dimension),
85 matrix_(matrix),
86 offset_(offset),
87 colpivhouseholderqr_(matrix_.colPivHouseholderQr()),
88 is_freudenthal_(false) {
89 GUDHI_CHECK(dimension == offset_.size(), std::invalid_argument("Offset must be of size 'dimension'"));
90 }
91
93 unsigned dimension() const { return dimension_; }
94
96 const Matrix& matrix() const { return matrix_; }
97
99 const Vector& offset() const { return offset_; }
100
104 void change_matrix(const Eigen::MatrixXd& matrix) {
105 matrix_ = matrix;
106 colpivhouseholderqr_ = matrix.colPivHouseholderQr();
107 is_freudenthal_ = false;
108 }
109
113 void change_offset(const Eigen::VectorXd& offset) {
114 offset_ = offset;
115 is_freudenthal_ = false;
116 }
117
134 template <class Point_d>
135 Simplex_handle locate_point(const Point_d& point, double scale = 1) const {
136 using Ordered_set_partition = typename Simplex_handle::OrderedSetPartition;
137 using Part = typename Ordered_set_partition::value_type;
138 unsigned d = point.size();
139 GUDHI_CHECK(d == dimension_,
140 std::invalid_argument("The point must be of the same dimension as the triangulation"));
141 double error = 1e-9;
142 Simplex_handle output;
143 std::vector<double> z;
144 if (is_freudenthal_) {
145 for (std::size_t i = 0; i < d; i++) {
146 double x_i = scale * point[i];
147 int y_i = std::floor(x_i);
148 output.vertex().push_back(y_i);
149 z.push_back(x_i - y_i);
150 }
151 } else {
152 Eigen::VectorXd p_vect(d);
153 for (std::size_t i = 0; i < d; i++) p_vect(i) = point[i];
154 Eigen::VectorXd x_vect = colpivhouseholderqr_.solve(p_vect - offset_);
155 for (std::size_t i = 0; i < d; i++) {
156 double x_i = scale * x_vect(i);
157 int y_i = std::floor(x_i);
158 output.vertex().push_back(y_i);
159 z.push_back(x_i - y_i);
160 }
161 }
162 z.push_back(0);
163 Part indices(d + 1);
164 std::iota(indices.begin(), indices.end(), 0);
165 std::sort(indices.begin(), indices.end(), [&z](std::size_t i1, std::size_t i2) { return z[i1] > z[i2]; });
166
167 output.partition().push_back(Part(1, indices[0]));
168 for (std::size_t i = 1; i <= d; ++i)
169 if (z[indices[i - 1]] > z[indices[i]] + error)
170 output.partition().push_back(Part(1, indices[i]));
171 else
172 output.partition().back().push_back(indices[i]);
173 return output;
174 }
175
184 Eigen::VectorXd cartesian_coordinates(const Vertex_handle& vertex, double scale = 1) const {
185 Eigen::VectorXd v_vect(dimension_);
186 for (std::size_t j = 0; j < dimension_; j++) v_vect(j) = vertex[j] / scale;
187 return matrix_ * v_vect + offset_;
188 }
189
198 Eigen::VectorXd barycenter(const Simplex_handle& simplex, double scale = 1) const {
199 Eigen::VectorXd res_vector(dimension_);
200 res_vector.setZero(dimension_, 1);
201 for (auto v : simplex.vertex_range()) {
202 res_vector += cartesian_coordinates(v, scale);
203 }
204 return (1. / (simplex.dimension() + 1)) * res_vector;
205 }
206
207 protected:
208 unsigned dimension_;
209 Matrix matrix_;
210 Vector offset_;
211 Eigen::ColPivHouseholderQR<Matrix> colpivhouseholderqr_;
212 bool is_freudenthal_;
213};
214
215} // namespace coxeter_triangulation
216
217} // namespace Gudhi
218
219#endif
A class that stores any affine transformation of the Freudenthal-Kuhn triangulation.
Definition: Freudenthal_triangulation.h:46
const Vector & offset() const
Vector that defines the offset of the triangulation.
Definition: Freudenthal_triangulation.h:99
Freudenthal_triangulation(unsigned dimension, const Matrix &matrix, const Vector &offset)
Constructor of the Freudenthal-Kuhn triangulation of a given dimension under an affine transformation...
Definition: Freudenthal_triangulation.h:83
Eigen::VectorXd barycenter(const Simplex_handle &simplex, double scale=1) const
Returns the Cartesian coordinates of the barycenter of a given simplex.
Definition: Freudenthal_triangulation.h:198
Simplex_handle locate_point(const Point_d &point, double scale=1) const
Returns the permutahedral representation of the simplex in the triangulation that contains a given qu...
Definition: Freudenthal_triangulation.h:135
typename Permutahedral_representation_::Vertex Vertex_handle
Type of the vertices in the triangulation.
Definition: Freudenthal_triangulation.h:55
Freudenthal_triangulation(std::size_t dimension)
Constructor of the Freudenthal-Kuhn triangulation of a given dimension.
Definition: Freudenthal_triangulation.h:60
Freudenthal_triangulation(std::size_t dimension, const Matrix &matrix)
Constructor of the Freudenthal-Kuhn triangulation of a given dimension under a linear transformation ...
Definition: Freudenthal_triangulation.h:71
Permutahedral_representation_ Simplex_handle
Type of the simplices in the triangulation.
Definition: Freudenthal_triangulation.h:52
void change_offset(const Eigen::VectorXd &offset)
Change the offset vector to a given value.
Definition: Freudenthal_triangulation.h:113
const Matrix & matrix() const
Matrix that defines the linear transformation of the triangulation.
Definition: Freudenthal_triangulation.h:96
Eigen::VectorXd cartesian_coordinates(const Vertex_handle &vertex, double scale=1) const
Returns the Cartesian coordinates of the given vertex.
Definition: Freudenthal_triangulation.h:184
unsigned dimension() const
Dimension of the triangulation.
Definition: Freudenthal_triangulation.h:93
void change_matrix(const Eigen::MatrixXd &matrix)
Change the linear transformation matrix to a given value.
Definition: Freudenthal_triangulation.h:104
Class that represents an ordered set partition of a set {0,...,n-1} in k parts as a pair of an unorde...
Definition: Ordered_set_partition_iterator.h:32