Loading...
Searching...
No Matches
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
21namespace Gudhi {
22
23namespace coxeter_triangulation {
24
25/* Get the domain dimension of the tuple of functions.
26 */
27template <std::size_t I = 0, typename... T>
28inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_amb_d(const std::tuple<T...>& tuple) {
29 return 0;
30}
31
32template <std::size_t I = 0, typename... T>
33inline 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 */
39template <std::size_t I = 0, typename... T>
40inline typename std::enable_if<I == sizeof...(T), std::size_t>::type get_cod_d(const std::tuple<T...>& tuple) {
41 return 0;
42}
43
44template <std::size_t I = 0, typename... T>
45inline 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 */
51template <std::size_t I = 0, typename... T>
52inline 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
55template <std::size_t I = 0, typename... T>
56inline 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 */
67template <std::size_t I = 0, typename... T>
68inline 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
73template <std::size_t I = 0, typename... T>
74inline 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
96template <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
148template <typename... Functions>
149Cartesian_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
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