mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-22 12:37:35 +08:00
Misc improvements
This commit is contained in:
parent
4cdf3fe427
commit
703c526355
@ -42,14 +42,14 @@ struct numeric_list<T, n, nn...> { constexpr static std::size_t count = sizeof..
|
|||||||
* typename gen_numeric_list_repeated<int, 0, 5>::type numeric_list<int, 0,0,0,0,0>
|
* typename gen_numeric_list_repeated<int, 0, 5>::type numeric_list<int, 0,0,0,0,0>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list : gen_numeric_list<T, n-1, start, start + n-1, ii...> {};
|
template<typename T, std::size_t n, T... ii> struct gen_numeric_list : gen_numeric_list<T, n-1, n-1, ii...> {};
|
||||||
template<typename T, T start, T... ii> struct gen_numeric_list<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; };
|
template<typename T, T... ii> struct gen_numeric_list<T, 0, ii...> { typedef numeric_list<T, ii...> type; };
|
||||||
|
|
||||||
template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, start, ii..., start + n-1> {};
|
template<typename T, std::size_t n, T... ii> struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, ii..., n-1> {};
|
||||||
template<typename T, T start, T... ii> struct gen_numeric_list_reversed<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; };
|
template<typename T, T... ii> struct gen_numeric_list_reversed<T, 0, ii...> { typedef numeric_list<T, ii...> type; };
|
||||||
|
|
||||||
template<typename T, std::size_t n, T a, T b, T start = 0, T... ii> struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, start, (start + n-1) == a ? b : ((start + n-1) == b ? a : (start + n-1)), ii...> {};
|
template<typename T, std::size_t n, T a, T b, T... ii> struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, (n-1) == a ? b : ((n-1) == b ? a : (n-1)), ii...> {};
|
||||||
template<typename T, T a, T b, T start, T... ii> struct gen_numeric_list_swapped_pair<T, 0, a, b, start, ii...> { typedef numeric_list<T, ii...> type; };
|
template<typename T, T a, T b, T... ii> struct gen_numeric_list_swapped_pair<T, 0, a, b, ii...> { typedef numeric_list<T, ii...> type; };
|
||||||
|
|
||||||
template<typename T, std::size_t n, T V, T... nn> struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n-1, V, V, nn...> {};
|
template<typename T, std::size_t n, T V, T... nn> struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n-1, V, V, nn...> {};
|
||||||
template<typename T, T V, T... nn> struct gen_numeric_list_repeated<T, 0, V, nn...> { typedef numeric_list<T, nn...> type; };
|
template<typename T, T V, T... nn> struct gen_numeric_list_repeated<T, 0, V, nn...> { typedef numeric_list<T, nn...> type; };
|
||||||
@ -370,6 +370,14 @@ constexpr inline auto array_prod(std::array<T, N> arr) -> decltype(array_reduce<
|
|||||||
return array_reduce<product_op, T, N>(arr);
|
return array_reduce<product_op, T, N>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename t>
|
||||||
|
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) {
|
||||||
|
eigen_assert(a.size() > 0);
|
||||||
|
t prod = 1;
|
||||||
|
for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; }
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
/* zip an array */
|
/* zip an array */
|
||||||
|
|
||||||
template<typename Op, typename A, typename B, std::size_t N, int... n>
|
template<typename Op, typename A, typename B, std::size_t N, int... n>
|
||||||
|
@ -48,15 +48,13 @@ namespace internal {
|
|||||||
* - libstdc++ from version 4.7 onwards has it nevertheless,
|
* - libstdc++ from version 4.7 onwards has it nevertheless,
|
||||||
* so use that
|
* so use that
|
||||||
* - libstdc++ older versions: use _M_instance directly
|
* - libstdc++ older versions: use _M_instance directly
|
||||||
* - libc++ from version 3.4 onwards has it IF compiled with
|
* - libc++ all versions so far: use __elems_ directly
|
||||||
* -std=c++1y
|
|
||||||
* - libc++ older versions or -std=c++11: use __elems_ directly
|
|
||||||
* - all other libs: use std::get to be portable, but
|
* - all other libs: use std::get to be portable, but
|
||||||
* this may not be constexpr
|
* this may not be constexpr
|
||||||
*/
|
*/
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
||||||
#define STD_GET_ARR_HACK a._M_instance[I]
|
#define STD_GET_ARR_HACK a._M_instance[I]
|
||||||
#elif defined(_LIBCPP_VERSION) && (!defined(_LIBCPP_STD_VER) || _LIBCPP_STD_VER <= 11)
|
#elif defined(_LIBCPP_VERSION)
|
||||||
#define STD_GET_ARR_HACK a.__elems_[I]
|
#define STD_GET_ARR_HACK a.__elems_[I]
|
||||||
#else
|
#else
|
||||||
#define STD_GET_ARR_HACK std::template get<I, T, N>(a)
|
#define STD_GET_ARR_HACK std::template get<I, T, N>(a)
|
||||||
@ -70,14 +68,14 @@ template<std::size_t I, class T> constexpr inline T& array_get(std::vector
|
|||||||
template<std::size_t I, class T> constexpr inline T&& array_get(std::vector<T>&& a) { return a[I]; }
|
template<std::size_t I, class T> constexpr inline T&& array_get(std::vector<T>&& a) { return a[I]; }
|
||||||
template<std::size_t I, class T> constexpr inline T const& array_get(std::vector<T> const& a) { return a[I]; }
|
template<std::size_t I, class T> constexpr inline T const& array_get(std::vector<T> const& a) { return a[I]; }
|
||||||
|
|
||||||
|
|
||||||
#undef STD_GET_ARR_HACK
|
#undef STD_GET_ARR_HACK
|
||||||
|
|
||||||
template <typename T> struct array_size;
|
template <typename T> struct array_size;
|
||||||
template<class T, std::size_t N> struct array_size<std::array<T,N> > {
|
template<class T, std::size_t N> struct array_size<const std::array<T,N> > {
|
||||||
static const size_t value = N;
|
static const size_t value = N;
|
||||||
};
|
};
|
||||||
template<class T, std::size_t N> struct array_size<const std::array<T,N> > {
|
template <typename T> struct array_size;
|
||||||
|
template<class T, std::size_t N> struct array_size<std::array<T,N> > {
|
||||||
static const size_t value = N;
|
static const size_t value = N;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ template <typename T, size_t n> class array {
|
|||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE array() { }
|
EIGEN_STRONG_INLINE array() { }
|
||||||
EIGEN_DEVICE_FUNC
|
explicit EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE array(const T& v) {
|
EIGEN_STRONG_INLINE array(const T& v) {
|
||||||
EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||||
values[0] = v;
|
values[0] = v;
|
||||||
@ -106,6 +106,7 @@ template <typename T, size_t n> class array {
|
|||||||
|
|
||||||
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
|
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
|
||||||
array(std::initializer_list<T> l) {
|
array(std::initializer_list<T> l) {
|
||||||
|
eigen_assert(l.size() == n);
|
||||||
std::copy(l.begin(), l.end(), values);
|
std::copy(l.begin(), l.end(), values);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -211,6 +212,29 @@ template<typename T, T V> struct gen_numeric_list_repeated<T, 8, V> {
|
|||||||
|
|
||||||
template <std::size_t index, class NList> struct get;
|
template <std::size_t index, class NList> struct get;
|
||||||
|
|
||||||
|
template <std::size_t i>
|
||||||
|
struct get<i, empty_list>
|
||||||
|
{
|
||||||
|
get() { eigen_assert(false && "index overflow"); }
|
||||||
|
typedef void type;
|
||||||
|
static const char value = '\0';
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t i, class Head>
|
||||||
|
struct get<i, type_list<Head, empty_list> >
|
||||||
|
{
|
||||||
|
get() { eigen_assert(false && "index overflow"); }
|
||||||
|
typedef void type;
|
||||||
|
static const char value = '\0';
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Head>
|
||||||
|
struct get<0, type_list<Head, empty_list> >
|
||||||
|
{
|
||||||
|
typedef typename Head::type type;
|
||||||
|
static const type value = Head::value;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Head, class Tail>
|
template <class Head, class Tail>
|
||||||
struct get<0, type_list<Head, Tail> >
|
struct get<0, type_list<Head, Tail> >
|
||||||
{
|
{
|
||||||
@ -221,10 +245,11 @@ struct get<0, type_list<Head, Tail> >
|
|||||||
template <std::size_t i, class Head, class Tail>
|
template <std::size_t i, class Head, class Tail>
|
||||||
struct get<i, type_list<Head, Tail> >
|
struct get<i, type_list<Head, Tail> >
|
||||||
{
|
{
|
||||||
typedef typename get<i-1, Tail>::type type;
|
typedef typename Tail::HeadType::type type;
|
||||||
static const type value = get<i-1, Tail>::value;
|
static const type value = get<i-1, Tail>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class NList> struct arg_prod {
|
template <class NList> struct arg_prod {
|
||||||
static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod<typename NList::TailType>::value;
|
static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod<typename NList::TailType>::value;
|
||||||
};
|
};
|
||||||
@ -354,24 +379,52 @@ struct greater_equal_zero_op {
|
|||||||
|
|
||||||
|
|
||||||
template<typename Reducer, typename Op, typename A, std::size_t N>
|
template<typename Reducer, typename Op, typename A, std::size_t N>
|
||||||
inline bool array_apply_and_reduce(const array<A, N>& a) {
|
struct ArrayApplyAndReduce {
|
||||||
EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
static inline bool run(const array<A, N>& a) {
|
||||||
|
EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
||||||
bool result = Reducer::run(Op::run(a[0]), Op::run(a[1]));
|
bool result = Reducer::run(Op::run(a[0]), Op::run(a[1]));
|
||||||
for (size_t i = 2; i < N; ++i) {
|
for (size_t i = 2; i < N; ++i) {
|
||||||
result = Reducer::run(result, Op::run(a[i]));
|
result = Reducer::run(result, Op::run(a[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Reducer, typename Op, typename A>
|
||||||
|
struct ArrayApplyAndReduce<Reducer, Op, A, 1> {
|
||||||
|
static inline bool run(const array<A, 1>& a) {
|
||||||
|
return Op::run(a[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Reducer, typename Op, typename A, std::size_t N>
|
||||||
|
inline bool array_apply_and_reduce(const array<A, N>& a) {
|
||||||
|
return ArrayApplyAndReduce<Reducer, Op, A, N>::run(a);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
|
template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
|
||||||
inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& b) {
|
struct ArrayZipAndReduce {
|
||||||
EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
static inline bool run(const array<A, N>& a, const array<B, N>& b) {
|
||||||
|
EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE);
|
||||||
bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1]));
|
bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1]));
|
||||||
for (size_t i = 2; i < N; ++i) {
|
for (size_t i = 2; i < N; ++i) {
|
||||||
result = Reducer::run(result, Op::run(a[i], b[i]));
|
result = Reducer::run(result, Op::run(a[i], b[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Reducer, typename Op, typename A, typename B>
|
||||||
|
struct ArrayZipAndReduce<Reducer, Op, A, B, 1> {
|
||||||
|
static inline bool run(const array<A, 1>& a, const array<B, 1>& b) {
|
||||||
|
return Op::run(a[0], b[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
|
||||||
|
inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& b) {
|
||||||
|
return ArrayZipAndReduce<Reducer, Op, A, B, N>::run(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user