OpenKalman
LQ_decomposition.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2022-2023 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
16 #ifndef OPENKALMAN_LQ_DECOMPOSITION_HPP
17 #define OPENKALMAN_LQ_DECOMPOSITION_HPP
18 
19 namespace OpenKalman
20 {
26 #ifdef __cpp_concepts
27  template<indexible A> requires (not euclidean_transformed<A>)
28  constexpr triangular_matrix<TriangleType::lower> decltype(auto)
29 #else
30  template<typename A, std::enable_if_t<indexible<A> and (not euclidean_transformed<A>), int> = 0>
31  constexpr decltype(auto)
32 #endif
34  {
35  if constexpr (triangular_matrix<A, TriangleType::lower>)
36  {
37  return internal::clip_square_shaped(std::forward<A>(a));
38  }
39  else if constexpr (constant_matrix<A>)
40  {
41  using Scalar = scalar_type_of_t<A>;
42 
43  auto elem = constant_coefficient{a} * values::sqrt(values::cast_to<Scalar>(get_index_dimension_of<1>(a)));
44 
45  if constexpr (dynamic_dimension<A, 0>)
46  {
47  auto dim = coordinates::Dimensions {get_index_dimension_of<0>(a)};
48  auto col1 = make_constant<A>(elem, dim, coordinates::Axis{});
49 
50  auto m {make_dense_object<A>(dim, dim)};
51 
52  if (get_dimension(dim) == 1) m = std::move(col1);
53  else m = concatenate<1>(std::move(col1), make_zero<A>(dim, dim - coordinates::Axis{}));
54 
55  auto ret {make_triangular_matrix<TriangleType::lower>(std::move(m))};
56 
57  // \todo Fix this:
58  if constexpr (has_untyped_index<A, 0>) return ret;
59  else return SquareRootCovariance {std::move(ret), get_vector_space_descriptor<0>(a)};
60  }
61  else
62  {
63  auto ret = make_triangular_matrix<TriangleType::lower>([](Scalar elem){
64  constexpr auto dim = index_dimension_of_v<A, 0>;
65  auto col1 = make_constant<A>(elem, coordinates::Dimensions<dim>{}, coordinates::Axis{});
66  if constexpr (dim == 1) return col1;
67  else return concatenate<1>(std::move(col1), make_zero<A>(coordinates::Dimensions<dim>{}, coordinates::Dimensions<dim - 1>{}));
68  }(elem));
69 
70  // \todo Fix this:
72  if constexpr (coordinates::euclidean_pattern<C>) return ret;
73  else return SquareRootCovariance {std::move(ret), C{}};
74  }
75  }
76  else
77  {
78  decltype(auto) ret = [](A&& a) -> decltype(auto) {
79  if constexpr (interface::LQ_decomposition_defined_for<A, A&&>)
80  {
82  }
83  else
84  {
85  static_assert(interface::QR_decomposition_defined_for<A, A&&>,
86  "LQ_decomposition requires definition of at least one of interface::LQ_decomposition or interface::QR_decomposition");
87  return transpose(interface::library_interface<std::decay_t<A>>::QR_decomposition(transpose(std::forward<A>(a))));
88  }
89  }(std::forward<A>(a));
90  using Ret = decltype(ret);
91 
92  static_assert(triangular_matrix<Ret, TriangleType::lower>,
93  "Interface implementation error: interface::library_interface<T>::LQ_decomposition must return a lower triangular_matrix.");
94 
95  // \todo Fix this:
96  if constexpr (has_untyped_index<A, 0>) return ret;
97  else return SquareRootCovariance {std::forward<Ret>(ret), get_vector_space_descriptor<0>(a)};
98  }
99  }
100 
101 
102 } // namespace OpenKalman
103 
104 #endif //OPENKALMAN_LQ_DECOMPOSITION_HPP
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 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
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 upper or lower triangle Cholesky factor (square root) of a covariance matrix. ...
Definition: forward-class-declarations.hpp:559
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
constexpr auto sqrt(const Arg &arg)
A constexpr alternative to std::sqrt.
Definition: sqrt.hpp:46
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
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
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42