OpenKalman
contract_in_place.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_CONTRACT_IN_PLACE_HPP
17 #define OPENKALMAN_CONTRACT_IN_PLACE_HPP
18 
19 
20 namespace OpenKalman
21 {
27 #ifdef __cpp_concepts
28  template<bool on_the_right = true, square_shaped<Applicability::permitted> A, square_shaped<Applicability::permitted> B> requires
29  vector_space_descriptors_may_match_with<A, B> and (not triangular_matrix<A> or triangle_type_of_v<A> == triangle_type_of_v<A, B>) and
30  (index_count_v<A> == dynamic_size or index_count_v<A> <= 2) and (index_count_v<B> == dynamic_size or index_count_v<B> <= 2)
31 #else
32  template<bool on_the_right = true, typename A, typename B, std::enable_if_t<
33  square_shaped<A, Applicability::permitted> and square_shaped<B, Applicability::permitted> and
34  vector_space_descriptors_may_match_with<A, B> and (not triangular_matrix<A> or triangle_type_of<A>::value == triangle_type_of<A, B>::value) and
35  (index_count<A>::value == dynamic_size or index_count<A>::value <= 2) and (index_count<B>::value == dynamic_size or index_count<B>::value <= 2), int> = 0>
36 #endif
37  constexpr A&&
38  contract_in_place(A&& a, B&& b)
39  {
40  if constexpr (not square_shaped<A> or not square_shaped<B> or not vector_space_descriptors_match_with<A, B>) if (not vector_space_descriptors_match(a, b))
41  throw std::invalid_argument {"Arguments to contract_in_place must match in size and be square matrices"};
42 
43  if constexpr (zero<A> or identity_matrix<B>)
44  {
45  ;
46  }
47  else if constexpr (zero<B> and writable<A>)
48  {
49  assign(a, std::forward<B>(b));
50  }
51  else if constexpr (interface::contract_in_place_defined_for<A, on_the_right, A&, B&&>)
52  {
53  return interface::library_interface<std::decay_t<A>>::template contract_in_place<on_the_right>(a, std::forward<B>(b));
54  }
55  else
56  {
57  assign(a, to_dense_object(contract(a, std::forward<B>(b))));
58  }
59  return std::forward<A>(a);
60  }
61 
62 
63 } // namespace OpenKalman
64 
65 
66 #endif //OPENKALMAN_CONTRACT_IN_PLACE_HPP
decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
decltype(auto) constexpr to_dense_object(Arg &&arg)
Convert the argument to a dense, writable matrix of a particular scalar type.
Definition: to_dense_object.hpp:37
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 bool vector_space_descriptors_match(const Ts &...ts)
Return true if every set of coordinates::pattern of a set of objects match.
Definition: vector_space_descriptors_match.hpp:62
constexpr A && contract_in_place(A &&a, B &&b)
In-place matrix multiplication of A * B, storing the result in A.
Definition: contract_in_place.hpp:38
constexpr To && assign(To &&a, From &&b)
Assign a writable object from an indexible object.
Definition: assign.hpp:51
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33