OpenKalman
cholesky_square.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) 2019-2024 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_CHOLESKY_SQUARE_HPP
17 #define OPENKALMAN_CHOLESKY_SQUARE_HPP
18 
19 namespace OpenKalman
20 {
26 #ifdef __cpp_concepts
27  template<triangular_matrix A> requires square_shaped<A, Applicability::permitted>
28  constexpr hermitian_matrix decltype(auto)
29 #else
30  template<typename A, std::enable_if_t<triangular_matrix<A> and square_shaped<A, Applicability::permitted>, int> = 0>
31  constexpr decltype(auto)
32 #endif
34  {
35  if constexpr (not square_shaped<A>)
36  if (not is_square_shaped(a)) throw std::invalid_argument {"Argument to cholesky_square must be a square matrix"};
37 
38  if constexpr (zero<A> or identity_matrix<A>)
39  {
40  return std::forward<A>(a);
41  }
42  else if constexpr (diagonal_matrix<A>)
43  {
44  return to_diagonal(n_ary_operation([](const auto x){
45  if constexpr (values::complex<scalar_type_of_t<A>>) return x * values::conj(x);
46  else return x * x;
47  }, diagonal_of(std::forward<A>(a))));
48  }
49  else if constexpr (triangular_matrix<A, TriangleType::upper>)
50  {
51  return make_hermitian_matrix<HermitianAdapterType::upper>(contract(adjoint(a), a));
52  }
53  else
54  {
55  return make_hermitian_matrix<HermitianAdapterType::lower>(contract(a, adjoint(a)));
56  }
57  }
58 
59 
60 } // namespace OpenKalman
61 
62 
63 #endif //OPENKALMAN_CHOLESKY_SQUARE_HPP
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
decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
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
constexpr auto is_square_shaped(const T &t)
Determine whether an object is square_shaped at runtime.
Definition: is_square_shaped.hpp:63
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
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
constexpr auto conj(const Arg &arg)
A constexpr function for the complex conjugate of a (complex) number.
Definition: conj.hpp:39
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
constexpr bool hermitian_matrix
Specifies that a type is a hermitian matrix (assuming it is square_shaped).
Definition: hermitian_matrix.hpp:50