16 #ifndef OPENKALMAN_RANK_UPDATE_TRIANGULAR_HPP 17 #define OPENKALMAN_RANK_UPDATE_TRIANGULAR_HPP 35 # ifdef __cpp_concepts 36 template<triangular_matrix<TriangleType::any> A, indexible U> requires
39 std::convertible_to<scalar_type_of_t<U>,
const scalar_type_of_t<A>>
42 template<
typename A,
typename U, std::enable_if_t<triangular_matrix<A, TriangleType::any> and indexible<U> and
43 dimension_size_of_index_is<U, 0, index_dimension_of<A, 0>::value, Applicability::permitted> and
44 dimension_size_of_index_is<U, 0, index_dimension_of<A, 1>::value, Applicability::permitted> and
45 std::is_convertible_v<scalar_type_of_t<U>, const scalar_type_of_t<A>>,
int> = 0>
52 if constexpr (zero<U>)
54 if constexpr (dynamic_dimension<A, 0> or dynamic_dimension<U, 0>)
if (get_index_dimension_of<0>(a) != get_index_dimension_of<0>(u))
55 throw std::invalid_argument {
"In rank_update_triangular, rows of a (" + std::to_string(get_index_dimension_of<0>(a)) +
56 ") do not match rows of u (" + std::to_string(get_index_dimension_of<0>(u)) +
")"};
58 return make_triangular_matrix<t>(std::forward<A>(a));
60 else if constexpr (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>)
62 if constexpr (dynamic_dimension<A, 0> or dynamic_dimension<U, 0>)
if (get_index_dimension_of<0>(a) != get_index_dimension_of<0>(u))
63 throw std::invalid_argument {
"In rank_update_triangular, rows of a (" + std::to_string(get_index_dimension_of<0>(a)) +
64 ") do not match rows of u (" + std::to_string(get_index_dimension_of<0>(u)) +
")"};
68 auto e = [](
auto ax,
const auto& uterm) {
71 }(internal::get_singular_component(a), alpha * internal::get_singular_component(
contract(u,
adjoint(u))));
73 if constexpr (writable_by_component<A&&>)
76 return make_triangular_matrix<t>(std::forward<A>(a));
81 if constexpr (std::is_assignable_v<A, decltype(std::move(ret))>)
84 return make_triangular_matrix<t>(std::forward<A>(a));
89 else if constexpr (zero<A>)
91 if constexpr (diagonal_matrix<U>)
98 else if constexpr (diagonal_matrix<A> and diagonal_matrix<U>)
101 if constexpr (std::is_assignable_v<A, decltype(std::move(d))>)
return a = std::move(d);
106 auto&& an = [](A&& a) -> decltype(
auto) {
107 if constexpr (triangular_adapter<A>)
return nested_object(std::forward<A>(a));
108 else return std::forward<A>(a);
109 }(std::forward<A>(a));
111 auto&& aw = internal::make_writable_square_matrix<U>(std::forward<decltype(an)>(an));
113 auto&& ret = Trait::template rank_update_triangular<t>(std::forward<decltype(aw)>(aw), std::forward<U>(u), alpha);
114 return make_triangular_matrix<t>(std::forward<decltype(ret)>(ret));
121 #endif //OPENKALMAN_RANK_UPDATE_TRIANGULAR_HPP decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
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
constexpr bool complex
T is a values::value that reduces to std::complex or a custom complex type.
Definition: complex.hpp:46
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
An upper-right triangular matrix.
decltype(auto) constexpr cholesky_square(A &&a)
Take the Cholesky square of a triangular_matrix.
Definition: cholesky_square.hpp:33
Type scalar type (e.g., std::float, std::double, std::complex<double>) of a tensor.
Definition: scalar_type_of.hpp:32
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...
constexpr auto conj(const Arg &arg)
A constexpr function for the complex conjugate of a (complex) number.
Definition: conj.hpp:39
constexpr auto sqrt(const Arg &arg)
A constexpr alternative to std::sqrt.
Definition: sqrt.hpp:46
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 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 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
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.
decltype(auto) constexpr cholesky_factor(A &&a)
Take the Cholesky factor of a matrix.
Definition: cholesky_factor.hpp:38