16 #ifndef OPENKALMAN_SUM_HPP 17 #define OPENKALMAN_SUM_HPP 26 template<std::size_t...Ix,
typename T0,
typename T1>
27 constexpr
auto sum_constants(std::index_sequence<Ix...> seq, T0&& t0, T1&& t1)
30 return make_constant<T0>(std::move(c), internal::best_vector_space_descriptor(
31 get_vector_space_descriptor<Ix>(t0), get_vector_space_descriptor<Ix>(t1))...);
36 constexpr T&& sum_impl(T&& t) {
return std::forward<T>(t); }
39 template<
typename T0,
typename T1,
typename...Ts>
40 constexpr decltype(
auto) sum_impl(T0&& t0, T1&& t1, Ts&&...ts)
42 if constexpr ((zero<T0> or zero<T1> or (constant_matrix<T0> and constant_matrix<T1>)) and not vector_space_descriptors_match_with<T0, T1>)
44 if (not
vector_space_descriptors_match(t0, t1))
throw std::invalid_argument {
"In sum function, vector space descriptors of arguments do not match"};
47 if constexpr (zero<T0>)
49 return sum_impl(std::forward<T1>(t1), std::forward<Ts>(ts)...);
51 else if constexpr (zero<T1>)
53 return sum_impl(std::forward<T0>(t0), std::forward<Ts>(ts)...);
55 else if constexpr ((constant_matrix<T0> and constant_matrix<T1>))
57 constexpr std::make_index_sequence<std::max(index_count_v<T0>, index_count_v<T1>)> seq;
58 auto ret {sum_impl(sum_constants(seq, std::forward<T0>(t0), std::forward<T1>(t1)), std::forward<Ts>(ts)...)};
61 else if constexpr (constant_matrix<T0> and
sizeof...(Ts) > 0)
63 return sum_impl(std::forward<T1>(t1), sum_impl(std::forward<T0>(t0), std::forward<Ts>(ts)...));
65 else if constexpr (constant_matrix<T1> and
sizeof...(Ts) > 0)
67 return sum_impl(std::forward<T0>(t0), sum_impl(std::forward<T1>(t1), std::forward<Ts>(ts)...));
69 else if constexpr (diagonal_matrix<T0> and diagonal_matrix<T1>)
74 else if constexpr (interface::sum_defined_for<T0, T0&&, T1&&, Ts&&...>)
76 return interface::library_interface<std::decay_t<T0>>::sum(std::forward<T0>(t0), std::forward<T1>(t1), std::forward<Ts>(ts)...);
78 else if constexpr (interface::sum_defined_for<T0, T0&&, T1&&>)
80 return sum_impl(interface::library_interface<std::decay_t<T0>>::
sum(std::forward<T0>(t0), std::forward<T1>(t1)), std::forward<Ts>(ts)...);
82 else if constexpr (interface::sum_defined_for<T1, T1&&, T0&&>)
84 return sum_impl(interface::library_interface<std::decay_t<T1>>::
sum(std::forward<T1>(t1), std::forward<T0>(t0)), std::forward<Ts>(ts)...);
86 else if constexpr (interface::sum_defined_for<T0, T0&&, decltype(to_native_matrix<T0>(std::declval<T1&&>()))>)
88 return sum_impl(interface::library_interface<std::decay_t<T0>>::
sum(std::forward<T0>(t0), to_native_matrix<T0>(std::forward<T1>(t1))), std::forward<Ts>(ts)...);
90 else if constexpr (interface::sum_defined_for<T1, T1&&, decltype(to_native_matrix<T1>(std::declval<T0&&>()))>)
92 return sum_impl(interface::library_interface<std::decay_t<T1>>::
sum(std::forward<T1>(t1), to_native_matrix<T1>(std::forward<T0>(t0))), std::forward<Ts>(ts)...);
105 #ifdef __cpp_concepts 108 template<
typename...Ts, std::enable_if_t<(indexible<Ts> and ...) and (
sizeof...(Ts) > 0) and
111 constexpr decltype(
auto)
114 auto s {internal::make_fixed_size_adapter_like<Ts...>(detail::sum_impl(std::forward<Ts>(ts)...))};
117 return make_triangular_matrix<t>(std::move(s));
118 else if constexpr ((... and hermitian_matrix<Ts>) and not
hermitian_matrix<decltype(s)>)
127 #endif //OPENKALMAN_SUM_HPP decltype(auto) constexpr make_hermitian_matrix(Arg &&arg)
Creates a hermitian_matrix by, if necessary, wrapping the argument in a hermitian_adapter.
Definition: make_hermitian_matrix.hpp:37
Lower, upper, or diagonal matrix.
constexpr bool indexible
T is a generalized tensor type.
Definition: indexible.hpp:32
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
constexpr bool triangular_matrix
Specifies that a type is a triangular matrix (upper, lower, or diagonal).
Definition: triangular_matrix.hpp:37
The root namespace for OpenKalman.
Definition: basics.hpp:34
constexpr bool vector_space_descriptors_match(const Ts &...ts)
Return true if every set of coordinates::pattern of a set of objects match.
Definition: vector_space_descriptors_match.hpp:62
decltype(auto) constexpr diagonal_of(Arg &&arg)
Extract a column vector (or column slice for rank>2 tensors) comprising the diagonal elements...
Definition: diagonal_of.hpp:33
constexpr bool vector_space_descriptors_may_match_with
Specifies that indexible objects Ts may have equivalent dimensions and vector-space types...
Definition: vector_space_descriptors_may_match_with.hpp:49
decltype(auto) constexpr sum(Ts &&...ts)
Element-by-element sum of one or more objects.
Definition: sum.hpp:112
constexpr auto triangle_type_of_v
The TriangleType associated with a triangular_matrix.
Definition: triangle_type_of.hpp:41
constant_coefficient(const T &) -> constant_coefficient< T >
Deduction guide for constant_coefficient.
constexpr bool hermitian_matrix
Specifies that a type is a hermitian matrix (assuming it is square_shaped).
Definition: hermitian_matrix.hpp:50