16 #ifndef OPENKALMAN_EIGEN_TRAITS_FUNCTORS_REDUX_HPP 17 #define OPENKALMAN_EIGEN_TRAITS_FUNCTORS_REDUX_HPP 19 #include <type_traits> 25 template<
typename MemberOp, std::
size_t direction>
28 template<
typename C,
typename Factor,
typename Dim>
29 static constexpr
auto get_constant(
const C&,
const Factor& factor,
const Dim& dim)
31 return std::monostate{};
34 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
35 static constexpr
auto get_constant_diagonal(
const C&,
const Factor& factor,
const Dim& dim)
37 return std::monostate{};
42 #ifndef __cpp_concepts 45 template<
typename C,
typename =
void>
49 struct const_is_zero<C,
std::enable_if_t<values::to_value_type(C{}) == 0>> : std::true_type {};
58 #if EIGEN_VERSION_AT_LEAST(3,4,0) 59 template<
int p,
typename ResultType,
typename Scalar, std::
size_t direction>
60 struct ReduxTraits<Eigen::internal::member_lpnorm<p, ResultType, Scalar>, direction>
62 template<int p, typename ResultType, std::size_t direction>
63 struct
ReduxTraits<Eigen::internal::member_lpnorm<p, ResultType>, direction>
71 constexpr Scalar operator()(X x, std::size_t dim)
const 74 if constexpr (p == 1)
return static_cast<Scalar
>(dim) * abs_x;
75 else if constexpr (p == 2)
return values::sqrt(static_cast<Scalar>(dim)) * abs_x;
76 else return values::pow(static_cast<Scalar>(dim), static_cast<Scalar>(1)/p) * abs_x;
84 constexpr Scalar operator()(X x)
const {
return values::abs(x); }
88 template<
bool diag,
bool at_least_square,
typename C,
typename Factor,
typename Dim>
89 static constexpr
auto get_constant_impl(
const C& c,
const Factor& factor,
const Dim& dim)
94 if constexpr (std::numeric_limits<ResultType>::has_infinity)
return std::numeric_limits<ResultType>::infinity();
95 else throw std::domain_error {
"Domain error in lpnorm<0>: result is infinity"};
105 else if constexpr (not at_least_square)
107 return std::monostate{};
109 else if constexpr (p == Eigen::Infinity)
113 else if constexpr (diag)
125 template<
typename C,
typename Factor,
typename Dim>
126 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
128 return get_constant_impl<false, true>(c, factor, dim);
132 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
133 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
135 return get_constant_impl<true, at_least_square>(c, factor, dim);
140 #if EIGEN_VERSION_AT_LEAST(3,4,0) 141 template<
typename ResultType,
typename Scalar, std::
size_t direction>
142 struct ReduxTraits<Eigen::internal::member_stableNorm<ResultType, Scalar>, direction>
143 :
ReduxTraits<Eigen::internal::member_lpnorm<2, ResultType, Scalar>, direction> {};
145 template<
typename ResultType, std::
size_t direction>
146 struct ReduxTraits<Eigen::internal::member_stableNorm<ResultType>, direction>
147 :
ReduxTraits<Eigen::internal::member_lpnorm<2, ResultType>, direction> {};
151 #if EIGEN_VERSION_AT_LEAST(3,4,0) 152 template<
typename ResultType,
typename Scalar, std::
size_t direction>
153 struct ReduxTraits<Eigen::internal::member_hypotNorm<ResultType, Scalar>, direction>
154 :
ReduxTraits<Eigen::internal::member_lpnorm<2, ResultType, Scalar>, direction> {};
156 template<
typename ResultType, std::
size_t direction>
157 struct ReduxTraits<Eigen::internal::member_hypotNorm<ResultType>, direction>
158 :
ReduxTraits<Eigen::internal::member_lpnorm<2, ResultType>, direction> {};
162 # if not EIGEN_VERSION_AT_LEAST(3,4,0) 163 template<
typename...Args, std::size_t direction>
164 struct ReduxTraits<Eigen::internal::member_squaredNorm<Args...>, direction>
168 template<
typename Scalar>
169 constexpr Scalar operator()(Scalar x, std::size_t dim)
const 171 if constexpr (values::complex<Scalar>)
175 if constexpr (constant_diagonal_matrix<XprType>)
return r * r + i * i;
176 else return dim * (r * r + i * i);
178 else return dim * x * x;
183 template<
typename C,
typename Factor,
typename Dim>
184 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
186 #ifdef __cpp_concepts 197 template<
bool at_least_square,
typename C,
typename Factor>
198 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim&)
200 #ifdef __cpp_concepts 206 else if constexpr (at_least_square)
209 return std::monostate{};
214 template<
typename...Args, std::size_t direction>
215 struct ReduxTraits<Eigen::internal::member_norm<Args...>, direction>
219 template<
typename Scalar>
220 constexpr Scalar operator()(Scalar x, std::size_t dim)
const 222 if constexpr (values::complex<Scalar>)
226 if constexpr (constant_diagonal_matrix<XprType>)
return r * r + i * i;
237 template<
typename XprType,
typename Factor,
typename Dim>
238 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
240 #ifdef __cpp_concepts 251 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
252 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
254 if constexpr (at_least_square)
257 return std::monostate{};
262 template<
typename...Args, std::size_t direction>
263 struct ReduxTraits<Eigen::internal::member_mean<Args...>, direction>
265 template<
typename C,
typename Factor,
typename Dim>
266 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim&)
272 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
273 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
275 #ifdef __cpp_concepts 281 else if constexpr (at_least_square)
282 return (c * factor) / dim;
284 return std::monostate{};
294 template<
typename T,
typename Scalar, std::
size_t direction>
295 struct ReduxTraits<Eigen::internal::member_redux<std::plus<T>, Scalar>, direction>
297 template<
typename C,
typename Factor,
typename Dim>
298 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
300 #ifdef __cpp_concepts 311 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
312 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
314 #ifdef __cpp_concepts 320 else if constexpr (at_least_square)
323 return std::monostate{};
328 #if EIGEN_VERSION_AT_LEAST(3,4,0) 329 template<
typename ResultType,
typename Scalar, std::
size_t direction>
330 struct ReduxTraits<Eigen::internal::member_sum<ResultType, Scalar>, direction>
332 template<typename ResultType, std::size_t direction>
333 struct
ReduxTraits<Eigen::internal::member_sum<ResultType>, direction>
335 :
ReduxTraits<Eigen::internal::member_redux<std::plus<Scalar>, Scalar>, direction> {};
338 template<
typename LhsScalar,
typename RhsScalar,
typename Scalar, std::
size_t direction>
339 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_sum_op<LhsScalar, RhsScalar>, Scalar>, direction>
340 :
ReduxTraits<Eigen::internal::member_redux<std::plus<Scalar>, Scalar>, direction> {};
347 #if EIGEN_VERSION_AT_LEAST(3,4,0) 348 template<
typename ResultType,
typename Scalar, std::
size_t direction>
349 struct ReduxTraits<Eigen::internal::member_minCoeff<ResultType, Scalar>, direction>
351 template<typename ResultType, std::size_t direction>
352 struct
ReduxTraits<Eigen::internal::member_minCoeff<ResultType>, direction>
357 template<
typename X,
typename Dim>
358 constexpr
auto operator()(X x, Dim dim)
const 360 if (dim > 1)
return std::min<ResultType>(x, 0);
366 template<
typename C,
typename Factor,
typename Dim>
367 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
373 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
374 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
376 if constexpr (at_least_square)
380 else if constexpr (values::fixed<C>)
382 if constexpr (
C::value < 0)
return std::monostate{};
385 else return std::monostate{};
390 template<
typename LhsScalar,
typename RhsScalar,
typename Scalar, std::
size_t direction>
391 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_min_op<LhsScalar, RhsScalar>, Scalar>, direction>
392 #if EIGEN_VERSION_AT_LEAST(3,4,0) 393 :
ReduxTraits<Eigen::internal::member_minCoeff<Scalar, Scalar>, direction> {};
403 #if EIGEN_VERSION_AT_LEAST(3,4,0) 404 template<
typename ResultType,
typename Scalar, std::
size_t direction>
405 struct ReduxTraits<Eigen::internal::member_maxCoeff<ResultType, Scalar>, direction>
407 template<typename ResultType, std::size_t direction>
408 struct
ReduxTraits<Eigen::internal::member_maxCoeff<ResultType>, direction>
413 template<
typename X,
typename Dim>
414 constexpr
auto operator()(X x, Dim dim)
const 416 if (dim > 1)
return std::max<ResultType>(x, 0);
422 template<
typename C,
typename Factor,
typename Dim>
423 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
429 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
430 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
432 if constexpr (at_least_square)
436 else if constexpr (values::fixed<C>)
438 if constexpr (
C::value > 0)
return std::monostate{};
441 else return std::monostate{};
446 template<
typename LhsScalar,
typename RhsScalar,
typename Scalar, std::
size_t direction>
447 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_max_op<LhsScalar, RhsScalar>, Scalar>, direction>
448 #if EIGEN_VERSION_AT_LEAST(3,4,0) 449 :
ReduxTraits<Eigen::internal::member_maxCoeff<Scalar, Scalar>, direction> {};
459 #if EIGEN_VERSION_AT_LEAST(3,4,0) 460 template<
typename ResultType,
typename Scalar, std::
size_t direction>
461 struct ReduxTraits<Eigen::internal::member_all<ResultType, Scalar>, direction>
463 template<typename ResultType, std::size_t direction>
464 struct
ReduxTraits<Eigen::internal::member_all<ResultType>, direction>
470 constexpr
bool operator()(X x)
const {
return static_cast<bool>(x); }
474 template<
typename C,
typename Factor,
typename Dim>
475 static constexpr
auto get_constant(
const C& c,
const Factor&,
const Dim&)
481 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
482 static constexpr
auto get_constant_diagonal(
const C&,
const Factor&,
const Dim&)
484 return std::false_type{};
489 template<
typename T,
typename Scalar, std::
size_t direction>
490 struct ReduxTraits<Eigen::internal::member_redux<std::logical_and<T>, Scalar>, direction>
491 #if EIGEN_VERSION_AT_LEAST(3,4,0) 492 :
ReduxTraits<Eigen::internal::member_all<bool, Scalar>, direction> {};
498 template<
typename Scalar, std::
size_t direction>
499 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_boolean_and_op, Scalar>, direction>
500 #if EIGEN_VERSION_AT_LEAST(3,4,0) 501 :
ReduxTraits<Eigen::internal::member_all<bool, Scalar>, direction> {};
511 #if EIGEN_VERSION_AT_LEAST(3,4,0) 512 template<
typename ResultType,
typename Scalar, std::
size_t direction>
513 struct ReduxTraits<Eigen::internal::member_any<ResultType, Scalar>, direction>
515 template<typename ResultType, std::size_t direction>
516 struct
ReduxTraits<Eigen::internal::member_any<ResultType>, direction>
522 constexpr
bool operator()(X x)
const {
return static_cast<bool>(x); }
526 template<
typename C,
typename Factor,
typename Dim>
527 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
533 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
534 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
536 if constexpr (at_least_square)
539 return std::monostate{};
544 template<
typename T,
typename Scalar, std::
size_t direction>
545 struct ReduxTraits<Eigen::internal::member_redux<std::logical_or<T>, Scalar>, direction>
546 #if EIGEN_VERSION_AT_LEAST(3,4,0) 547 :
ReduxTraits<Eigen::internal::member_any<bool, Scalar>, direction> {};
553 template<
typename Scalar, std::
size_t direction>
554 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_boolean_or_op, Scalar>, direction>
555 #if EIGEN_VERSION_AT_LEAST(3,4,0) 556 :
ReduxTraits<Eigen::internal::member_any<bool, Scalar>, direction> {};
566 #if EIGEN_VERSION_AT_LEAST(3,4,0) 567 template<
typename ResultType,
typename Scalar, std::
size_t direction>
568 struct ReduxTraits<Eigen::internal::member_count<ResultType, Scalar>, direction>
570 template<typename ResultType, std::size_t direction>
571 struct
ReduxTraits<Eigen::internal::member_count<ResultType>, direction>
577 constexpr Eigen::Index operator()(X x, std::size_t dim)
const 579 return static_cast<bool>(x) ? static_cast<Eigen::Index>(dim) : Eigen::Index{0};
584 template<
typename C,
typename Factor,
typename Dim>
585 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
591 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
592 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim&)
594 if constexpr (at_least_square)
597 return std::monostate{};
606 #if EIGEN_VERSION_AT_LEAST(3,4,0) 607 template<
typename ResultType,
typename Scalar, std::
size_t direction>
608 struct ReduxTraits<Eigen::internal::member_prod<ResultType, Scalar>, direction>
610 template<typename ResultType, std::size_t direction>
611 struct
ReduxTraits<Eigen::internal::member_prod<ResultType>, direction>
617 constexpr Scalar operator()(X x, std::size_t dim)
const {
return values::pow(x, dim); }
621 template<
typename C,
typename Factor,
typename Dim>
622 static constexpr
auto get_constant(
const C& c,
const Factor& factor,
const Dim& dim)
624 #ifdef __cpp_concepts 635 template<
bool at_least_square,
typename C,
typename Factor,
typename Dim>
636 static constexpr
auto get_constant_diagonal(
const C& c,
const Factor& factor,
const Dim& dim)
643 template<
typename LhsScalar,
typename RhsScalar,
typename Scalar, std::
size_t direction>
644 struct ReduxTraits<Eigen::internal::member_redux<Eigen::internal::scalar_product_op<LhsScalar, RhsScalar>, Scalar>, direction>
645 #if EIGEN_VERSION_AT_LEAST(3,4,0) 646 :
ReduxTraits<Eigen::internal::member_prod<Scalar, Scalar>, direction> {};
652 template<
typename T,
typename Scalar, std::
size_t direction>
653 struct ReduxTraits<Eigen::internal::member_redux<std::multiplies<T>, Scalar>, direction>
654 #if EIGEN_VERSION_AT_LEAST(3,4,0) 655 :
ReduxTraits<Eigen::internal::member_prod<Scalar, Scalar>, direction> {};
Definition: fixed_value.hpp:41
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
constexpr auto imag(const Arg &arg)
A constexpr function to obtain the imaginary part of a (complex) number.
Definition: imag.hpp:40
constexpr auto sqrt(const Arg &arg)
A constexpr alternative to std::sqrt.
Definition: sqrt.hpp:46
Definition: eigen-forward-declarations.hpp:22
constexpr auto real(const Arg &arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
constexpr auto abs(const Arg &arg)
A constexpr alternative to std::abs.
Definition: abs.hpp:38
constexpr auto operation(Operation &&op, Args &&...args)
A potentially constant-evaluated operation involving some number of values.
Definition: operation.hpp:98