OpenKalman
transpose.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_TRANSPOSE_HPP
17 #define OPENKALMAN_TRANSPOSE_HPP
18 
19 #include<complex>
20 
21 
22 namespace OpenKalman
23 {
24  namespace internal
25  {
26  template<typename C, typename Arg, std::size_t...Is>
27  constexpr decltype(auto) transpose_constant(C&& c, Arg&& arg, std::index_sequence<Is...>)
28  {
29  return make_constant<Arg>(std::forward<C>(c),
30  get_vector_space_descriptor<1>(arg), get_vector_space_descriptor<0>(arg), get_vector_space_descriptor<Is + 2>(arg)...);
31  }
32  } // namespace internal
33 
34 
35 #ifndef __cpp_concepts
36  namespace detail
37  {
38  template<typename T, typename Arg, typename = void>
39  struct constant_transpose_defined_for: std::false_type {};
40 
41  template<typename T, typename Arg>
42  struct constant_transpose_defined_for<T, Arg, std::enable_if_t<
43  constant_matrix<decltype(interface::library_interface<T>::transpose(std::declval<Arg>()))>>>
44  : std::true_type {};
45  } // namespace detail
46 #endif
47 
48 
53 #ifdef __cpp_concepts
54  template<indexible Arg> requires (max_tensor_order_v<Arg> <= 2)
55 #else
56  template<typename Arg, std::enable_if_t<indexible<Arg> and (max_tensor_order_v<Arg> <= 2), int> = 0>
57 #endif
58  constexpr decltype(auto) transpose(Arg&& arg)
59  {
60  if constexpr (((diagonal_matrix<Arg> or constant_matrix<Arg>) and square_shaped<Arg>) or
61  (hermitian_matrix<Arg> and not values::complex<scalar_type_of_t<Arg>>))
62  {
63  return std::forward<Arg>(arg);
64  }
65  else if constexpr (hermitian_matrix<Arg>)
66  {
67  return conjugate(std::forward<Arg>(arg));
68  }
69 #ifdef __cpp_concepts
70  else if constexpr (constant_matrix<Arg> and
71  not requires { {interface::library_interface<std::decay_t<Arg>>::transpose(std::forward<Arg>(arg))} -> constant_matrix; })
72 #else
73  else if constexpr (constant_matrix<Arg> and not detail::constant_transpose_defined_for<Arg, Arg>::value)
74 #endif
75  {
76  constexpr std::make_index_sequence<std::max({index_count_v<Arg>, 2_uz}) - 2_uz> seq;
77  return internal::transpose_constant(constant_coefficient{arg}, std::forward<Arg>(arg), seq);
78  }
79  else
80  {
81  return interface::library_interface<std::decay_t<Arg>>::transpose(std::forward<Arg>(arg));
82  }
83  }
84 
85 
86 } // namespace OpenKalman
87 
88 #endif //OPENKALMAN_TRANSPOSE_HPP
constexpr bool constant_matrix
Specifies that all components of an object are the same constant value.
Definition: constant_matrix.hpp:31
Definition: tuple_reverse.hpp:103
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
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37