16 #ifndef OPENKALMAN_INTERFACES_VECTORSPACEADAPTER_HPP 17 #define OPENKALMAN_INTERFACES_VECTORSPACEADAPTER_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>
52 if constexpr (coordinates::euclidean_pattern_collection<Descriptors>)
56 else if constexpr (pattern_tuple<Descriptors>)
59 if constexpr (values::fixed<N>)
63 else if constexpr (fixed_pattern<std::tuple_element_t<N::value, Descriptors>>)
64 return std::tuple_element_t<N::value, Descriptors> {};
66 return std::get<N::value>(std::forward<Arg>(arg).my_descriptors);
71 [](
auto&&...vs){
return std::array<coordinates::DynamicDescriptor<scalar_type>, dim> {std::forward<decltype(vs)>(vs)...}; },
72 std::forward<Arg>(arg).my_descriptors)[n];
77 using Dyn = coordinates::DynamicDescriptor<scalar_type>;
78 #ifdef __cpp_lib_ranges 79 namespace ranges = std::ranges;
87 return static_cast<Dyn
>(std::forward<Arg>(arg).my_descriptors[n]);
93 template<
typename Arg>
100 static constexpr
auto get_constant(
const Xpr& arg)
106 static constexpr
auto get_constant_diagonal(
const Xpr& arg)
112 template<Applicability b>
113 static constexpr
bool one_dimensional = OpenKalman::one_dimensional<NestedObject, b>;
116 template<Applicability b>
117 static constexpr
bool is_square = square_shaped<NestedObject, b>;
120 template<TriangleType t>
121 static constexpr
bool is_triangular = triangular_matrix<NestedObject, t>;
124 static constexpr
bool is_triangular_adapter =
false;
127 static constexpr
bool is_hermitian = hermitian_matrix<NestedObject, Applicability::permitted>;
130 static constexpr
bool is_writable = writable<NestedObject>;
133 #ifdef __cpp_lib_concepts 134 template<
typename Arg> requires raw_data_defined_for<nested_object_of_t<Arg&&>>
136 template<typename Arg, std::enable_if_t<raw_data_defined_for<typename nested_object_of<Arg&&>::type>,
int> = 0>
138 static constexpr decltype(
auto)
145 static constexpr
Layout layout = layout_of_v<NestedObject>;
148 #ifdef __cpp_concepts 151 template<Layout l = layout,
typename Arg, std::enable_if_t<l == Layout::str
ide,
int> = 0>
156 return OpenKalman::internal::strides(
nested_object(std::forward<Arg>(arg)));
166 template<
typename Nested,
typename...Ds>
171 using NestedObject = std::decay_t<Nested>;
174 template<
typename T,
typename Arg>
175 static constexpr
auto 176 make_adapter(T&& t, Arg&& arg)
178 return std::apply([](
auto&& a,
auto&&...vs){
180 }, std::tuple_cat(std::forward_as_tuple(std::forward<Arg>(arg)), std::forward<T>(t).my_descriptors));
185 template<
typename Derived>
186 using LibraryBase = internal::library_base_t<Derived, NestedObject>;
188 #ifdef __cpp_lib_ranges 189 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>> and
190 interface::get_component_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const Indices&>
191 static constexpr values::scalar decltype(
auto)
193 template<
typename Arg,
typename Indices, std::enable_if_t<
194 interface::get_component_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const Indices&>,
int> = 0>
195 static constexpr decltype(
auto)
203 #ifdef __cpp_lib_ranges 204 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>> and
205 interface::set_component_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const scalar_type_of_t<Arg>&,
const Indices&>
207 template<
typename Arg,
typename Indices, std::enable_if_t<
208 interface::set_component_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const typename scalar_type_of<Arg>::type&,
const Indices&>,
int> = 0>
210 static constexpr
void 211 set_component(Arg& arg,
const scalar_type_of_t<Arg>& s,
const Indices& indices)
217 #ifdef __cpp_concepts 218 template<
typename Arg> requires interface::to_native_matrix_defined_for<NestedObject, nested_object_of_t<Arg&&>>
220 template<
typename Arg, std::enable_if_t<
interface::to_native_matrix_defined_for<NestedObject, nested_
object_of_t<Arg&&>>,
int> = 0>
222 static decltype(
auto)
229 #ifdef __cpp_concepts 230 template<
typename To,
typename From> requires
231 interface::assign_defined_for<NestedObject, nested_object_of_t<To&>, From&&>
233 template<
typename To,
typename From, std::enable_if_t<
234 interface::assign_defined_for<NestedObject, nested_object_of_t<To&>, From&&>,
int> = 0>
243 #ifdef __cpp_concepts 244 template<Layout layout,
typename Scalar,
typename D> requires
245 interface::make_default_defined_for<NestedObject, layout, Scalar, D&&>
247 template<
Layout layout,
typename Scalar,
typename D, std::enable_if_t<
248 interface::make_default_defined_for<NestedObject, layout, Scalar, D&&>,
int> = 0>
253 return NestedInterface::template make_default<layout, Scalar>(std::forward<D>(d));
257 #ifdef __cpp_concepts 258 template<
Layout layout,
typename Arg,
typename...Scalars> requires
259 interface::fill_components_defined_for<NestedObject, layout, nested_object_of_t<Arg&>, Scalars...>
261 template<
Layout layout,
typename Arg,
typename...Scalars, std::enable_if_t<
262 interface::fill_components_defined_for<NestedObject, layout, typename nested_object_of<Arg&>::type, Scalars...>,
int> = 0>
267 NestedInterface::template fill_components<layout>(
nested_object(arg), scalars...);
271 #ifdef __cpp_concepts 272 template<
typename C,
typename D> requires interface::make_constant_defined_for<NestedObject, C&&, D&&>
274 template<
typename C,
typename D, std::enable_if_t<
interface::make_constant_defined_for<NestedObject, C&&, D&&>,
int> = 0>
276 static constexpr
auto 283 #ifdef __cpp_concepts 284 template<
typename Scalar,
typename D> requires interface::make_identity_matrix_defined_for<NestedObject, Scalar, D&&>
286 template<
typename Scalar,
typename D, std::enable_if_t<
interface::make_
identity_matrix_defined_for<NestedObject, Scalar, D&&>,
int> = 0>
288 static constexpr
auto 289 make_identity_matrix(D&& d)
291 return NestedInterface::make_identity_matrix(std::forward<D>(d));
295 #ifdef __cpp_concepts 296 template<TriangleType t, indexible Arg> requires
297 interface::make_triangular_matrix_defined_for<NestedObject, t, nested_object_of_t<Arg&&>>
298 static constexpr triangular_matrix<t>
auto 300 template<
TriangleType t,
typename Arg, std::enable_if_t<
301 interface::make_triangular_matrix_defined_for<NestedObject, t, typename nested_object_of<Arg&&>::type>,
int> = 0>
302 static constexpr
auto 306 return make_adapter(std::forward<Arg>(arg), (NestedInterface::template make_triangular_matrix<t>(
nested_object(std::forward<Arg>(arg)))));
310 #ifdef __cpp_concepts 311 template<HermitianAdapterType t, indexible Arg> requires
312 interface::make_hermitian_adapter_defined_for<NestedObject, t, nested_object_of_t<Arg&&>>
316 make_hermitian_adapter_defined_for<NestedObject, t, typename nested_object_of<Arg&>::type>,
int> = 0>
317 static constexpr
auto 319 make_hermitian_adapter(Arg&& arg)
321 return make_adapter(std::forward<Arg>(arg), NestedInterface::template make_hermitian_adapter<t>(
nested_object(std::forward<Arg>(arg))));
326 template<
typename Arg,
typename BeginTup,
typename SizeTup, std::size_t...Ix>
327 static decltype(
auto)
328 get_slice_impl(Arg&& arg,
const BeginTup& begin_tup,
const SizeTup& size_tup, std::index_sequence<Ix...>)
336 #ifdef __cpp_concepts 337 template<
typename Arg,
typename...Begin,
typename...Size> requires
338 interface::get_slice_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const std::tuple<Begin...>&,
const std::tuple<Size...>&>
340 template<
typename Arg,
typename...Begin,
typename...Size, std::enable_if_t<
341 interface::get_slice_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const std::tuple<Begin...>&,
const std::tuple<Size...>&>,
int> = 0>
343 static decltype(
auto)
344 get_slice(Arg&& arg,
const std::tuple<Begin...>& begin_tup,
const std::tuple<Size...>& size_tup)
346 return get_slice_impl(std::forward<Arg>(arg), begin_tup, size_tup, std::index_sequence_for<Begin...>{});
350 #ifdef __cpp_concepts 351 template<
typename Arg,
typename Block,
typename...Begin> requires
352 interface::set_slice_defined_for<Arg, nested_object_of_t<Arg&>, Block&&,
const Begin&...>
354 template<
typename Arg,
typename Block,
typename...Begin, std::enable_if_t<
355 interface::set_slice_defined_for<Arg, typename nested_object_of<Arg&>::type, Block&&,
const Begin&...>,
int> = 0>
358 set_slice(Arg& arg, Block&& block,
const Begin&...begin)
364 #ifdef __cpp_concepts 365 template<TriangleType t,
typename A,
typename B> requires
366 interface::set_triangle_defined_for<NestedObject, t, nested_object_of_t<A&&>, B&&>
368 template<
TriangleType t,
typename A,
typename B, std::enable_if_t<
369 interface::set_triangle_defined_for<NestedObject, t, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
372 set_triangle(A&& a, B&& b)
374 NestedInterface::template set_triangle<t>(
nested_object(std::forward<A>(a)), std::forward<B>(b));
378 #ifdef __cpp_concepts 379 template<
typename Arg> requires
380 interface::to_diagonal_defined_for<NestedObject, nested_object_of_t<Arg&&>>
383 template<
typename Arg, std::enable_if_t<
384 interface::to_diagonal_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
385 static constexpr
auto 389 return std::apply([](
auto&& a,
auto&& v,
auto&&...vs){
391 std::forward<decltype(a)>(a),
392 std::forward<decltype(v)>(v),
393 std::forward<decltype(v)>(v),
394 std::forward<decltype(vs)>(vs)...);
397 std::forward<Arg>(arg).my_descriptors),
403 template<
typename Arg,
typename V0,
typename V1,
typename...Vs>
404 static constexpr decltype(
auto)
405 diagonal_of_impl(Arg&& arg, V0&& v0, V1&& v1,
const Vs&...vs)
407 auto d0 = internal::smallest_vector_space_descriptor<scalar_type_of_t<Arg>>(std::forward<V0>(v0), std::forward<V1>(v1));
413 #ifdef __cpp_concepts 414 template<indexible Arg> requires diagonal_adapter<NestedObject> or
415 (diagonal_adapter<NestedObject, 1> and
417 interface::diagonal_of_defined_for<NestedObject, nested_object_of_t<Arg&&>>
418 static constexpr
vector auto 420 template<
typename Arg, std::enable_if_t<diagonal_adapter<NestedObject> or
421 (diagonal_adapter<NestedObject, 1> and
422 interface::transpose_defined_for<NestedObject, decltype(nested_
object(nested_
object(std::declval<Arg>())))>) or
423 interface::diagonal_of_defined_for<NestedObject,
typename nested_
object_of<Arg&&>::type>,
int> = 0>
424 static constexpr
auto 428 if constexpr (diagonal_adapter<NestedObject>)
430 else if constexpr (diagonal_adapter<NestedObject, 1> and
440 template<std::
size_t Ix,
typename Arg,
typename Factors_tup>
441 static constexpr
auto broadcast_for_index(
const Arg& arg,
const Factors_tup& factors_tup)
443 constexpr
auto N = std::tuple_size_v<Factors_tup>;
444 if constexpr (Ix < N)
445 return get_vector_space_descriptor<Ix>(arg) * std::get<Ix>(factors_tup);
451 template<
typename Arg, std::size_t...Is,
typename Factors_tup>
452 static constexpr
auto broadcast_impl(Arg&& arg, std::index_sequence<Is...>,
const Factors_tup& factors_tup)
454 constexpr
auto N = std::tuple_size_v<Factors_tup>;
460 #ifdef __cpp_concepts 462 interface::broadcast_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const Factors&...>
465 template<
typename Arg,
typename...Factors, std::enable_if_t<
466 interface::broadcast_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const Factors&...>,
int> = 0>
469 broadcast(Arg&& arg,
const Factors&...factors)
472 using Ret = decltype(ret);
473 auto seq = std::make_index_sequence<std::max(index_count_v<Arg>,
sizeof...(factors))>{};
474 return broadcast_impl(std::forward<Ret>(ret), seq, std::forward_as_tuple(factors...));
478 #ifdef __cpp_concepts 479 template<coordinates::pattern...Vs,
typename Operation> requires
480 interface::n_ary_operation_defined_for<
NestedInterface,
const std::tuple<Vs...>&, Operation&&>
483 template<
typename...Vs,
typename Operation, std::enable_if_t<
484 interface::n_ary_operation_defined_for<NestedInterface,
const std::tuple<Vs...>&, Operation&&>,
int> = 0>
493 #ifdef __cpp_concepts 494 template<coordinates::pattern...Vs,
typename Operation,
indexible Arg,
indexible...Args> requires
495 interface::n_ary_operation_defined_for<NestedObject,
const std::tuple<Vs...>&, Operation&&,
nested_object_of_t<Arg&&>, Args...>
498 template<
typename...Vs,
typename Operation,
typename Arg,
typename...Args, std::enable_if_t<
499 interface::n_ary_operation_defined_for<NestedObject,
const std::tuple<Vs...>&, Operation&&,
typename nested_object_of<Arg&&>::type, Args...>,
int> = 0>
502 n_ary_operation(
const std::tuple<Vs...>& d_tup, Operation&& op, Arg&& arg, Args&&...args)
509 template<std::size_t...indices,
typename Arg,
typename...Vs, std::size_t...Ix>
510 static constexpr decltype(
auto)
511 reduce_impl(Arg&& arg,
const std::tuple<Vs...>& tup_vs, std::index_sequence<Ix...> seq)
514 ([]{ constexpr
auto I = Ix;
return ((I == indices) or ...); } ?
515 uniform_static_vector_space_descriptor_component_of_t<vector_space_descriptor_of_t<Vs, Ix>>{} :
516 std::get<Ix>(tup_vs))...);
521 #ifdef __cpp_concepts 522 template<std::size_t...indices,
typename BinaryFunction,
indexible Arg> requires
523 interface::reduce_defined_for<NestedObject, BinaryFunction&&, nested_object_of_t<Arg&&>, indices...>
525 template<std::size_t...indices,
typename BinaryFunction,
typename Arg, std::enable_if_t<
526 interface::reduce_defined_for<NestedObject, BinaryFunction&&, typename nested_object_of<Arg&&>::type, indices...>,
int> = 0>
528 static constexpr
auto 529 reduce(BinaryFunction&& op, Arg&& arg)
531 return reduce_impl<indices...>(
532 NestedInterface::template
reduce<indices...>(std::forward<BinaryFunction>(op),
nested_object(std::forward<Arg>(arg))),
533 std::forward<Arg>(arg).my_descriptors,
534 std::index_sequence_for<Ds...>{});
538 #ifdef __cpp_concepts 539 template<indexible Arg> requires
540 interface::to_euclidean_defined_for<NestedObject, Arg&&> or
541 interface::to_euclidean_defined_for<NestedObject, nested_object_of_t<Arg&&>>
544 template<
typename Arg, std::enable_if_t<
545 interface::to_euclidean_defined_for<NestedObject, Arg&&> or
546 interface::to_euclidean_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
547 static constexpr
auto 551 if constexpr (interface::to_euclidean_defined_for<NestedObject, Arg&&>)
558 #ifdef __cpp_concepts 559 template<indexible Arg, coordinates::pattern V> requires
560 interface::from_euclidean_defined_for<NestedObject, Arg&&, const V&> or
561 interface::from_euclidean_defined_for<NestedObject, nested_object_of_t<Arg&&>,
const V&>
564 template<
typename Arg,
typename V, std::enable_if_t<
565 interface::from_euclidean_defined_for<NestedObject, Arg&&, const V&> or
566 interface::from_euclidean_defined_for<NestedObject, typename nested_object_of<Arg&&>::type,
const V&>,
int> = 0>
567 static constexpr
auto 571 if constexpr (interface::from_euclidean_defined_for<NestedObject, Arg&&, const V&>)
578 #ifdef __cpp_concepts 579 template<indexible Arg> requires
580 interface::wrap_angles_defined_for<NestedObject, Arg&&> or
581 interface::wrap_angles_defined_for<NestedObject, nested_object_of_t<Arg&&>>
584 template<
typename Arg, std::enable_if_t<
585 interface::wrap_angles_defined_for<NestedObject, Arg&&> or
586 interface::wrap_angles_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
587 static constexpr
auto 589 wrap_angles(Arg&& arg)
591 if constexpr (interface::wrap_angles_defined_for<NestedObject, Arg&&>)
592 return NestedInterface::wrap_angles(std::forward<Arg>(arg));
594 return NestedInterface::wrap_angles(
nested_object(std::forward<Arg>(arg)));
598 #ifdef __cpp_concepts 599 template<indexible Arg> requires
600 interface::conjugate_defined_for<NestedObject, Arg&&> or
601 interface::conjugate_defined_for<NestedObject, nested_object_of_t<Arg&&>>
604 template<
typename Arg, std::enable_if_t<
605 interface::conjugate_defined_for<NestedObject, Arg&&> or
606 interface::conjugate_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
607 static constexpr
auto 611 if constexpr (interface::conjugate_defined_for<NestedObject, Arg&&>)
618 return internal::make_fixed_size_adapter_like<Arg>(std::forward<decltype(conj)>(
conj));
623 #ifdef __cpp_concepts 624 template<indexible Arg> requires
625 interface::transpose_defined_for<NestedObject, Arg&&> or
626 interface::transpose_defined_for<NestedObject, nested_object_of_t<Arg&&>>
629 template<
typename Arg, std::enable_if_t<
630 interface::transpose_defined_for<NestedObject, Arg&&> or
631 interface::transpose_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
632 static constexpr
auto 636 if constexpr (interface::transpose_defined_for<NestedObject, Arg&&>)
648 #ifdef __cpp_concepts 649 template<indexible Arg> requires
650 interface::adjoint_defined_for<NestedObject, Arg&&> or
651 interface::adjoint_defined_for<NestedObject, nested_object_of_t<Arg&&>>
654 template<
typename Arg, std::enable_if_t<
655 interface::adjoint_defined_for<NestedObject, Arg&&> or
656 interface::adjoint_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
657 static constexpr
auto 661 if constexpr (interface::adjoint_defined_for<NestedObject, Arg&&>)
673 #ifdef __cpp_concepts 674 template<indexible Arg> requires
675 interface::determinant_defined_for<NestedObject, Arg&&> or
676 interface::determinant_defined_for<NestedObject, nested_object_of_t<Arg&&>>
677 static constexpr std::convertible_to<scalar_type_of_t<Arg>>
auto 679 template<
typename Arg, std::enable_if_t<
680 interface::determinant_defined_for<NestedObject, Arg&&> or
681 interface::determinant_defined_for<NestedObject, typename nested_object_of<Arg&&>::type>,
int> = 0>
682 static constexpr
auto 686 if constexpr (interface::determinant_defined_for<NestedObject, Arg&&>)
697 #ifdef __cpp_concepts 698 template<
typename Arg,
typename...Args> requires
699 interface::sum_defined_for<NestedObject, Arg&&, Args&&...> or
700 interface::sum_defined_for<NestedObject, nested_object_of_t<Arg&&>, Args&&...>
702 template<
typename Arg,
typename...Args, std::enable_if_t<
703 interface::sum_defined_for<NestedObject, Arg&&, Args&&...> or
704 interface::sum_defined_for<NestedObject, typename nested_object_of<Arg&&>::type, Args&&...>,
int> = 0>
707 sum(Arg&& arg, Args&&...args)
709 if constexpr (interface::sum_defined_for<NestedObject, Arg&&, Args&&...>)
720 #ifdef __cpp_concepts 721 template<
typename A,
typename B> requires
722 interface::contract_defined_for<NestedObject, A&&, B&&> or
723 interface::contract_defined_for<NestedObject, nested_object_of_t<A&&>, B&&>
725 template<
typename A,
typename B, std::enable_if_t<
726 interface::contract_defined_for<NestedObject, A&&, B&&> or
727 interface::contract_defined_for<NestedObject, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
732 if constexpr (interface::contract_defined_for<NestedObject, A&&, B&&>)
744 #ifdef __cpp_concepts 745 template<
bool on_the_right,
typename A,
typename B> requires
746 interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&> or
747 interface::contract_in_place_defined_for<NestedObject, on_the_right, nested_object_of_t<A&&>, B&&>
749 template<
bool on_the_right,
typename A,
typename B, std::enable_if_t<
750 interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&> or
751 interface::contract_in_place_defined_for<NestedObject, on_the_right, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
753 static decltype(
auto)
756 if constexpr (interface::contract_in_place_defined_for<NestedObject, on_the_right, A&&, B&&>)
758 return NestedInterface::template contract_in_place<on_the_right>(std::forward<A>(a), std::forward<B>(b));
762 auto&& ret = NestedInterface::template contract_in_place<on_the_right>(
nested_object(std::forward<A>(a)), std::forward<B>(b));
763 using Ret = decltype(ret);
766 return std::forward<A>(a);
768 else if constexpr (on_the_right)
780 #ifdef __cpp_concepts 781 template<TriangleType triangle_type, indexible Arg> requires
782 interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&> or
783 interface::cholesky_factor_defined_for<NestedObject, triangle_type, nested_object_of_t<Arg&&>>
784 static constexpr triangular_matrix<triangle_type>
auto 786 template<
TriangleType triangle_type,
typename Arg, std::enable_if_t<
787 interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&> or
788 interface::cholesky_factor_defined_for<NestedObject, triangle_type, typename nested_object_of<Arg&&>::type>,
int> = 0>
789 static constexpr
auto 793 if constexpr (interface::cholesky_factor_defined_for<NestedObject, triangle_type, Arg&&>)
795 return NestedInterface::template cholesky_factor<triangle_type>(std::forward<Arg>(arg));
799 auto tri = NestedInterface::template cholesky_factor<triangle_type>(
nested_object(std::forward<Arg>(arg)));
800 return internal::make_fixed_square_adapter_like(std::move(tri));
805 #ifdef __cpp_concepts 806 template<HermitianAdapterType significant_triangle, indexible A, indexible U> requires
807 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&, const scalar_type_of_t<A>&> or
808 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, nested_object_of_t<A&&>, U&&,
const scalar_type_of_t<A>&>
812 interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&, const typename scalar_type_of<A>::type&> or
813 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>
814 static constexpr
auto 818 if constexpr (interface::rank_update_self_adjoint_defined_for<NestedObject, significant_triangle, A&&, U&&,
const scalar_type_of_t<A>&>)
820 return NestedInterface::template rank_update_hermitian<significant_triangle>(std::forward<A>(a), std::forward<U>(u), alpha);
824 auto tri = NestedInterface::template rank_update_hermitian<significant_triangle>(
nested_object(std::forward<A>(a), std::forward<U>(u), alpha));
825 return internal::make_fixed_square_adapter_like(std::move(tri));
830 #ifdef __cpp_concepts 831 template<TriangleType triangle_type, indexible A, indexible U> requires
832 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&, const scalar_type_of_t<A>&> or
833 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, nested_object_of_t<A&&>, U&&,
const scalar_type_of_t<A>&>
834 static constexpr triangular_matrix<triangle_type>
auto 836 template<
TriangleType triangle_type,
typename A,
typename U, std::enable_if_t<
837 interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&, const typename scalar_type_of<A>::type&> or
838 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>
839 static constexpr
auto 843 if constexpr (interface::rank_update_triangular_defined_for<NestedObject, triangle_type, A&&, U&&,
const scalar_type_of_t<A>&>)
845 return NestedInterface::template rank_update_triangular<triangle_type>(std::forward<A>(a), std::forward<U>(u), alpha);
849 auto tri = NestedInterface::template rank_update_triangular<triangle_type>(
nested_object(std::forward<A>(a), std::forward<U>(u), alpha));
850 return internal::make_fixed_square_adapter_like(std::move(tri));
855 #ifdef __cpp_concepts 856 template<
bool must_be_unique,
bool must_be_exact,
typename A,
typename B> requires
857 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&> or
858 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, nested_object_of_t<A&&>, B&&>
861 template<
bool must_be_unique,
bool must_be_exact,
typename A,
typename B, std::enable_if_t<
862 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&> or
863 interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, typename nested_object_of<A&&>::type, B&&>,
int> = 0>
868 if constexpr (interface::solve_defined_for<NestedObject, must_be_unique, must_be_exact, A&&, B&&>)
870 return NestedInterface::template solve<must_be_unique, must_be_exact>(std::forward<A>(a), std::forward<B>(b));
875 NestedInterface::template solve<must_be_unique, must_be_exact>(
nested_object(std::forward<A>(a)), std::forward<B>(b)));
880 #ifdef __cpp_concepts 881 template<
typename A> requires
882 interface::LQ_decomposition_defined_for<NestedObject, A&&> or
883 interface::LQ_decomposition_defined_for<NestedObject, nested_object_of_t<A&&>>
885 template<
typename A, std::enable_if_t<
886 interface::LQ_decomposition_defined_for<NestedObject, A&&> or
887 interface::LQ_decomposition_defined_for<NestedObject, typename nested_object_of<A&&>::type>,
int> = 0>
892 if constexpr (interface::LQ_decomposition_defined_for<NestedObject, A&&>)
900 return internal::make_fixed_square_adapter_like<D0>(std::forward<decltype(ret)>(ret));
905 #ifdef __cpp_concepts 906 template<
typename A> requires
907 interface::QR_decomposition_defined_for<NestedObject, A&&> or
908 interface::QR_decomposition_defined_for<NestedObject, nested_object_of_t<A&&>>
910 template<
typename A, std::enable_if_t<
911 interface::QR_decomposition_defined_for<NestedObject, A&&> or
912 interface::QR_decomposition_defined_for<NestedObject, typename nested_object_of<A&&>::type>,
int> = 0>
917 if constexpr (interface::QR_decomposition_defined_for<NestedObject, A&&>)
925 return internal::make_fixed_square_adapter_like<D1>(std::forward<decltype(ret)>(ret));
934 #endif //OPENKALMAN_INTERFACES_VECTORSPACEADAPTER_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
constexpr NestedObject & nested_object() &
Get the nested object.
Definition: AdapterBase.hpp:97
constexpr bool one_dimensional
Specifies that a type is one-dimensional in every index.
Definition: one_dimensional.hpp:83
An adapter that adds vector space descriptors for each index.
Definition: forward-class-declarations.hpp:301
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
auto make_vector_space_adapter(Arg &&arg, Descriptors &&descriptors)
If necessary, wrap an object in a wrapper that adds vector space descriptors for each index...
Definition: make_vector_space_adapter.hpp:37
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.
constexpr bool size
T is either an index representing a size, or void which represents that there is no size...
Definition: size.hpp:32
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
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
constexpr bool vector
T is a vector (e.g., column or row vector).
Definition: vector.hpp:67
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448
constexpr auto get_index_dimension_of(const T &t, N n=N{})
Get the runtime dimensions of index N of indexible T.
Definition: get_index_dimension_of.hpp:34
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