16 #ifndef OPENKALMAN_INTERFACES_FIXEDSIZEADAPTER_HPP 17 #define OPENKALMAN_INTERFACES_FIXEDSIZEADAPTER_HPP 26 template<
typename NestedObject,
typename Descriptors>
38 template<
typename Arg>
42 using NewDesc = decltype(OpenKalman::internal::remove_trailing_1D_descriptors(std::declval<Descriptors>()));
47 template<
typename Arg,
typename N>
51 if constexpr (values::fixed<N>)
55 else if constexpr (fixed_pattern<std::tuple_element_t<N::value, Descriptors>>)
56 return std::tuple_element_t<N::value, Descriptors> {};
67 template<
typename Arg>
75 template<
typename Arg> requires constant_matrix<NestedObject>
77 template<
typename M = NestedObject,
typename Arg, std::enable_if_t<constant_matrix<M>,
int> = 0>
79 static constexpr
auto get_constant(
const Arg& arg)
86 template<
typename Arg> requires constant_diagonal_matrix<NestedObject>
88 template<
typename M = NestedObject,
typename Arg, std::enable_if_t<constant_diagonal_matrix<M>,
int> = 0>
90 static constexpr
auto get_constant_diagonal(
const Arg& arg)
102 template<TriangleType t>
103 static constexpr
bool is_triangular = triangular_matrix<NestedObject, t>;
106 static constexpr
bool is_triangular_adapter =
false;
109 static constexpr
bool is_hermitian = hermitian_matrix<NestedObject, Applicability::permitted>;
112 static constexpr
bool is_writable = writable<NestedObject>;
115 #ifdef __cpp_lib_concepts 116 template<
typename Arg> requires raw_data_defined_for<nested_object_of_t<Arg&&>>
118 template<typename Arg, std::enable_if_t<raw_data_defined_for<typename nested_object_of<Arg&&>::type>,
int> = 0>
120 static constexpr decltype(
auto)
127 static constexpr
Layout layout = layout_of_v<NestedObject>;
130 #ifdef __cpp_concepts 133 template<Layout l = layout,
typename Arg, std::enable_if_t<l == Layout::str
ide,
int> = 0>
138 return OpenKalman::internal::strides(
nested_object(std::forward<Arg>(arg)));
148 template<
typename Nested,
typename Descriptors>
153 using NestedObject = std::decay_t<Nested>;
158 template<
typename Derived>
159 using LibraryBase = internal::library_base_t<Derived, NestedObject>;
163 template<
typename Object,
typename Indices>
164 static constexpr decltype(
auto) add_trailing_indices(
const Indices& indices)
166 if constexpr (not index_range_for<Indices, Object>)
168 constexpr
auto N = index_count_v<Object>;
169 std::array<std::size_t, N> ret;
170 #ifdef __cpp_lib_ranges 171 namespace ranges = std::ranges;
173 std::ranges::fill(std::ranges::copy(ranges::begin(indices), ranges::end(indices), ranges::begin(ret)), ranges::end(ret), 0);
181 #ifdef __cpp_lib_ranges 182 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>> and
183 interface::get_component_defined_for<NestedObject, nested_object_of_t<Arg&>, std::initializer_list<std::size_t>>
184 static constexpr values::scalar decltype(
auto)
186 template<
typename Arg,
typename Indices, std::enable_if_t<
187 interface::get_component_defined_for<NestedObject, typename nested_object_of<Arg&>::type, std::initializer_list<std::size_t>>,
int> = 0>
188 static constexpr decltype(
auto)
196 #ifdef __cpp_lib_ranges 197 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>> and
198 interface::set_component_defined_for<NestedObject, nested_object_of_t<Arg&>,
const scalar_type_of_t<Arg>&, std::initializer_list<std::size_t>>
200 template<
typename Arg,
typename Indices, std::enable_if_t<
201 interface::set_component_defined_for<NestedObject, typename nested_object_of<Arg&>::type,
const typename scalar_type_of<Arg>::type&, std::initializer_list<std::size_t>>,
int> = 0>
203 static constexpr
void 204 set_component(Arg& arg,
const scalar_type_of_t<Arg>& s,
const Indices& indices)
210 #ifdef __cpp_concepts 211 template<
typename A> requires interface::to_native_matrix_defined_for<NestedObject, nested_object_of_t<A&&>>
213 template<
typename A, std::enable_if_t<
interface::to_native_matrix_defined_for<NestedObject, nested_
object_of_t<A&&>>,
int> = 0>
215 static decltype(
auto)
222 #ifdef __cpp_concepts 223 template<
typename To,
typename From> requires
224 interface::assign_defined_for<NestedObject, nested_object_of_t<To&>, From&&>
226 template<
typename To,
typename From, std::enable_if_t<
227 interface::assign_defined_for<NestedObject, nested_object_of_t<To&>, From&&>,
int> = 0>
236 #ifdef __cpp_concepts 237 template<Layout layout,
typename Scalar,
typename D> requires
238 interface::make_default_defined_for<NestedObject, layout, Scalar, D&&>
240 template<
Layout layout,
typename Scalar,
typename D, std::enable_if_t<
241 interface::make_default_defined_for<NestedObject, layout, Scalar, D&&>,
int> = 0>
246 return NestedInterface::template make_default<layout, Scalar>(std::forward<D>(d));
250 #ifdef __cpp_concepts 251 template<
Layout layout,
typename Arg,
typename...Scalars> requires
252 interface::fill_components_defined_for<NestedObject, layout, nested_object_of_t<Arg&>, Scalars...>
254 template<
Layout layout,
typename Arg,
typename...Scalars, std::enable_if_t<
255 interface::fill_components_defined_for<NestedObject, layout, typename nested_object_of<Arg&>::type, Scalars...>,
int> = 0>
260 NestedInterface::template fill_components<layout>(
nested_object(arg), scalars...);
264 #ifdef __cpp_concepts 265 template<
typename C,
typename D> requires interface::make_constant_defined_for<NestedObject, C&&, D&&>
267 template<
typename C,
typename D, std::enable_if_t<
interface::make_constant_defined_for<NestedObject, C&&, D&&>,
int> = 0>
269 static constexpr
auto 276 #ifdef __cpp_concepts 277 template<
typename Scalar,
typename D> requires interface::make_identity_matrix_defined_for<NestedObject, Scalar, D&&>
279 template<
typename Scalar,
typename D, std::enable_if_t<
interface::make_
identity_matrix_defined_for<NestedObject, Scalar, D&&>,
int> = 0>
281 static constexpr
auto 282 make_identity_matrix(D&& d)
284 return NestedInterface::make_identity_matrix(std::forward<D>(d));
288 #ifdef __cpp_concepts 289 template<TriangleType t, indexible Arg> requires
290 interface::make_triangular_matrix_defined_for<NestedObject, t, nested_object_of_t<Arg&&>>
291 static constexpr triangular_matrix<t>
auto 293 template<
TriangleType t,
typename Arg, std::enable_if_t<
294 interface::make_triangular_matrix_defined_for<NestedObject, t, typename nested_object_of<Arg&&>::type>,
int> = 0>
295 static constexpr
auto 299 return internal::make_fixed_size_adapter<Descriptors>(NestedInterface::template make_triangular_matrix<t>(
nested_object(std::forward<Arg>(arg))));
303 #ifdef __cpp_concepts 304 template<HermitianAdapterType t, indexible Arg> requires
305 interface::make_hermitian_adapter_defined_for<NestedObject, t, nested_object_of_t<Arg&&>>
309 make_hermitian_adapter_defined_for<NestedObject, t, typename nested_object_of<Arg&>::type>,
int> = 0>
310 static constexpr
auto 312 make_hermitian_adapter(Arg&& arg)
314 return internal::make_fixed_size_adapter<Descriptors>(NestedInterface::template make_hermitian_adapter<t>(
nested_object(std::forward<Arg>(arg))));
319 template<
typename Arg,
typename...Begin,
typename...Size, std::size_t...Ix>
320 static decltype(
auto)
321 get_slice_impl(Arg&& arg,
const std::tuple<Begin...>& begin_tup,
const std::tuple<Size...>& size_tup, std::index_sequence<Ix...>)
323 using NewDesc = std::tuple<std::decay_t<decltype(coordinates::get_slice<scalar_type_of_t<Arg>>(
324 std::declval<std::tuple_element_t<Ix, Descriptors>>, std::declval<Begin>(), std::declval<Size>()))>...>;
325 return internal::make_fixed_size_adapter<NewDesc>(NestedInterface::get_slice(
nested_object(std::forward<Arg>(arg)), begin_tup, size_tup));
330 #ifdef __cpp_concepts 331 template<
typename Arg,
typename...Begin,
typename...Size> requires
332 interface::get_slice_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const std::tuple<Begin...>&,
const std::tuple<Size...>&>
334 template<
typename Arg,
typename...Begin,
typename...Size, std::enable_if_t<
335 interface::get_slice_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const std::tuple<Begin...>&,
const std::tuple<Size...>&>,
int> = 0>
337 static decltype(
auto)
338 get_slice(Arg&& arg,
const std::tuple<Begin...>& begin_tup,
const std::tuple<Size...>& size_tup)
340 return get_slice_impl(std::forward<Arg>(arg), begin_tup, size_tup, std::make_index_sequence<std::tuple_size_v<Descriptors>>{});
344 #ifdef __cpp_concepts 345 template<
typename Arg,
typename Block,
typename...Begin> requires
346 interface::set_slice_defined_for<Arg, nested_object_of_t<Arg&>, Block&&,
const Begin&...>
348 template<
typename Arg,
typename Block,
typename...Begin, std::enable_if_t<
349 interface::set_slice_defined_for<Arg, typename nested_object_of<Arg&>::type, Block&&,
const Begin&...>,
int> = 0>
352 set_slice(Arg& arg, Block&& block,
const Begin&...begin)
358 #ifdef __cpp_concepts 359 template<TriangleType t,
typename A,
typename B> requires
360 interface::set_triangle_defined_for<NestedObject, t, nested_object_of_t<A&&>, B&&>
362 template<
TriangleType t,
typename A,
typename B, std::enable_if_t<
363 interface::set_triangle_defined_for<NestedObject, t, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
366 set_triangle(A&& a, B&& b)
368 NestedInterface::template set_triangle<t>(
nested_object(std::forward<A>(a)), std::forward<B>(b));
372 #ifdef __cpp_concepts 373 template<
typename Arg> requires
374 interface::to_diagonal_defined_for<NestedObject, nested_object_of_t<Arg&&>>
377 template<
typename Arg, std::enable_if_t<
378 interface::to_diagonal_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
379 static constexpr
auto 389 template<
typename Arg,
typename V0,
typename V1,
typename...Vs>
390 static constexpr decltype(
auto)
391 diagonal_of_impl(Arg&& arg,
const std::tuple<V0, V1, Vs...>&)
393 using D0 = decltype(internal::smallest_vector_space_descriptor<scalar_type_of_t<Arg>>(std::declval<V0>(), std::declval<V1>()));
394 return OpenKalman::internal::make_fixed_size_adapter<D0, Vs...>(std::forward<Arg>(arg));
399 #ifdef __cpp_concepts 400 template<indexible Arg> requires diagonal_adapter<NestedObject> or
401 (diagonal_adapter<NestedObject, 1> and
403 interface::diagonal_of_defined_for<NestedObject, nested_object_of_t<Arg&&>>
406 template<
typename Arg, std::enable_if_t<diagonal_adapter<NestedObject> or
407 (diagonal_adapter<NestedObject, 1> and
408 interface::transpose_defined_for<NestedObject, decltype(nested_
object(nested_
object(std::declval<Arg>())))>) or
409 interface::diagonal_of_defined_for<NestedObject,
typename nested_
object_of<Arg&&>::type>,
int> = 0>
410 static constexpr
auto 414 if constexpr (diagonal_adapter<NestedObject>)
416 else if constexpr (diagonal_adapter<NestedObject, 1> and
426 template<std::
size_t Ix,
typename Arg,
typename Factors_tup>
427 static constexpr
auto broadcast_for_index(
const Arg& arg,
const Factors_tup& factors_tup)
429 constexpr
auto N = std::tuple_size_v<Factors_tup>;
430 if constexpr (Ix < N)
431 return get_vector_space_descriptor<Ix>(arg) * std::get<Ix>(factors_tup);
437 template<
typename Arg, std::size_t...Is,
typename Factors_tup>
438 static constexpr
auto broadcast_impl(Arg&& arg, std::index_sequence<Is...>,
const Factors_tup& factors_tup)
440 constexpr
auto N = std::tuple_size_v<Factors_tup>;
441 return internal::make_fixed_size_adapter<decltype(broadcast_for_index<Is>(arg, factors_tup))...>(std::forward<Arg>(arg));
446 #ifdef __cpp_concepts 448 interface::broadcast_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const Factors&...>
451 template<
typename Arg,
typename...Factors, std::enable_if_t<
452 interface::broadcast_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const Factors&...>,
int> = 0>
455 broadcast(Arg&& arg,
const Factors&...factors)
458 using Ret = decltype(ret);
459 auto seq = std::make_index_sequence<std::max(index_count_v<Arg>,
sizeof...(factors))>{};
460 return broadcast_impl(std::forward<Ret>(ret), seq, std::forward_as_tuple(factors...));
464 #ifdef __cpp_concepts 465 template<coordinates::pattern...IDs,
typename Operation> requires
466 interface::n_ary_operation_defined_for<
NestedInterface,
const std::tuple<IDs...>&, Operation&&>
469 template<
typename...IDs,
typename Operation, std::enable_if_t<
470 interface::n_ary_operation_defined_for<NestedInterface,
const std::tuple<IDs...>&, Operation&&>,
int> = 0>
479 #ifdef __cpp_concepts 480 template<coordinates::pattern...IDs,
typename Operation,
indexible Arg,
indexible...Args> requires
481 interface::n_ary_operation_defined_for<NestedObject,
const std::tuple<IDs...>&, Operation&&,
nested_object_of_t<Arg&&>, Args...>
484 template<
typename...IDs,
typename Operation,
typename Arg,
typename...Args, std::enable_if_t<
485 interface::n_ary_operation_defined_for<NestedObject,
const std::tuple<IDs...>&, Operation&&,
typename nested_object_of<Arg&&>::type, Args...>,
int> = 0>
488 n_ary_operation(
const std::tuple<IDs...>& d_tup, Operation&& op, Arg&& arg, Args&&...args)
490 return internal::make_fixed_size_adapter<IDs...>(
496 template<std::size_t Ix, std::size_t...indices>
497 static constexpr
bool matching_Ix() {
return ((Ix == indices) or ...); }
499 template<std::size_t...indices,
typename Arg, std::size_t...Ix>
500 static constexpr decltype(
auto)
501 reduce_impl(Arg&& arg, std::index_sequence<Ix...> seq)
503 return internal::make_fixed_size_adapter<std::tuple<
505 matching_Ix<Ix, indices...>(),
507 std::tuple_element_t<Ix, Descriptors>>...>>
508 (std::forward<Arg>(arg));
513 #ifdef __cpp_concepts 514 template<std::size_t...indices,
typename BinaryFunction,
indexible Arg> requires
515 interface::reduce_defined_for<NestedObject, BinaryFunction&&, nested_object_of_t<Arg&&>, indices...>
517 template<std::size_t...indices,
typename BinaryFunction,
typename Arg, std::enable_if_t<
518 interface::reduce_defined_for<NestedObject, BinaryFunction&&, typename nested_object_of<Arg&&>::type, indices...>,
int> = 0>
520 static constexpr decltype(
auto)
521 reduce(BinaryFunction&& op, Arg&& arg)
523 return reduce_impl<indices...>(
524 NestedInterface::template
reduce<indices...>(std::forward<BinaryFunction>(op),
nested_object(std::forward<Arg>(arg))),
525 std::make_index_sequence<std::tuple_size_v<Descriptors>>{});
529 #ifdef __cpp_concepts 530 template<indexible Arg> requires interface::to_euclidean_defined_for<NestedObject, nested_object_of_t<Arg&&>>
533 template<
typename Arg, std::enable_if_t<
534 interface::to_euclidean_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
535 static constexpr
auto 539 constexpr
auto dim = std::tuple_size_v<Descriptors>;
540 if constexpr (dim == 0)
542 return std::forward<Arg>(arg);
546 using D0 = std::tuple_element_t<0, Descriptors>;
547 if constexpr (coordinates::euclidean_pattern<D0>)
549 return std::forward<Arg>(arg);
553 using V0 = std::conditional_t<
556 coordinates::DynamicDescriptor<scalar_type_of_t<Arg>>>;
557 using Vtail = std::decay_t<decltype(internal::tuple_slice<1, dim>(std::declval<Descriptors>()))>;
558 using Vcat = decltype(std::tuple_cat(std::declval<V0>()), std::declval<Vtail>());
565 #ifdef __cpp_concepts 566 template<indexible Arg, coordinates::pattern D> requires
567 interface::from_euclidean_defined_for<NestedObject, nested_object_of_t<Arg&&>, D&&>
570 template<
typename Arg,
typename V, std::enable_if_t<
571 interface::from_euclidean_defined_for<NestedObject, typename nested_object_of<Arg&&>::type, V&&>,
int> = 0>
572 static constexpr
auto 576 if constexpr (coordinates::euclidean_pattern<D>)
578 return std::forward<Arg>(arg);
582 constexpr
auto dim = std::tuple_size_v<Descriptors>;
583 using Vtail = std::decay_t<decltype(internal::tuple_slice<1, dim>(std::declval<Descriptors>()))>;
584 using Vcat = decltype(std::tuple_cat(std::declval<D>()), std::declval<Vtail>());
590 #ifdef __cpp_concepts 591 template<indexible Arg> requires interface::wrap_angles_defined_for<NestedObject, nested_object_of_t<Arg&&>>
594 template<
typename Arg, std::enable_if_t<
595 interface::wrap_angles_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
596 static constexpr
auto 598 wrap_angles(Arg&& arg)
600 return internal::make_fixed_size_adapter<Descriptors>(NestedInterface::wrap_angles(
nested_object(std::forward<Arg>(arg))));
604 #ifdef __cpp_concepts 605 template<indexible Arg> requires
606 interface::conjugate_defined_for<NestedObject, Arg&&> or
607 interface::conjugate_defined_for<NestedObject, nested_object_of_t<Arg&&>>
610 template<
typename Arg, std::enable_if_t<
611 interface::conjugate_defined_for<NestedObject, Arg&&> or
612 interface::conjugate_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
613 static constexpr
auto 617 if constexpr (interface::conjugate_defined_for<NestedObject, Arg&&>)
624 return internal::make_fixed_size_adapter_like<Arg>(std::forward<decltype(conj)>(
conj));
629 #ifdef __cpp_concepts 630 template<indexible Arg> requires
631 interface::transpose_defined_for<NestedObject, Arg&&> or
632 interface::transpose_defined_for<NestedObject, nested_object_of_t<Arg&&>>
635 template<
typename Arg, std::enable_if_t<
636 interface::transpose_defined_for<NestedObject, Arg&&> or
637 interface::transpose_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
638 static constexpr
auto 642 if constexpr (interface::transpose_defined_for<NestedObject, Arg&&>)
654 #ifdef __cpp_concepts 655 template<indexible Arg> requires
656 interface::adjoint_defined_for<NestedObject, Arg&&> or
657 interface::adjoint_defined_for<NestedObject, nested_object_of_t<Arg&&>>
660 template<
typename Arg, std::enable_if_t<
661 interface::adjoint_defined_for<NestedObject, Arg&&> or
662 interface::adjoint_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
663 static constexpr
auto 667 if constexpr (interface::adjoint_defined_for<NestedObject, Arg&&>)
679 #ifdef __cpp_concepts 680 template<indexible Arg> requires
681 interface::determinant_defined_for<NestedObject, Arg&&> or
682 interface::determinant_defined_for<NestedObject, nested_object_of_t<Arg&&>>
683 static constexpr std::convertible_to<scalar_type_of_t<Arg>>
auto 685 template<
typename Arg, std::enable_if_t<
686 interface::determinant_defined_for<NestedObject, Arg&&> or
687 interface::determinant_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
688 static constexpr
auto 692 if constexpr (interface::determinant_defined_for<NestedObject, Arg&&>)
703 #ifdef __cpp_concepts 704 template<
typename Arg,
typename...Args> requires
705 interface::sum_defined_for<NestedObject, Arg&&, Args&&...> or
706 interface::sum_defined_for<NestedObject, nested_object_of_t<Arg&&>, Args&&...>
708 template<
typename Arg,
typename...Args, std::enable_if_t<
709 interface::sum_defined_for<NestedObject, Arg&&, Args&&...> or
710 interface::sum_defined_for<NestedObject, typename nested_object_of<Arg&&>::type, Args&&...>,
int> = 0>
713 sum(Arg&& arg, Args&&...args)
715 if constexpr (interface::sum_defined_for<NestedObject, Arg&&, Args&&...>)
726 #ifdef __cpp_concepts 727 template<
typename A,
typename B> requires
728 interface::contract_defined_for<NestedObject, A&&, B&&> or
729 interface::contract_defined_for<NestedObject, nested_object_of_t<A&&>, B&&>
731 template<
typename A,
typename B, std::enable_if_t<
732 interface::contract_defined_for<NestedObject, A&&, B&&> or
733 interface::contract_defined_for<NestedObject, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
738 if constexpr (interface::contract_defined_for<NestedObject, A&&, B&&>)
750 #ifdef __cpp_concepts 751 template<
bool on_the_right,
typename A,
typename B> requires
752 interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&> or
753 interface::contract_in_place_defined_for<NestedObject, on_the_right, nested_object_of_t<A&&>, B&&>
755 template<
bool on_the_right,
typename A,
typename B, std::enable_if_t<
756 interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&> or
757 interface::contract_in_place_defined_for<NestedObject, on_the_right, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
759 static decltype(
auto)
762 if constexpr (interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&>)
764 return NestedInterface::template contract_in_place<on_the_right>(std::forward<A>(a), std::forward<B>(b));
768 auto&& ret = NestedInterface::template contract_in_place<on_the_right>(
nested_object(std::forward<A>(a)), std::forward<B>(b));
769 using Ret = decltype(ret);
772 return std::forward<A>(a);
774 else if constexpr (on_the_right)
786 #ifdef __cpp_concepts 787 template<TriangleType triangle_type, indexible Arg> requires
788 interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&> or
789 interface::cholesky_factor_defined_for<NestedObject, triangle_type, nested_object_of_t<Arg&&>>
790 static constexpr triangular_matrix<triangle_type>
auto 792 template<
TriangleType triangle_type,
typename Arg, std::enable_if_t<
793 interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&> or
794 interface::cholesky_factor_defined_for<NestedObject, triangle_type, typename nested_object_of<Arg&&>::type>,
int> = 0>
795 static constexpr
auto 799 if constexpr (interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&>)
801 return NestedInterface::template cholesky_factor<triangle_type>(std::forward<Arg>(arg));
805 auto tri = NestedInterface::template cholesky_factor<triangle_type>(
nested_object(std::forward<Arg>(arg)));
806 return internal::make_fixed_square_adapter_like(std::move(tri));
811 #ifdef __cpp_concepts 812 template<HermitianAdapterType significant_triangle, indexible A, indexible U> requires
813 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&, const scalar_type_of_t<A>&> or
814 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, nested_object_of_t<A&&>, U&&,
const scalar_type_of_t<A>&>
818 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&, const typename scalar_type_of<A>::type&> or
819 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, typename nested_object_of<A&&>::type, U&&,
const typename scalar_type_of<A>::type&>,
int> = 0>
820 static constexpr
auto 824 if constexpr (interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&,
const scalar_type_of_t<A>&>)
826 return NestedInterface::template rank_update_hermitian<significant_triangle>(std::forward<A>(a), std::forward<U>(u), alpha);
830 auto tri = NestedInterface::template rank_update_hermitian<significant_triangle>(
nested_object(std::forward<A>(a), std::forward<U>(u), alpha));
831 return internal::make_fixed_square_adapter_like(std::move(tri));
836 #ifdef __cpp_concepts 837 template<TriangleType triangle_type, indexible A, indexible U> requires
838 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&, const scalar_type_of_t<A>&> or
839 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, nested_object_of_t<A&&>, U&&,
const scalar_type_of_t<A>&>
840 static constexpr triangular_matrix<triangle_type>
auto 842 template<
TriangleType triangle_type,
typename A,
typename U, std::enable_if_t<
843 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&, const typename scalar_type_of<A>::type&> or
844 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, typename nested_object_of<A&&>::type, U&&,
const typename scalar_type_of<A>::type&>,
int> = 0>
845 static constexpr
auto 849 if constexpr (interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&,
const scalar_type_of_t<A>&>)
851 return NestedInterface::template rank_update_triangular<triangle_type>(std::forward<A>(a), std::forward<U>(u), alpha);
855 auto tri = NestedInterface::template rank_update_triangular<triangle_type>(
nested_object(std::forward<A>(a), std::forward<U>(u), alpha));
856 return internal::make_fixed_square_adapter_like(std::move(tri));
861 #ifdef __cpp_concepts 862 template<
bool must_be_unique,
bool must_be_exact,
typename A,
typename B> requires
863 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&> or
864 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, nested_object_of_t<A&&>, B&&>
867 template<
bool must_be_unique,
bool must_be_exact,
typename A,
typename B, std::enable_if_t<
868 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&> or
869 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
874 if constexpr (interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&>)
876 return NestedInterface::template solve<must_be_unique, must_be_exact>(std::forward<A>(a), std::forward<B>(b));
881 NestedInterface::template solve<must_be_unique, must_be_exact>(
nested_object(std::forward<A>(a)), std::forward<B>(b)));
886 #ifdef __cpp_concepts 887 template<
typename A> requires
888 interface::LQ_decomposition_defined_for<NestedObject, A&&> or
889 interface::LQ_decomposition_defined_for<NestedObject, nested_object_of_t<A&&>>
891 template<
typename A, std::enable_if_t<
892 interface::LQ_decomposition_defined_for<NestedObject, A&&> or
893 interface::LQ_decomposition_defined_for<NestedObject, typename nested_object_of<A&&>::type>,
int> = 0>
898 if constexpr (interface::LQ_decomposition_defined_for<NestedObject, A&&>)
906 return internal::make_fixed_square_adapter_like<D0>(std::forward<decltype(ret)>(ret));
911 #ifdef __cpp_concepts 912 template<
typename A> requires
913 interface::QR_decomposition_defined_for<NestedObject, A&&> or
914 interface::QR_decomposition_defined_for<NestedObject, nested_object_of_t<A&&>>
916 template<
typename A, std::enable_if_t<
917 interface::QR_decomposition_defined_for<NestedObject, A&&> or
918 interface::QR_decomposition_defined_for<NestedObject, typename nested_object_of<A&&>::type>,
int> = 0>
923 if constexpr (interface::QR_decomposition_defined_for<NestedObject, A&&>)
931 return internal::make_fixed_square_adapter_like<D1>(std::forward<decltype(ret)>(ret));
940 #endif //OPENKALMAN_INTERFACES_FIXEDSIZEADAPTER_HPP constexpr auto count_indices(const T &t)
Get the number of indices available to address the components of an indexible object.
Definition: count_indices.hpp:33
decltype(auto) constexpr from_euclidean(Arg &&arg, const V &v)
Project the Euclidean vector space associated with index 0 to coordinates::pattern v after applying d...
Definition: from_euclidean.hpp:35
typename nested_object_of< T >::type nested_object_of_t
Helper type for nested_object_of.
Definition: nested_object_of.hpp:66
constexpr auto n_ary_operation(const std::tuple< Ds... > &d_tup, Operation &&operation, Args &&...args)
Perform a component-wise n-ary operation, using broadcasting to match the size of a pattern matrix...
Definition: n_ary_operation.hpp:319
decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
TriangleType
The type of a triangular matrix.
Definition: global-definitions.hpp:60
Definition: indexible_object_traits.hpp:36
Definition: basics.hpp:41
decltype(auto) rank_update_hermitian(A &&a, U &&u, scalar_type_of_t< A > alpha=1)
Do a rank update on a hermitian matrix.
Definition: rank_update_hermitian.hpp:45
constexpr bool diagonal_matrix
Specifies that a type is a diagonal matrix or tensor.
Definition: diagonal_matrix.hpp:32
Arg && set_component(Arg &&arg, const scalar_type_of_t< Arg > &s, const Indices &indices)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: set_component.hpp:51
decltype(auto) constexpr conjugate(Arg &&arg)
Take the conjugate of a matrix.
Definition: conjugate.hpp:33
decltype(auto) constexpr get_slice(Arg &&arg, const std::tuple< Offset... > &offsets, const std::tuple< Extent... > &extents)
Extract a slice from a matrix or tensor.
Definition: get_slice.hpp:101
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
The coordinates::pattern for index N of object T.
Definition: vector_space_descriptor_of.hpp:34
constexpr bool indexible
T is a generalized tensor type.
Definition: indexible.hpp:32
decltype(auto) to_native_matrix(Arg &&arg)
If it isn't already, convert Arg to a native object in the library associated with LibraryObject...
Definition: to_native_matrix.hpp:35
decltype(auto) constexpr QR_decomposition(A &&a)
Perform a QR decomposition of matrix A=Q[U,0], U is a upper-triangular matrix, and Q is orthogonal...
Definition: QR_decomposition.hpp:33
HermitianAdapterType
The type of a hermitian adapter, indicating which triangle of the nested matrix is used...
Definition: global-definitions.hpp:78
The size of a sized object (including a collection).
Definition: size_of.hpp:36
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
decltype(auto) constexpr reduce(BinaryFunction &&b, Arg &&arg)
Perform a partial reduction based on an associative binary function, across one or more indices...
Definition: reduce.hpp:143
decltype(auto) constexpr broadcast(Arg &&arg, const Factors &...factors)
Broadcast an object by replicating it by factors specified for each index.
Definition: broadcast.hpp:49
Type scalar type (e.g., std::float, std::double, std::complex<double>) of a tensor.
Definition: scalar_type_of.hpp:32
A wrapper type's nested object type, if it exists.
Definition: nested_object_of.hpp:33
The constant associated with T, assuming T is a constant_matrix.
Definition: constant_coefficient.hpp:36
decltype(auto) constexpr transpose(Arg &&arg)
Take the transpose of a matrix.
Definition: transpose.hpp:58
decltype(auto) constexpr all_vector_space_descriptors(const T &t)
Return a collection of coordinates::pattern objects associated with T.
Definition: all_vector_space_descriptors.hpp:52
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37
The constant associated with T, assuming T is a constant_diagonal_matrix.
Definition: constant_diagonal_coefficient.hpp:32
constexpr A && contract_in_place(A &&a, B &&b)
In-place matrix multiplication of A * B, storing the result in A.
Definition: contract_in_place.hpp:38
constexpr auto solve(A &&a, B &&b)
Solve the equation AX = B for X, which may or may not be a unique solution.
Definition: solve.hpp:87
constexpr auto conj(const Arg &arg)
A constexpr function for the complex conjugate of a (complex) number.
Definition: conj.hpp:39
constexpr auto determinant(Arg &&arg)
Take the determinant of a matrix.
Definition: determinant.hpp:44
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
A generalization of the above: a custom stride is specified for each index.
Definition: FixedSizeAdapter.hpp:28
decltype(auto) constexpr to_euclidean(Arg &&arg)
Project the vector space associated with index 0 to a Euclidean space for applying directional statis...
Definition: to_euclidean.hpp:38
decltype(auto) constexpr adjoint(Arg &&arg)
Take the adjoint of a matrix.
Definition: adjoint.hpp:33
typename vector_space_descriptor_of< T, N >::type vector_space_descriptor_of_t
helper template for vector_space_descriptor_of.
Definition: vector_space_descriptor_of.hpp:56
Arg && fill_components(Arg &&arg, S...s)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: fill_components.hpp:44
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
decltype(auto) constexpr sum(Ts &&...ts)
Element-by-element sum of one or more objects.
Definition: sum.hpp:112
decltype(auto) constexpr LQ_decomposition(A &&a)
Perform an LQ decomposition of matrix A=[L,0]Q, L is a lower-triangular matrix, and Q is orthogonal...
Definition: LQ_decomposition.hpp:33
decltype(auto) rank_update_triangular(A &&a, U &&u, scalar_type_of_t< A > alpha=1)
Do a rank update on triangular matrix.
Definition: rank_update_triangular.hpp:48
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
constexpr bool index
T is an index value.
Definition: index.hpp:56
constexpr auto make_constant(C &&c, Descriptors &&descriptors)
Make a constant object based on a particular library object.
Definition: make_constant.hpp:37
constexpr To && assign(To &&a, From &&b)
Assign a writable object from an indexible object.
Definition: assign.hpp:51
decltype(auto) constexpr get_component(Arg &&arg, const Indices &indices)
Get a component of an object at a particular set of indices.
Definition: get_component.hpp:54
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448
constexpr bool hermitian_matrix
Specifies that a type is a hermitian matrix (assuming it is square_shaped).
Definition: hermitian_matrix.hpp:50
constexpr auto get_vector_space_descriptor(const T &t, const N &n)
Get the coordinates::pattern object for index N of indexible object T.
Definition: get_vector_space_descriptor.hpp:56
decltype(auto) constexpr make_triangular_matrix(Arg &&arg)
Create a triangular_matrix from a general matrix.
Definition: make_triangular_matrix.hpp:35
decltype(auto) constexpr cholesky_factor(A &&a)
Take the Cholesky factor of a matrix.
Definition: cholesky_factor.hpp:38
constexpr Arg && set_slice(Arg &&arg, Block &&block, const Begin &...begin)
Assign an object to a particular slice of a matrix or tensor.
Definition: set_slice.hpp:56