16 #ifndef OPENKALMAN_FROMEUCLIDEANEXPR_HPP 17 #define OPENKALMAN_FROMEUCLIDEANEXPR_HPP 19 #include "basics/traits/traits.hpp" 25 template<has_untyped_index<0> NestedObject, coordinates::pattern V0>
27 template<
typename NestedObject,
typename V0>
34 #ifndef __cpp_concepts 35 static_assert(indexible<NestedObject>);
36 static_assert(coordinates::pattern<V0>);
37 static_assert(has_untyped_index<NestedObject, 0>);
50 constexpr
FromEuclideanExpr() requires std::default_initializable<Base> and fixed_pattern<V0>
52 template<
typename B = Base, std::enable_if_t<std::is_default_constructible_v<B> and fixed_pattern<V0>,
int> = 0>
62 template<indexible Arg, coordinates::pattern D0> requires
63 std::constructible_from<NestedObject, Arg&&> and std::constructible_from<std::decay_t<V0>, D0>
65 template<
typename Arg,
typename D0, std::enable_if_t<indexible<Arg> and coordinates::pattern<C> and
66 std::is_constructible_v<NestedObject, Arg&&> and std::is_constructible_v<std::decay_t<V0>, D0>,
int> = 0>
68 explicit FromEuclideanExpr(Arg&& arg,
const D0& d0) :
Base {std::forward<Arg>(arg)}, vector_space_descriptor_index_0{d0} {}
75 template<indexible Arg> requires std::constructible_from<NestedObject, Arg&&> and fixed_index_descriptor<V0>
77 template<
typename Arg,
typename D0, std::enable_if_t<indexible<Arg> and
78 std::is_constructible_v<NestedObject, Arg&&> and fixed_index_descriptor<V0>,
int> = 0>
87 template<indexible Arg> requires (not std::is_base_of_v<
FromEuclideanExpr, std::decay_t<Arg>>) and
88 std::assignable_from<std::add_lvalue_reference_t<NestedObject>, decltype(
to_euclidean(std::declval<Arg&&>()))>
90 template<
typename Arg, std::enable_if_t<indexible<Arg> and (not std::is_base_of_v<ToEucl
ideanExpr, std::decay_t<Arg>>) and
91 std::is_assignable_v<std::add_lvalue_reference_t<NestedObject>, decltype(to_eucl
idean(std::declval<Arg&&>()))>,
int> = 0>
95 using TArg = decltype(
to_euclidean(std::declval<Arg>()));
96 if constexpr ((zero<NestedObject> and zero<TArg>) or (identity_matrix<NestedObject> and identity_matrix<TArg>))
107 std::decay_t<V0> vector_space_descriptor_index_0;
119 #ifdef __cpp_concepts 120 template<indexible Arg, coordinates::pattern V>
122 template<
typename Arg,
typename V, std::enable_if_t<indexible<Arg> and coordinates::pattern<V>,
int> = 0>
138 template<
typename NestedObject,
typename V0>
144 template<
typename Arg>
148 template<
typename Arg,
typename N>
149 static constexpr
auto 152 if constexpr (values::fixed<N>)
154 if constexpr (n == 0_uz)
return std::forward<Arg>(arg).vector_space_descriptor_index_0;
159 using Desc = DynamicDescriptor<scalar_type_of<Arg>>;
160 if (n == 0)
return Desc {std::forward<Arg>(arg).vector_space_descriptor_index_0};
166 template<
typename Arg>
167 static decltype(
auto)
174 template<
typename Arg>
175 static constexpr
auto 176 get_constant(
const Arg& arg)
178 if constexpr (coordinates::euclidean_pattern<V0>)
181 return std::monostate {};
185 template<
typename Arg>
186 static constexpr
auto 187 get_constant_diagonal(
const Arg& arg)
189 if constexpr (coordinates::euclidean_pattern<V0>)
192 return std::monostate {};
196 template<Applicability b>
197 static constexpr
bool 198 one_dimensional = coordinates::euclidean_pattern<V0> and OpenKalman::one_dimensional<NestedObject, b>;
201 template<Applicability b>
202 static constexpr
bool 203 is_square = coordinates::euclidean_pattern<V0> and square_shaped<NestedObject, b>;
206 template<TriangleType t>
207 static constexpr
bool 208 is_triangular = coordinates::euclidean_pattern<V0> and triangular_matrix<NestedObject, t>;
211 static constexpr
bool 212 is_triangular_adapter =
false;
215 static constexpr
bool 216 is_hermitian = coordinates::euclidean_pattern<V0> and hermitian_matrix<NestedObject>;
222 static constexpr
bool is_writable =
false;
225 #ifdef __cpp_lib_concepts 226 template<
typename Arg> requires coordinates::euclidean_pattern<V0> and raw_data_defined_for<nested_object_of_t<Arg&>>
228 template<
typename Arg, std::enable_if_t<coordinates::eucl
idean_pattern<V0> and raw_data_defined_for<
typename nested_
object_of<Arg&>::type>,
int> = 0>
230 static constexpr
auto *
const 238 layout = coordinates::euclidean_pattern<V0> ? layout_of_v<NestedObject> :
Layout::none;
241 #ifdef __cpp_concepts 242 template<
typename Arg> requires (layout !=
Layout::none)
244 template<Layout l = layout,
typename Arg, std::enable_if_t<l != Layout::none,
int> = 0>
259 template<
typename NestedObject,
typename V0>
268 template<
typename Derived>
269 using LibraryBase = internal::library_base_t<Derived, pattern_matrix_of_t<T>>;
272 #ifdef __cpp_lib_ranges 273 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>>
274 static constexpr values::scalar decltype(
auto)
276 template<
typename Arg,
typename Indices>
277 static constexpr decltype(
auto)
281 if constexpr (coordinates::euclidean_pattern<V0>)
289 return coordinates::get_wrapped_component(get_vector_space_descriptor<0>(arg), g, i);
291 return coordinates::from_stat_space(get_vector_space_descriptor<0>(arg), g, i);
296 #ifdef __cpp_lib_ranges 297 template<indexible Arg, std::ranges::input_range Indices> requires values::index<std::ranges::range_value_t<Indices>>
299 template<
typename Arg,
typename Indices>
313 auto g {[&arg, is...](std::size_t ix) {
316 coordinates::set_wrapped_component(get_vector_space_descriptor<0>(arg), s, g, s, i);
325 template<
typename Arg>
328 return OpenKalman::to_native_matrix<nested_object_of_t<Arg>>(std::forward<Arg>(arg));
332 template<Layout layout,
typename Scalar,
typename D>
333 static auto make_default(D&& d)
335 return make_dense_object<NestedObject, layout, Scalar>(std::forward<D>(d));
342 template<
typename C,
typename D>
345 return make_constant<NestedObject>(std::forward<C>(c), std::forward<D>(d));
349 template<
typename Scalar,
typename D>
350 static constexpr
auto make_identity_matrix(D&& d)
352 return make_identity_matrix_like<NestedObject, Scalar>(std::forward<D>(d));
362 template<
typename Arg>
366 if constexpr( has_untyped_index<Arg, 0>)
377 template<
typename Arg>
381 if constexpr(has_untyped_index<Arg, 0>)
392 template<
typename Arg,
typename...Factors>
394 broadcast(Arg&& arg,
const Factors&...factors)
400 template<
typename...Ds,
typename Operation,
typename...Args>
401 static constexpr decltype(
auto)
402 n_ary_operation(
const std::tuple<Ds...>& tup, Operation&& op, Args&&...args)
408 template<std::size_t...indices,
typename BinaryFunction,
typename Arg>
409 static constexpr decltype(
auto)
410 reduce(BinaryFunction&& b, Arg&& arg)
416 template<
typename Arg>
417 constexpr decltype(
auto)
427 template<
typename Arg>
428 constexpr decltype(
auto)
429 wrap_angles(Arg&& arg)
431 return std::forward<Arg>(arg);
435 template<
typename Arg>
436 static constexpr decltype(
auto)
439 if constexpr(has_untyped_index<Arg, 0>)
445 return std::forward<Arg>(arg).
conjugate();
450 template<
typename Arg>
451 static constexpr decltype(
auto)
454 if constexpr(has_untyped_index<Arg, 0>)
460 return std::forward<Arg>(arg).
transpose();
465 template<
typename Arg>
466 static constexpr decltype(
auto)
469 if constexpr(has_untyped_index<Arg, 0>)
475 return std::forward<Arg>(arg).
adjoint();
480 template<
typename Arg>
481 static constexpr
auto 484 if constexpr(has_untyped_index<Arg, 0>)
490 return arg.determinant();
495 template<HermitianAdapterType significant_triangle,
typename A,
typename U,
typename Alpha>
496 static decltype(
auto)
503 template<TriangleType triangle,
typename A,
typename U,
typename Alpha>
510 template<
bool must_be_unique,
bool must_be_exact,
typename A,
typename B>
511 static constexpr decltype(
auto)
514 return OpenKalman::solve<must_be_unique, must_be_exact>(
515 to_native_matrix<T>(std::forward<A>(a)), std::forward<B>(b));
543 #endif //OPENKALMAN_FROMEUCLIDEANEXPR_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
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
constexpr FromEuclideanExpr()
Default constructor.
Definition: FromEuclideanExpr.hpp:53
Definition: indexible_object_traits.hpp:36
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
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
constexpr bool to_euclidean_expr
Specifies that T is an expression converting coefficients to Euclidean space (i.e., ToEuclideanExpr).
Definition: forward-class-declarations.hpp:404
An expression that transforms angular or other modular vector space descriptors back from Euclidean s...
Definition: FromEuclideanExpr.hpp:29
No storage layout (e.g., if the elements are calculated rather than stored).
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
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
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
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
decltype(auto) constexpr to_dense_object(Arg &&arg)
Convert the argument to a dense, writable matrix of a particular scalar type.
Definition: to_dense_object.hpp:37
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
Definition: AdapterBase.hpp:36
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
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
The root namespace for OpenKalman.
Definition: basics.hpp:34
FromEuclideanExpr(Arg &&arg)
Construct from a compatible indexible object if the coordinate_list of index 0 is fixed...
Definition: FromEuclideanExpr.hpp:80
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
FromEuclideanExpr(Arg &&arg, const D0 &d0)
Construct from a compatible indexible object.
Definition: FromEuclideanExpr.hpp:68
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 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
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
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
auto & operator=(Arg &&arg)
Assign from a compatible indexible object.
Definition: FromEuclideanExpr.hpp:93
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
constexpr auto make_constant(C &&c, Descriptors &&descriptors)
Make a constant object based on a particular library object.
Definition: make_constant.hpp:37
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 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