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 
26 namespace Gudhi {
27 
28 namespace coxeter_triangulation {
29 
44 template <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
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
const Vector & offset() const
Vector that defines the offset of the triangulation.
Definition: Freudenthal_triangulation.h:99
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
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
const Matrix & matrix() const
Matrix that defines the linear transformation of the triangulation.
Definition: Freudenthal_triangulation.h:96
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
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
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