Himalaya
Sum.hpp
Go to the documentation of this file.
1 // ====================================================================
2 // This file is part of Himalaya.
3 //
4 // Himalaya is licenced under the GNU General Public License (GNU GPL)
5 // version 3.
6 // ====================================================================
7 
8 #pragma once
9 
10 /**
11  * @file Sum.hpp
12  *
13  * @brief Contains the definition of the \a SUM macro.
14  *
15  * Usage example of the \a SUM macro:
16  *
17  * Calculate \f$\sum_{n=1}^{10} n^2\f$
18  *
19  * @code{.cpp}
20 const double s = SUM(n,1,10,n*n);
21  @endcode
22  */
23 
24 #include <type_traits>
25 #include <cstddef>
26 #include <Eigen/Core>
27 
28 namespace himalaya {
29 namespace mh2_fo {
30 
31 #define SUM(...) (get_sum(__VA_ARGS__)(__VA_ARGS__))
32 
33 #define get_sum(...) get_sum_macro(__VA_ARGS__, sum_user_t, sum_ptrdiff_t,)
34 
35 #define get_sum_macro(_1, _2, _3, _4, _5, name, ...) name
36 
37 #define sum_ptrdiff_t(idx, ini, fin, expr) \
38  sum<std::ptrdiff_t>((ini), (fin), [&](std::ptrdiff_t (idx)) { return (expr); })
39 
40 #define sum_user_t(type, idx, ini, fin, expr) \
41  sum<type>((ini), (fin), [&](type (idx)) { return (expr); })
42 
43 template<typename T>
45 {
46  static constexpr auto value =
47  std::is_base_of<Eigen::EigenBase<T>, T>::value;
48 };
49 
50 template<typename Idx, typename Function, bool isEigenType>
52  static auto eval(Idx i, Function f) -> decltype(f(i)) {
53  return f(i);
54  }
55 };
56 
57 template<typename Idx, typename Function>
58 struct EvalEigenXprImpl<Idx, Function, true> {
59  static auto eval(Idx i, Function f) ->
60  typename std::remove_reference<decltype(f(i).eval())>::type
61  {
62  return f(i).eval();
63  }
64 };
65 
66 template<typename Idx, typename Function>
67 auto EvalEigenXpr(Idx i, Function f) ->
68  decltype(
69  EvalEigenXprImpl<Idx, Function, is_eigen_type<decltype(f(i))>::value>::
70  eval(i, f))
71 {
72  return
74  eval(i, f);
75 }
76 
77 template<typename T, bool isEigenType>
78 struct create_zero {
79  static const T zero() {
80  return T();
81  }
82 };
83 
84 template<typename T>
85 struct create_zero<T, true> {
86  static const T zero() {
87  T z;
88  z.setZero();
89  return z;
90  }
91 };
92 
93 template<class Idx, class Function>
94 auto sum(Idx ini, Idx fin, Function f) -> decltype(EvalEigenXpr<Idx>(ini, f))
95 {
96  using Evaled = decltype(EvalEigenXpr<Idx>(ini, f));
97  using Acc = typename std::remove_cv<Evaled>::type;
99  for (Idx i = ini; i <= fin; i++) s += f(i);
100  return s;
101 }
102 
103 } // namespace mh2_fo
104 } // namespace himalaya
auto sum(Idx ini, Idx fin, Function f) -> decltype(EvalEigenXpr< Idx >(ini, f))
Definition: Sum.hpp:94
Definition: H3.cpp:14
static auto eval(Idx i, Function f) -> decltype(f(i))
Definition: Sum.hpp:52
static auto eval(Idx i, Function f) -> typename std::remove_reference< decltype(f(i).eval())>::type
Definition: Sum.hpp:59
static constexpr auto value
Definition: Sum.hpp:46
auto EvalEigenXpr(Idx i, Function f) -> decltype(EvalEigenXprImpl< Idx, Function, is_eigen_type< decltype(f(i))>::value >::eval(i, f))
Definition: Sum.hpp:67
static const T zero()
Definition: Sum.hpp:79