16 #ifndef OPENKALMAN_RANK_UPDATE_HERMITIAN_HPP 17 #define OPENKALMAN_RANK_UPDATE_HERMITIAN_HPP 33 template<hermitian_matrix<Applicability::permitted> A, indexible U> requires
36 std::convertible_to<scalar_type_of_t<U>,
const scalar_type_of_t<A>>
39 template<
typename A,
typename U, std::enable_if_t<indexible<U> and hermitian_matrix<A, Applicability::permitted> and
40 dimension_size_of_index_is<U, 0, index_dimension_of<A, 0>::value, Applicability::permitted> and
41 dimension_size_of_index_is<U, 0, index_dimension_of<A, 1>::value, Applicability::permitted> and
42 std::is_convertible_v<
typename scalar_type_of<U>::type, const
typename scalar_type_of<A>::type>,
int> = 0>
49 if constexpr (zero<U> or dimension_size_of_index_is<A, 0, 1> or dimension_size_of_index_is<A, 1, 1> or dimension_size_of_index_is<U, 0, 1>)
51 if constexpr ((dynamic_dimension<A, 0> and dynamic_dimension<A, 1>) or dynamic_dimension<U, 0>)
52 if (get_index_dimension_of<0>(a) != get_index_dimension_of<0>(u))
53 throw std::invalid_argument {
"In rank_update_hermitian, rows of a (" + std::to_string(get_index_dimension_of<0>(a)) +
54 ") do not match rows of u (" + std::to_string(get_index_dimension_of<0>(u)) +
")"};
56 if constexpr (zero<U>)
58 return make_hermitian_matrix<t>(std::forward<A>(a));
62 auto e = internal::get_singular_component(a) + alpha * internal::get_singular_component(
contract(u,
adjoint(u)));
64 if constexpr (writable_by_component<A&&>)
67 return make_hermitian_matrix<t>(std::forward<A>(a));
71 auto ret {make_dense_object_from<A>(std::tuple{}, e)};
72 if constexpr (std::is_assignable_v<A, decltype(std::move(ret))>)
75 return make_hermitian_matrix<t>(std::forward<A>(a));
81 else if constexpr (zero<A> and diagonal_matrix<U>)
83 if constexpr (has_dynamic_dimensions<A>)
if (get_index_dimension_of<0>(a) != get_index_dimension_of<1>(a))
84 throw std::invalid_argument {
85 "In rank_update_hermitian, rows of a (" + std::to_string(get_index_dimension_of<0>(a)) +
86 ") do not match columns of a (" + std::to_string(get_index_dimension_of<1>(a)) +
")"};
90 else if constexpr (diagonal_matrix<A> and diagonal_matrix<U>)
93 if constexpr (std::is_assignable_v<A, decltype(std::move(d))>)
return a = std::move(d);
96 else if constexpr (hermitian_adapter<A>)
98 auto&& aw = internal::make_writable_square_matrix<U>(
nested_object(std::forward<A>(a)));
100 auto&& ret = Trait::template rank_update_hermitian<t>(std::forward<decltype(aw)>(aw), std::forward<U>(u), alpha);
101 return make_hermitian_matrix<t>(std::forward<decltype(ret)>(ret));
105 auto&& aw = internal::make_writable_square_matrix<U>(std::forward<A>(a));
107 auto&& ret = Trait::template rank_update_hermitian<t>(std::forward<decltype(aw)>(aw), std::forward<U>(u), alpha);
108 return make_hermitian_matrix<t>(std::forward<decltype(ret)>(ret));
115 #endif //OPENKALMAN_RANK_UPDATE_HERMITIAN_HPP decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
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
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
typename scalar_type_of< T >::type scalar_type_of_t
helper template for scalar_type_of.
Definition: scalar_type_of.hpp:54
decltype(auto) constexpr cholesky_square(A &&a)
Take the Cholesky square of a triangular_matrix.
Definition: cholesky_square.hpp:33
The root namespace for OpenKalman.
Definition: basics.hpp:34
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37
The concept, trait, or restraint is permitted, but whether it applies is not necessarily known at com...
decltype(auto) constexpr adjoint(Arg &&arg)
Take the adjoint of a matrix.
Definition: adjoint.hpp:33
decltype(auto) constexpr sum(Ts &&...ts)
Element-by-element sum of one or more objects.
Definition: sum.hpp:112
decltype(auto) constexpr nested_object(Arg &&arg)
Retrieve a nested object of Arg, if it exists.
Definition: nested_object.hpp:34
A lower-left triangular matrix.
constexpr bool hermitian_matrix
Specifies that a type is a hermitian matrix (assuming it is square_shaped).
Definition: hermitian_matrix.hpp:50