Cartesian_product.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 FUNCTIONS_CARTESIAN_PRODUCT_H_
12 #define FUNCTIONS_CARTESIAN_PRODUCT_H_
13 
14 #include <cstdlib>
15 #include <tuple>
16 #include <type_traits> // for std::enable_if
17 #include <cstdlib> // for std::size_t
18 
19 #include <Eigen/Dense>
20 
21 namespace Gudhi {
22 
23 namespace coxeter_triangulation {
24 
25 /* Get the domain dimension of the tuple of functions.
26  */
27 template <std::size_t I = 0, typename... T>
28 inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_amb_d(const std::tuple<T...>& tuple) {
29  return 0;
30 }
31 
32 template <std::size_t I = 0, typename... T>
33 inline typename std::enable_if<I != sizeof...(T), std::size_t>::type get_amb_d(const std::tuple<T...>& tuple) {
34  return std::get<I>(tuple).amb_d() + get_amb_d<I + 1, T...>(tuple);
35 }
36 
37 /* Get the codomain dimension of the tuple of functions.
38  */
39 template <std::size_t I = 0, typename... T>
40 inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_cod_d(const std::tuple<T...>& tuple) {
41  return 0;
42 }
43 
44 template <std::size_t I = 0, typename... T>
45 inline typename std::enable_if<I != sizeof...(T), std::size_t>::type get_cod_d(const std::tuple<T...>& tuple) {
46  return std::get<I>(tuple).cod_d() + get_cod_d<I + 1, T...>(tuple);
47 }
48 
49 /* Get the seed of the tuple of functions.
50  */
51 template <std::size_t I = 0, typename... T>
52 inline typename std::enable_if<I == sizeof...(T), void>::type get_seed(const std::tuple<T...>& tuple,
53  Eigen::VectorXd& point, std::size_t i = 0) {}
54 
55 template <std::size_t I = 0, typename... T>
56 inline typename std::enable_if<I != sizeof...(T), void>::type get_seed(const std::tuple<T...>& tuple,
57  Eigen::VectorXd& point, std::size_t i = 0) {
58  const auto& f = std::get<I>(tuple);
59  std::size_t n = f.amb_d();
60  Eigen::VectorXd seed = f.seed();
61  for (std::size_t j = 0; j < n; ++j) point(i + j) = seed(j);
62  get_seed<I + 1, T...>(tuple, point, i + n);
63 }
64 
65 /* Get the seed of the tuple of functions.
66  */
67 template <std::size_t I = 0, typename... T>
68 inline typename std::enable_if<I == sizeof...(T), void>::type get_value(const std::tuple<T...>& tuple,
69  const Eigen::VectorXd& x,
70  Eigen::VectorXd& point, std::size_t i = 0,
71  std::size_t j = 0) {}
72 
73 template <std::size_t I = 0, typename... T>
74 inline typename std::enable_if<I != sizeof...(T), void>::type get_value(const std::tuple<T...>& tuple,
75  const Eigen::VectorXd& x,
76  Eigen::VectorXd& point, std::size_t i = 0,
77  std::size_t j = 0) {
78  const auto& f = std::get<I>(tuple);
79  std::size_t n = f.amb_d();
80  std::size_t k = f.cod_d();
81  Eigen::VectorXd x_i(n);
82  for (std::size_t l = 0; l < n; ++l) x_i(l) = x(i + l);
83  Eigen::VectorXd res = f(x_i);
84  for (std::size_t l = 0; l < k; ++l) point(j + l) = res(l);
85  get_value<I + 1, T...>(tuple, x, point, i + n, j + k);
86 }
87 
96 template <class... Functions>
102  Eigen::VectorXd operator()(const Eigen::VectorXd& p) const {
103  Eigen::VectorXd result(cod_d_);
104  get_value(function_tuple_, p, result, 0, 0);
105  return result;
106  }
107 
109  std::size_t amb_d() const { return amb_d_; }
110 
112  std::size_t cod_d() const { return cod_d_; }
113 
115  Eigen::VectorXd seed() const {
116  Eigen::VectorXd result(amb_d_);
117  get_seed(function_tuple_, result, 0);
118  return result;
119  }
120 
127  Cartesian_product(const Functions&... functions) : function_tuple_(std::make_tuple(functions...)) {
128  amb_d_ = get_amb_d(function_tuple_);
129  cod_d_ = get_cod_d(function_tuple_);
130  }
131 
132  private:
133  std::tuple<Functions...> function_tuple_;
134  std::size_t amb_d_, cod_d_;
135 };
136 
148 template <typename... Functions>
149 Cartesian_product<Functions...> make_product_function(const Functions&... functions) {
150  return Cartesian_product<Functions...>(functions...);
151 }
152 
153 } // namespace coxeter_triangulation
154 
155 } // namespace Gudhi
156 
157 #endif
Cartesian_product< Functions... > make_product_function(const Functions &... functions)
Static constructor of a Cartesian product function.
Definition: Cartesian_product.h:149
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
Constructs the function the zero-set of which is the Cartesian product of the zero-sets of some given...
Definition: Cartesian_product.h:97
std::size_t cod_d() const
Returns the codomain dimension.
Definition: Cartesian_product.h:112
std::size_t amb_d() const
Returns the domain (ambient) dimension.
Definition: Cartesian_product.h:109
Eigen::VectorXd seed() const
Returns a point on the zero-set.
Definition: Cartesian_product.h:115
Eigen::VectorXd operator()(const Eigen::VectorXd &p) const
Value of the function at a specified point.
Definition: Cartesian_product.h:102
Cartesian_product(const Functions &... functions)
Constructor of the Cartesian product function.
Definition: Cartesian_product.h:127