diff options
author | Hind-M <hind.montassif@gmail.com> | 2022-01-18 16:30:33 +0100 |
---|---|---|
committer | Hind-M <hind.montassif@gmail.com> | 2022-01-18 16:30:33 +0100 |
commit | f7c3fd1033e8956777b82d84d231115cb5540bc3 (patch) | |
tree | 1bd6467863b75e7b11247a899c5172f99f14a3b4 /src/Coxeter_triangulation/include/gudhi/Functions | |
parent | aa600c433e1f756bec4323e29e86786b937d9443 (diff) | |
parent | de5aa9c891ef13c9fc2b2635bcd27ab873b0057b (diff) |
Merge remote-tracking branch 'upstream/master' into fetch_datasets
Diffstat (limited to 'src/Coxeter_triangulation/include/gudhi/Functions')
16 files changed, 1421 insertions, 0 deletions
diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h new file mode 100644 index 00000000..0533bb83 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Cartesian_product.h @@ -0,0 +1,157 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_CARTESIAN_PRODUCT_H_ +#define FUNCTIONS_CARTESIAN_PRODUCT_H_ + +#include <cstdlib> +#include <tuple> +#include <type_traits> // for std::enable_if +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/* Get the domain dimension of the tuple of functions. + */ +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_amb_d(const std::tuple<T...>& tuple) { + return 0; +} + +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I != sizeof...(T), std::size_t>::type get_amb_d(const std::tuple<T...>& tuple) { + return std::get<I>(tuple).amb_d() + get_amb_d<I + 1, T...>(tuple); +} + +/* Get the codomain dimension of the tuple of functions. + */ +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_cod_d(const std::tuple<T...>& tuple) { + return 0; +} + +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I != sizeof...(T), std::size_t>::type get_cod_d(const std::tuple<T...>& tuple) { + return std::get<I>(tuple).cod_d() + get_cod_d<I + 1, T...>(tuple); +} + +/* Get the seed of the tuple of functions. + */ +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I == sizeof...(T), void>::type get_seed(const std::tuple<T...>& tuple, + Eigen::VectorXd& point, std::size_t i = 0) {} + +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I != sizeof...(T), void>::type get_seed(const std::tuple<T...>& tuple, + Eigen::VectorXd& point, std::size_t i = 0) { + const auto& f = std::get<I>(tuple); + std::size_t n = f.amb_d(); + Eigen::VectorXd seed = f.seed(); + for (std::size_t j = 0; j < n; ++j) point(i + j) = seed(j); + get_seed<I + 1, T...>(tuple, point, i + n); +} + +/* Get the seed of the tuple of functions. + */ +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I == sizeof...(T), void>::type get_value(const std::tuple<T...>& tuple, + const Eigen::VectorXd& x, + Eigen::VectorXd& point, std::size_t i = 0, + std::size_t j = 0) {} + +template <std::size_t I = 0, typename... T> +inline typename std::enable_if<I != sizeof...(T), void>::type get_value(const std::tuple<T...>& tuple, + const Eigen::VectorXd& x, + Eigen::VectorXd& point, std::size_t i = 0, + std::size_t j = 0) { + const auto& f = std::get<I>(tuple); + std::size_t n = f.amb_d(); + std::size_t k = f.cod_d(); + Eigen::VectorXd x_i(n); + for (std::size_t l = 0; l < n; ++l) x_i(l) = x(i + l); + Eigen::VectorXd res = f(x_i); + for (std::size_t l = 0; l < k; ++l) point(j + l) = res(l); + get_value<I + 1, T...>(tuple, x, point, i + n, j + k); +} + +/** + * \class Cartesian_product + * \brief Constructs the function the zero-set of which is the Cartesian product + * of the zero-sets of some given functions. + * + * \tparam Functions A pack template parameter for functions. All functions should be models of + * the concept FunctionForImplicitManifold. + */ +template <class... Functions> +struct Cartesian_product { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result(cod_d_); + get_value(function_tuple_, p, result, 0, 0); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return amb_d_; } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return cod_d_; } + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result(amb_d_); + get_seed(function_tuple_, result, 0); + return result; + } + + /** + * \brief Constructor of the Cartesian product function. + * + * @param[in] functions The functions the zero-sets of which are factors in the + * Cartesian product of the resulting function. + */ + Cartesian_product(const Functions&... functions) : function_tuple_(std::make_tuple(functions...)) { + amb_d_ = get_amb_d(function_tuple_); + cod_d_ = get_cod_d(function_tuple_); + } + + private: + std::tuple<Functions...> function_tuple_; + std::size_t amb_d_, cod_d_; +}; + +/** + * \brief Static constructor of a Cartesian product function. + * + * @param[in] functions The functions the zero-sets of which are factors in the + * Cartesian product of the resulting function. + * + * \tparam Functions A pack template parameter for functions. All functions should be models of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <typename... Functions> +Cartesian_product<Functions...> make_product_function(const Functions&... functions) { + return Cartesian_product<Functions...>(functions...); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h new file mode 100644 index 00000000..0603afd8 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Constant_function.h @@ -0,0 +1,64 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_CONSTANT_FUNCTION_H_ +#define FUNCTIONS_CONSTANT_FUNCTION_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Constant_function + * \brief A class that encodes a constant function from R^d to R^k. + * This class does not have any implicit manifold in correspondence. + */ +struct Constant_function { + /** \brief Value of the function at a specified point. The value is constant. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + return value_; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const { return d_; }; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const { return k_; }; + + /** \brief No seed point is available. Throws an exception on evocation. */ + Eigen::VectorXd seed() const { throw "Seed invoked on a constant function.\n"; } + + Constant_function() {} + + /** + * \brief Constructor of a constant function from R^d to R^m. + * + * @param[in] d The domain dimension. + * @param[in] k The codomain dimension. + * @param[in] value The constant value of the function. + */ + Constant_function(std::size_t d, std::size_t k, const Eigen::VectorXd& value) : d_(d), k_(k), value_(value) {} + + private: + std::size_t d_, k_; + Eigen::VectorXd value_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h new file mode 100644 index 00000000..e1fe868f --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Embed_in_Rd.h @@ -0,0 +1,93 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_EMBED_IN_RD_H_ +#define FUNCTIONS_EMBED_IN_RD_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Embed_in_Rd + * \brief Embedding of an implicit manifold in a higher dimension. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + */ +template <class Function_> +struct Embed_in_Rd { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd x = p; + Eigen::VectorXd x_k(fun_.amb_d()), x_rest(d_ - fun_.amb_d()); + for (std::size_t i = 0; i < fun_.amb_d(); ++i) x_k(i) = x(i); + for (std::size_t i = fun_.amb_d(); i < d_; ++i) x_rest(i - fun_.amb_d()) = x(i); + Eigen::VectorXd result = fun_(x_k); + result.conservativeResize(this->cod_d()); + for (std::size_t i = fun_.cod_d(); i < this->cod_d(); ++i) result(i) = x_rest(i - fun_.cod_d()); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return d_; } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return d_ - (fun_.amb_d() - fun_.cod_d()); } + + /** \brief Returns a point on the zero-set of the embedded function. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result.conservativeResize(d_); + for (std::size_t l = fun_.amb_d(); l < d_; ++l) result(l) = 0; + return result; + } + + /** + * \brief Constructor of the embedding function. + * + * @param[in] function The function to be embedded in higher dimension. + * @param[in] d Embedding dimension. + */ + Embed_in_Rd(const Function_& function, std::size_t d) : fun_(function), d_(d) {} + + private: + Function_ fun_; + std::size_t d_; +}; + +/** + * \brief Static constructor of an embedding function. + * + * @param[in] function The function to be embedded in higher dimension. + * @param[in] d Embedding dimension. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <class Function_> +Embed_in_Rd<Function_> make_embedding(const Function_& function, std::size_t d) { + return Embed_in_Rd<Function_>(function, d); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h new file mode 100644 index 00000000..8911f990 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_Sm_in_Rd.h @@ -0,0 +1,110 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_SM_IN_RD_H_ +#define FUNCTIONS_FUNCTION_SM_IN_RD_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_Sm_in_Rd + * \brief A class for the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space. + */ +struct Function_Sm_in_Rd { + /** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd x = p; + for (std::size_t i = 0; i < d_; ++i) x(i) -= center_[i]; + Eigen::VectorXd result = Eigen::VectorXd::Zero(k_); + for (std::size_t i = 0; i < m_ + 1; ++i) result(0) += x(i) * x(i); + result(0) -= r_ * r_; + for (std::size_t j = 1; j < k_; ++j) result(j) = x(m_ + j); + return result; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const { return d_; }; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const { return k_; }; + + /** \brief Returns a point on the sphere. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); + result(0) += r_; + for (std::size_t i = 0; i < d_; ++i) result(i) += center_[i]; + return result; + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] d The ambient dimension of the sphere. + * @param[in] center The center of the sphere. + */ + Function_Sm_in_Rd(double r, std::size_t m, std::size_t d, Eigen::VectorXd center) + : m_(m), k_(d - m), d_(d), r_(r), center_(center) {} + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the d-dimensional Euclidean space centered at the origin. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] d The ambient dimension of the sphere. + */ + Function_Sm_in_Rd(double r, std::size_t m, std::size_t d) + : m_(m), k_(d - m), d_(d), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the (m+1)-dimensional Euclidean space. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + * @param[in] center The center of the sphere. + */ + Function_Sm_in_Rd(double r, std::size_t m, Eigen::VectorXd center) + : m_(m), k_(1), d_(m_ + 1), r_(r), center_(center) {} + + /** + * \brief Constructor of the function that defines an m-dimensional implicit sphere embedded + * in the (m+1)-dimensional Euclidean space centered at the origin. + * + * @param[in] r The radius of the sphere. + * @param[in] m The dimension of the sphere. + */ + Function_Sm_in_Rd(double r, std::size_t m) : m_(m), k_(1), d_(m_ + 1), r_(r), center_(Eigen::VectorXd::Zero(d_)) {} + + Function_Sm_in_Rd(const Function_Sm_in_Rd& rhs) : Function_Sm_in_Rd(rhs.r_, rhs.m_, rhs.d_, rhs.center_) {} + + private: + std::size_t m_, k_, d_; + double r_; + Eigen::VectorXd center_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h new file mode 100644 index 00000000..b29f0906 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_affine_plane_in_Rd.h @@ -0,0 +1,91 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ +#define FUNCTIONS_FUNCTION_AFFINE_PLANE_IN_RD_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_affine_plane_in_Rd + * \brief A class for the function that defines an m-dimensional implicit affine plane + * embedded in d-dimensional Euclidean space. + */ +struct Function_affine_plane_in_Rd { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = normal_matrix_.transpose() * (p - off_); + return result; + } + + /** \brief Returns the domain dimension. Same as the ambient dimension of the sphere. */ + std::size_t amb_d() const { return d_; }; + + /** \brief Returns the codomain dimension. Same as the codimension of the sphere. */ + std::size_t cod_d() const { return k_; }; + + /** \brief Returns a point on the affine plane. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = off_; + return result; + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit affine + * plane in the d-dimensional Euclidean space. + * + * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). + * @param[in] offset The offset vector of the affine plane. + * The dimension of the vector should be the ambient dimension of the manifold. + */ + Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix, const Eigen::VectorXd& offset) + : normal_matrix_(normal_matrix), d_(normal_matrix.rows()), k_(normal_matrix.cols()), m_(d_ - k_), off_(offset) { + normal_matrix_.colwise().normalize(); + } + + /** + * \brief Constructor of the function that defines an m-dimensional implicit affine + * plane in the d-dimensional Euclidean space that passes through origin. + * + * @param[in] normal_matrix A normal matrix of the affine plane. The number of rows should + * correspond to the ambient dimension, the number of columns should corespond to + * the size of the normal basis (codimension). + */ + Function_affine_plane_in_Rd(const Eigen::MatrixXd& normal_matrix) + : normal_matrix_(normal_matrix), + d_(normal_matrix.rows()), + k_(normal_matrix.cols()), + m_(d_ - k_), + off_(Eigen::VectorXd::Zero(d_)) { + normal_matrix_.colwise().normalize(); + } + + private: + Eigen::MatrixXd normal_matrix_; + std::size_t d_, k_, m_; + Eigen::VectorXd off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h new file mode 100644 index 00000000..620446da --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_chair_in_R3.h @@ -0,0 +1,80 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ +#define FUNCTIONS_FUNCTION_CHAIR_IN_R3_H_ + +#include <cstdlib> // for std::size_t +#include <cmath> // for std::pow + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_chair_in_R3 + * \brief A class that encodes the function, the zero-set of which is a so-called + * "chair" surface embedded in R^3. + */ +struct Function_chair_in_R3 { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = std::pow(x * x + y * y + z * z - a_ * k_ * k_, 2) - + b_ * ((z - k_) * (z - k_) - 2 * x * x) * ((z + k_) * (z + k_) - 2 * y * y); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return 3; } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return 1; } + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + double t1 = a_ - b_; + double discr = t1 * t1 - (1.0 - b_) * (a_ * a_ - b_); + double z0 = k_ * std::sqrt((t1 + std::sqrt(discr)) / (1 - b_)); + Eigen::Vector3d result(off_[0], off_[1], z0 + off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines the 'chair' surface + * embedded in R^3. + * + * @param[in] a A numerical parameter. + * @param[in] b A numerical parameter. + * @param[in] k A numerical parameter. + * @param[in] off Offset vector. + */ + Function_chair_in_R3(double a = 0.8, double b = 0.4, double k = 1.0, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : a_(a), b_(b), k_(k), off_(off) {} + + protected: + double a_, b_, k_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif + +// (x^2 + y^2 + z^2 - a*k^2)^2 - b*((z-k)^2 - 2*x^2)*((z+k)^2 - 2*y^2) +// sqrt(k/(1-b))*sqrt(a-b + sqrt((a-b)^2 - (1-b)*(a^2 - b)*k^2)) diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h new file mode 100644 index 00000000..f73c4280 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_iron_in_R3.h @@ -0,0 +1,69 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_IRON_IN_R3_H_ +#define FUNCTIONS_FUNCTION_IRON_IN_R3_H_ + +#include <cstdlib> // for std::size_t +#include <cmath> // for std::pow + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_iron_in_R3 + * \brief A class that encodes the function, the zero-set of which is a surface + * embedded in R^3 that ressembles an iron. + */ +struct Function_iron_in_R3 { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0), y = p(1), z = p(2); + Eigen::VectorXd result(cod_d()); + result(0) = -std::pow(x, 6) / 300. - std::pow(y, 6) / 300. - std::pow(z, 6) / 300. + x * y * y * z / 2.1 + y * y + + std::pow(z - 2, 4) - 1; + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return 3; }; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return 1; }; + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(std::pow(4500, 1. / 6), 0, 0); + return result; + } + + /** + * \brief Constructor of the function that defines a surface embedded in R^3 + * that ressembles an iron. + * + * @param[in] off Offset vector. + */ + Function_iron_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} + + private: + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h new file mode 100644 index 00000000..beb41e00 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_lemniscate_revolution_in_R3.h @@ -0,0 +1,85 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ +#define FUNCTIONS_FUNCTION_LEMNISCATE_REVOLUTION_IN_R3_H_ + +#include <cstdlib> // for std::size_t +#include <cmath> // for std::sqrt + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_lemniscate_revolution_in_R3 + * \brief A class that encodes the function, the zero-set of which is a surface of revolution + * around the x axis based on the lemniscate of Bernoulli embedded in R^3. + */ +struct Function_lemniscate_revolution_in_R3 { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; + Eigen::VectorXd result(cod_d()); + double x2 = x * x, y2 = y * y, z2 = z * z, a2 = a_ * a_; + double t1 = x2 + y2 + z2; + result(0) = t1 * t1 - 2 * a2 * (x2 - y2 - z2); + return result; + } + + /** \brief Returns the (ambient) domain dimension.*/ + std::size_t amb_d() const { return 3; }; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return 1; }; + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed2() for the other point. + */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(std::sqrt(2 * a_) + off_[0], off_[1], off_[2]); + return result; + } + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. + */ + Eigen::VectorXd seed2() const { + Eigen::Vector3d result(-std::sqrt(2 * a_) + off_[0], off_[1], off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines a surface of revolution + * around the x axis based on the lemniscate of Bernoulli embedded in R^3. + * + * @param[in] a A numerical parameter. + * @param[in] off Offset vector. + */ + Function_lemniscate_revolution_in_R3(double a = 1, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : a_(a), off_(off) {} + + private: + double a_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h new file mode 100644 index 00000000..11b379f3 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_moment_curve_in_Rd.h @@ -0,0 +1,79 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ +#define FUNCTIONS_FUNCTION_MOMENT_CURVE_IN_RD_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_moment_curve_in_Rd + * \brief A class for the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + */ +struct Function_moment_curve_in_Rd { + /** \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result(k_); + for (std::size_t i = 1; i < d_; ++i) result(i - 1) = p(i) - p(0) * p(i - 1); + return result; + } + + /** \brief Returns the domain (ambient) dimension.. */ + std::size_t amb_d() const { return d_; }; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return k_; }; + + /** \brief Returns a point on the moment curve. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = Eigen::VectorXd::Zero(d_); + return result; + } + + /** + * \brief Constructor of the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + * + * @param[in] r Numerical parameter. + * @param[in] d The ambient dimension. + */ + Function_moment_curve_in_Rd(double r, std::size_t d) : m_(1), k_(d - 1), d_(d), r_(r) {} + + /** + * \brief Constructor of the function that defines an implicit moment curve + * in the d-dimensional Euclidean space. + * + * @param[in] r Numerical parameter. + * @param[in] d The ambient dimension. + * @param[in] offset The offset of the moment curve. + */ + Function_moment_curve_in_Rd(double r, std::size_t d, Eigen::VectorXd& offset) + : m_(1), k_(d - 1), d_(d), r_(r), off_(offset) {} + + private: + std::size_t m_, k_, d_; + double r_; + Eigen::VectorXd off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h new file mode 100644 index 00000000..b54d3c74 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_torus_in_R3.h @@ -0,0 +1,71 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ +#define FUNCTIONS_FUNCTION_TORUS_IN_R3_H_ + +#include <cstdlib> // for std::size_t +#include <cmath> // for std::sqrt + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_torus_in_R3 + * \brief A class that encodes the function, the zero-set of which is a torus + * surface embedded in R^3. + */ +struct Function_torus_in_R3 { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = (z * z + (std::sqrt(x * x + y * y) - r_) * (std::sqrt(x * x + y * y) - r_) - R_ * R_); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return 3; }; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return 1; }; + + /** \brief Returns a point on the surface. */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(R_ + r_ + off_[0], off_[1], off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines a torus embedded in R^3. + * + * @param[in] R The outer radius of the torus. + * @param[in] r The inner radius of the torus. + * @param[in] off Offset vector. + */ + Function_torus_in_R3(double R = 1, double r = 0.5, Eigen::Vector3d off = Eigen::Vector3d::Zero()) + : R_(R), r_(r), off_(off) {} + + private: + double R_, r_; + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h new file mode 100644 index 00000000..df1f1eec --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Function_whitney_umbrella_in_R3.h @@ -0,0 +1,78 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ +#define FUNCTIONS_FUNCTION_WHITNEY_UMBRELLA_IN_R3_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Function_whitney_umbrella_in_R3 + * \brief A class that encodes the function, the zero-set of which is the Whitney umbrella + * surface embedded in R^3. + */ +struct Function_whitney_umbrella_in_R3 { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + double x = p(0) - off_[0], y = p(1) - off_[1], z = p(2) - off_[2]; + Eigen::VectorXd result(cod_d()); + result(0) = x * x - y * y * z; + return result; + } + + /** \brief Returns the (ambient) domain dimension.*/ + std::size_t amb_d() const { return 3; }; + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return 1; }; + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed2() for the other point. + */ + Eigen::VectorXd seed() const { + Eigen::Vector3d result(1 + off_[0], 1 + off_[1], 1 + off_[2]); + return result; + } + + /** \brief Returns a point on the surface. This seed point is only one of + * two necessary seed points for the manifold tracing algorithm. + * See the method seed() for the other point. + */ + Eigen::VectorXd seed2() const { + Eigen::Vector3d result(-1 + off_[0], -1 + off_[1], 1 + off_[2]); + return result; + } + + /** + * \brief Constructor of the function that defines the Whitney umbrella in R^3. + * + * @param[in] off Offset vector. + */ + Function_whitney_umbrella_in_R3(Eigen::Vector3d off = Eigen::Vector3d::Zero()) : off_(off) {} + + private: + Eigen::Vector3d off_; +}; + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h new file mode 100644 index 00000000..82e25bb9 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Linear_transformation.h @@ -0,0 +1,88 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_LINEAR_TRANSFORMATION_H_ +#define FUNCTIONS_LINEAR_TRANSFORMATION_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \class Linear_transformation + * \brief Transforms the zero-set of the function by a given linear transformation. + * The underlying function corresponds to f(M*x), where M is the transformation matrix. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + */ +template <class Function_> +struct Linear_transformation { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = fun_(matrix_.householderQr().solve(p)); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return fun_.amb_d(); } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return fun_.cod_d(); } + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result = matrix_ * result; + return result; + } + + /** + * \brief Constructor of a linearly transformed function. + * + * @param[in] function The function to be linearly transformed. + * @param[in] matrix The transformation matrix. Its dimension should be d*d, + * where d is the domain (ambient) dimension of 'function'. + */ + Linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) : fun_(function), matrix_(matrix) {} + + private: + Function_ fun_; + Eigen::MatrixXd matrix_; +}; + +/** + * \brief Static constructor of a linearly transformed function. + * + * @param[in] function The function to be linearly transformed. + * @param[in] matrix The transformation matrix. Its dimension should be d*d, + * where d is the domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <class Function_> +Linear_transformation<Function_> make_linear_transformation(const Function_& function, const Eigen::MatrixXd& matrix) { + return Linear_transformation<Function_>(function, matrix); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h new file mode 100644 index 00000000..fdf07f27 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Negation.h @@ -0,0 +1,84 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_NEGATION_H_ +#define FUNCTIONS_NEGATION_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + *\class Negation + * \brief Constructs the "minus" function. The zero-set is the same, but + * the values at other points are the negative of their original value. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + */ +template <class Function_> +struct Negation { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = -fun_(p); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return fun_.amb_d(); } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return fun_.cod_d(); } + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + return result; + } + + /** + * \brief Constructor of the negative function. + * + * @param[in] function The function to be negated. + */ + Negation(const Function_& function) : fun_(function) {} + + private: + Function_ fun_; +}; + +/** + * \brief Static constructor of the negative function. + * + * @param[in] function The function to be translated. + * domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <class Function_> +Negation<Function_> negation(const Function_& function) { + return Negation<Function_>(function); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h new file mode 100644 index 00000000..22071d6d --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/PL_approximation.h @@ -0,0 +1,111 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_PL_APPROXIMATION_H_ +#define FUNCTIONS_PL_APPROXIMATION_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class PL_approximation + * \brief Constructs a piecewise-linear approximation of a function induced by + * an ambient triangulation. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * \tparam Triangulation The triangulation template parameter. Should be a model of + * the concept TriangulationForManifoldTracing. + */ +template <class Function_, class Triangulation_> +struct PL_approximation { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + std::size_t cod_d = this->cod_d(); + std::size_t amb_d = this->amb_d(); + auto s = tr_.locate_point(p); + Eigen::MatrixXd matrix(cod_d, s.dimension() + 1); + Eigen::MatrixXd vertex_matrix(amb_d + 1, s.dimension() + 1); + for (std::size_t i = 0; i < s.dimension() + 1; ++i) vertex_matrix(0, i) = 1; + std::size_t j = 0; + for (auto v : s.vertex_range()) { + Eigen::VectorXd pt_v = tr_.cartesian_coordinates(v); + Eigen::VectorXd fun_v = fun_(pt_v); + for (std::size_t i = 1; i < amb_d + 1; ++i) vertex_matrix(i, j) = pt_v(i - 1); + for (std::size_t i = 0; i < cod_d; ++i) matrix(i, j) = fun_v(i); + j++; + } + assert(j == s.dimension() + 1); + Eigen::VectorXd z(amb_d + 1); + z(0) = 1; + for (std::size_t i = 1; i < amb_d + 1; ++i) z(i) = p(i - 1); + Eigen::VectorXd lambda = vertex_matrix.colPivHouseholderQr().solve(z); + Eigen::VectorXd result = matrix * lambda; + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return fun_.amb_d(); } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return fun_.cod_d(); } + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + // TODO: not finished. Should use an oracle. + return Eigen::VectorXd(amb_d()); + } + + /** + * \brief Constructor of the piecewise-linear approximation of a function + * induced by an ambient triangulation. + * + * @param[in] function The function. + * @param[in] triangulation The ambient triangulation. + */ + PL_approximation(const Function_& function, const Triangulation_& triangulation) + : fun_(function), tr_(triangulation) {} + + private: + Function_ fun_; + Triangulation_ tr_; +}; + +/** + * \brief Static constructor of the piecewise-linear approximation of a function + * induced by an ambient triangulation. + * + * @param[in] function The function. + * @param[in] triangulation The ambient triangulation. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <class Function_, class Triangulation_> +PL_approximation<Function_, Triangulation_> make_pl_approximation(const Function_& function, + const Triangulation_& triangulation) { + return PL_approximation<Function_, Triangulation_>(function, triangulation); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h new file mode 100644 index 00000000..cbe65abe --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/Translate.h @@ -0,0 +1,89 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_TRANSLATE_H_ +#define FUNCTIONS_TRANSLATE_H_ + +#include <cstdlib> // for std::size_t + +#include <Eigen/Dense> + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** + * \class Translate + * \brief Translates the zero-set of the function by a vector. + * The underlying function corresponds to f(x-off), where off is the offset vector. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + */ +template <class Function_> +struct Translate { + /** + * \brief Value of the function at a specified point. + * @param[in] p The input point. The dimension needs to coincide with the ambient dimension. + */ + Eigen::VectorXd operator()(const Eigen::VectorXd& p) const { + Eigen::VectorXd result = fun_(p - off_); + return result; + } + + /** \brief Returns the domain (ambient) dimension. */ + std::size_t amb_d() const { return fun_.amb_d(); } + + /** \brief Returns the codomain dimension. */ + std::size_t cod_d() const { return fun_.cod_d(); } + + /** \brief Returns a point on the zero-set. */ + Eigen::VectorXd seed() const { + Eigen::VectorXd result = fun_.seed(); + result += off_; + return result; + } + + /** + * \brief Constructor of the translated function. + * + * @param[in] function The function to be translated. + * @param[in] off The offset vector. The dimension should correspond to the + * domain (ambient) dimension of 'function'. + */ + Translate(const Function_& function, const Eigen::VectorXd& off) : fun_(function), off_(off) {} + + private: + Function_ fun_; + Eigen::VectorXd off_; +}; + +/** + * \brief Static constructor of a translated function. + * + * @param[in] function The function to be translated. + * @param[in] off The offset vector. The dimension should correspond to the + * domain (ambient) dimension of 'function'. + * + * \tparam Function_ The function template parameter. Should be a model of + * the concept FunctionForImplicitManifold. + * + * \ingroup coxeter_triangulation + */ +template <class Function_> +Translate<Function_> translate(const Function_& function, Eigen::VectorXd off) { + return Translate<Function_>(function, off); +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif diff --git a/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h new file mode 100644 index 00000000..6a896e94 --- /dev/null +++ b/src/Coxeter_triangulation/include/gudhi/Functions/random_orthogonal_matrix.h @@ -0,0 +1,72 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Siargey Kachanovich + * + * Copyright (C) 2019 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ +#define FUNCTIONS_RANDOM_ORTHOGONAL_MATRIX_H_ + +#include <cstdlib> // for std::size_t +#include <cmath> // for std::cos, std::sin +#include <random> // for std::uniform_real_distribution, std::random_device + +#include <Eigen/Dense> +#include <Eigen/Sparse> +#include <Eigen/SVD> + +#include <CGAL/Epick_d.h> +#include <CGAL/point_generators_d.h> + +#include <boost/math/constants/constants.hpp> // for PI value + +namespace Gudhi { + +namespace coxeter_triangulation { + +/** \brief Generates a uniform random orthogonal matrix using the "subgroup algorithm" by + * Diaconis & Shashahani. + * \details Taken from https://en.wikipedia.org/wiki/Rotation_matrix#Uniform_random_rotation_matrices. + * The idea: take a random rotation matrix of dimension d-1, embed it + * as a d*d matrix M with the last column (0,...,0,1). + * Pick a random vector v on a sphere S^d. rotate the matrix M so that its last column is v. + * The determinant of the matrix can be either 1 or -1 + */ +// Note: the householderQR operation at the end seems to take a lot of time at compilation. +// The CGAL headers are another source of long compilation time. +Eigen::MatrixXd random_orthogonal_matrix(std::size_t d) { + typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> Kernel; + typedef typename Kernel::Point_d Point_d; + if (d == 1) return Eigen::VectorXd::Constant(1, 1.0); + if (d == 2) { + // 0. < alpha < 2 Pi + std::uniform_real_distribution<double> unif(0., 2 * boost::math::constants::pi<double>()); + std::random_device rand_dev; + std::mt19937 rand_engine(rand_dev()); + double alpha = unif(rand_engine); + + Eigen::Matrix2d rot; + rot << std::cos(alpha), -std::sin(alpha), std::sin(alpha), cos(alpha); + return rot; + } + Eigen::MatrixXd low_dim_rot = random_orthogonal_matrix(d - 1); + Eigen::MatrixXd rot(d, d); + Point_d v = *CGAL::Random_points_on_sphere_d<Point_d>(d, 1); + for (std::size_t i = 0; i < d; ++i) rot(i, 0) = v[i]; + for (std::size_t i = 0; i < d - 1; ++i) + for (std::size_t j = 1; j < d - 1; ++j) rot(i, j) = low_dim_rot(i, j - 1); + for (std::size_t j = 1; j < d; ++j) rot(d - 1, j) = 0; + rot = rot.householderQr() + .householderQ(); // a way to do Gram-Schmidt, see https://forum.kde.org/viewtopic.php?f=74&t=118568#p297246 + return rot; +} + +} // namespace coxeter_triangulation + +} // namespace Gudhi + +#endif |