OpenKalman
library-interfaces-defined.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) 2023-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_LIBRARY_INTERFACES_DEFINED_HPP
17 #define OPENKALMAN_LIBRARY_INTERFACES_DEFINED_HPP
18 
19 #include <type_traits>
20 #include <utility>
23 
24 namespace OpenKalman::interface
25 {
26  // ------------- //
27  // LibraryBase //
28  // ------------- //
29 
30 #if defined(__cpp_concepts) and OPENKALMAN_CPP_FEATURE_CONCEPTS
31  template<typename Derived, typename LibraryObject>
32  concept LibraryBase_defined_for = requires {
33  typename library_interface<std::decay_t<LibraryObject>>::template LibraryBase<std::decay_t<Derived>>;
34  };
35 #else
36  namespace detail
37  {
38  template<typename Derived, typename LibraryObject, typename = void>
39  struct LibraryBase_defined_for_impl : std::false_type {};
40 
41  template<typename Derived, typename LibraryObject>
42  struct LibraryBase_defined_for_impl<Derived, LibraryObject,
43  std::void_t<typename library_interface<std::decay_t<LibraryObject>>::template LibraryBase<std::decay_t<Derived>>>>
44  : std::true_type {};
45  }
46 
47  template<typename Derived, typename LibraryObject>
48  constexpr bool LibraryBase_defined_for = detail::LibraryBase_defined_for_impl<Derived, LibraryObject>::value;
49 #endif
50 
51 
52  // --------------- //
53  // get_component //
54  // --------------- //
55 
56 #ifdef __cpp_concepts
57  template<typename T, typename Arg, typename Indices>
58  concept get_component_defined_for = requires (Arg arg, Indices indices) {
59  library_interface<std::decay_t<T>>::get_component(std::forward<Arg>(arg), std::forward<Indices>(indices));
60  };
61 #else
62  namespace detail
63  {
64  template<typename T, typename Arg, typename Indices, typename = void>
65  struct get_component_defined_for_impl: std::false_type {};
66 
67  template<typename T, typename Arg, typename Indices>
68  struct get_component_defined_for_impl<T, Arg, Indices, std::void_t<
69  decltype(library_interface<std::decay_t<T>>::get_component(std::declval<Arg>(), std::declval<Indices>()))>>
70  : std::true_type {};
71  }
72 
73  template<typename T, typename Arg, typename Indices>
74  constexpr bool get_component_defined_for = detail::get_component_defined_for_impl<T, Arg, Indices>::value;
75 #endif
76 
77 
78  // --------------- //
79  // set_component //
80  // --------------- //
81 
82 #ifdef __cpp_concepts
83  template<typename T, typename Arg, typename Scalar, typename Indices>
84  concept set_component_defined_for = requires (Arg arg, Scalar scalar, Indices indices) {
85  library_interface<std::decay_t<T>>::set_component(std::forward<Arg>(arg), std::forward<Scalar>(scalar), std::forward<Indices>(indices));
86  };
87 #else
88  namespace detail
89  {
90  template<typename T, typename Arg, typename Scalar, typename Indices, typename = void>
91  struct set_component_defined_for_impl: std::false_type {};
92 
93  template<typename T, typename Arg, typename Scalar, typename Indices>
94  struct set_component_defined_for_impl<T, Arg, Scalar, Indices, std::void_t<
95  decltype(library_interface<std::decay_t<T>>::set_component(std::declval<Arg>(), std::declval<Scalar>(), std::declval<Indices>()))>>
96  : std::true_type {};
97  }
98 
99  template<typename T, typename Arg, typename Scalar, typename Indices>
100  constexpr bool set_component_defined_for = detail::set_component_defined_for_impl<T, Arg, Scalar, Indices>::value;
101 #endif
102 
103 
104  // ------------------ //
105  // to_native_matrix //
106  // ------------------ //
107 
108 #ifdef __cpp_concepts
109  template<typename T, typename Arg>
110  concept to_native_matrix_defined_for = requires (Arg arg) {
112  };
113 #else
114  namespace detail
115  {
116  template<typename T, typename Arg, typename = void>
117  struct to_native_matrix_defined_for_impl: std::false_type {};
118 
119  template<typename T, typename Arg>
120  struct to_native_matrix_defined_for_impl<T, Arg, std::void_t<
121  decltype(library_interface<std::decay_t<T>>::to_native_matrix(std::declval<Arg>()))>>
122  : std::true_type {};
123  }
124 
125  template<typename T, typename Arg>
126  constexpr bool to_native_matrix_defined_for = detail::to_native_matrix_defined_for_impl<T, Arg>::value;
127 #endif
128 
129 
130  // -------- //
131  // assign //
132  // -------- //
133 
134 #ifdef __cpp_concepts
135  template<typename T, typename To, typename From>
136  concept assign_defined_for = requires(To a, From b) {
137  library_interface<std::decay_t<T>>::assign(std::forward<To>(a), std::forward<From>(b));
138  };
139 #else
140  namespace detail
141  {
142  template<typename T, typename To, typename From, typename = void>
143  struct assign_defined_for_impl : std::false_type {};
144 
145  template<typename T, typename To, typename From>
146  struct assign_defined_for_impl<T, To, From, std::void_t<decltype(
147  library_interface<std::decay_t<T>>::assign(std::declval<To>(), std::declval<From>()))>>
148  : std::true_type {};
149  }
150 
151  template<typename T, typename To, typename From>
152  constexpr bool assign_defined_for = detail::assign_defined_for_impl<T, To, From>::value;
153 #endif
154 
155 
156  // -------------- //
157  // make_default //
158  // -------------- //
159 
160 #ifdef __cpp_concepts
161  template<typename T, Layout layout, typename Scalar, typename D>
162  concept make_default_defined_for = requires(D d) {
163  library_interface<std::decay_t<T>>::template make_default<layout, Scalar>(std::forward<D>(d));
164  };
165 #else
166  namespace detail
167  {
168  template<typename T, Layout layout, typename Scalar, typename D, typename = void>
169  struct make_default_defined_for_impl : std::false_type {};
170 
171  template<typename T, Layout layout, typename Scalar, typename D>
172  struct make_default_defined_for_impl<T, layout, Scalar, D, std::void_t<decltype(
173  library_interface<std::decay_t<T>>::template make_default<layout, Scalar>(std::declval<D>()...))>>
174  : std::true_type {};
175  }
176 
177  template<typename T, Layout layout, typename Scalar, typename D>
178  constexpr bool make_default_defined_for = detail::make_default_defined_for_impl<T, layout, Scalar, D>::value;
179 #endif
180 
181 
182  // ----------------- //
183  // fill_components //
184  // ----------------- //
185 
186 #ifdef __cpp_concepts
187  template<typename T, Layout layout, typename Arg, typename...Scalars>
188  concept fill_components_defined_for = requires(Arg arg, Scalars...scalars) {
189  library_interface<std::decay_t<T>>::template fill_components<layout>(std::forward<Arg>(arg), std::forward<Scalars>(scalars)...);
190  };
191 #else
192  namespace detail
193  {
194  template<typename T, Layout layout, typename Arg, typename = void, typename...Scalars>
195  struct fill_components_defined_for_impl : std::false_type {};
196 
197  template<typename T, Layout layout, typename Arg, typename...Scalars>
198  struct fill_components_defined_for_impl<T, layout, Arg, std::void_t<decltype(
199  library_interface<std::decay_t<T>>::template fill_components<layout>(std::declval<Arg>(), std::declval<Scalars>()...))>, Scalars...>
200  : std::true_type {};
201  }
202 
203  template<typename T, Layout layout, typename Arg, typename...Scalars>
204  constexpr bool fill_components_defined_for = detail::fill_components_defined_for_impl<T, layout, Arg, void, Scalars...>::value;
205 #endif
206 
207 
208  // --------------- //
209  // make_constant //
210  // --------------- //
211 
212 #ifdef __cpp_concepts
213  template<typename T, typename C, typename Ds>
214  concept make_constant_defined_for = requires (C c, Ds ds) {
215  library_interface<std::decay_t<T>>::make_constant(std::forward<C>(c), std::forward<Ds>(ds));
216  };
217 #else
218  namespace detail
219  {
220  template<typename T, typename C, typename Ds, typename = void>
221  struct make_constant_matrix_defined_for_impl: std::false_type {};
222 
223  template<typename T, typename C, typename Ds>
224  struct make_constant_matrix_defined_for_impl<T, C, Ds, std::void_t<
225  decltype(library_interface<std::decay_t<T>>::make_constant(std::declval<C>(), std::declval<Ds>()))>>
226  : std::true_type {};
227  }
228 
229  template<typename T, typename C, typename Ds>
230  constexpr bool make_constant_defined_for = detail::make_constant_matrix_defined_for_impl<T, C, Ds>::value;
231 #endif
232 
233 
234  // ---------------------- //
235  // make_identity_matrix //
236  // ---------------------- //
237 
238 #ifdef __cpp_concepts
239  template<typename T, typename Scalar, typename Ds>
240  concept make_identity_matrix_defined_for = requires (Ds ds) {
241  library_interface<std::decay_t<T>>::template make_identity_matrix<Scalar>(std::forward<Ds>(ds));
242  };
243 #else
244  namespace detail
245  {
246  template<typename T, typename Scalar, typename Ds, typename = void>
247  struct make_identity_matrix_defined_for_impl: std::false_type {};
248 
249  template<typename T, typename Scalar, typename Ds>
250  struct make_identity_matrix_defined_for_impl<T, Scalar, Ds, std::void_t<
251  decltype(library_interface<std::decay_t<T>>::template make_identity_matrix<Scalar>(std::declval<Ds>()))>>
252  : std::true_type {};
253  }
254 
255  template<typename T, typename Scalar, typename Ds>
256  constexpr bool make_identity_matrix_defined_for = detail::make_identity_matrix_defined_for_impl<T, Scalar, Ds>::value;
257 #endif
258 
259 
260  // ------------------------ //
261  // make_triangular_matrix //
262  // ------------------------ //
263 
264 #ifdef __cpp_concepts
265  template<typename T, TriangleType triangle_type, typename Arg>
266  concept make_triangular_matrix_defined_for = requires (Arg arg) {
267  library_interface<std::decay_t<T>>::template make_triangular_matrix<triangle_type>(std::forward<Arg>(arg));
268  };
269 #else
270  namespace detail
271  {
272  template<typename T, TriangleType triangle_type, typename Arg, typename = void>
273  struct make_triangular_matrix_defined_for_impl: std::false_type {};
274 
275  template<typename T, TriangleType triangle_type, typename Arg>
276  struct make_triangular_matrix_defined_for_impl<T, triangle_type, Arg, std::void_t<
277  decltype(library_interface<std::decay_t<T>>::template make_triangular_matrix<triangle_type>(std::declval<Arg>()))>>
278  : std::true_type {};
279  }
280 
281  template<typename T, TriangleType triangle_type, typename Arg>
282  constexpr bool make_triangular_matrix_defined_for = detail::make_triangular_matrix_defined_for_impl<T, triangle_type, Arg>::value;
283 #endif
284 
285 
286  // ------------------------ //
287  // make_hermitian_adapter //
288  // ------------------------ //
289 
290 #ifdef __cpp_concepts
291  template<typename T, HermitianAdapterType adapter_type, typename Arg>
292  concept make_hermitian_adapter_defined_for = requires (Arg arg) {
293  library_interface<std::decay_t<T>>::template make_hermitian_adapter<adapter_type>(std::forward<Arg>(arg));
294  };
295 #else
296  namespace detail
297  {
298  template<typename T, HermitianAdapterType adapter_type, typename Arg, typename = void>
299  struct make_hermitian_adapter_defined_for_impl: std::false_type {};
300 
301  template<typename T, HermitianAdapterType adapter_type, typename Arg>
302  struct make_hermitian_adapter_defined_for_impl<T, adapter_type, Arg, std::void_t<
303  decltype(library_interface<std::decay_t<T>>::template make_hermitian_adapter<adapter_type>(std::declval<Arg>()))>>
304  : std::true_type {};
305  }
306 
307  template<typename T, HermitianAdapterType adapter_type, typename Arg>
308  constexpr bool make_hermitian_adapter_defined_for = detail::make_hermitian_adapter_defined_for_impl<T, adapter_type, Arg>::value;
309 #endif
310 
311 
312  // -------------- //
313  // to_euclidean //
314  // -------------- //
315 
316 #ifdef __cpp_concepts
317  template<typename T, typename Arg>
318  concept to_euclidean_defined_for = requires (Arg arg) {
319  library_interface<std::decay_t<T>>::to_euclidean(std::forward<Arg>(arg));
320  };
321 #else
322  namespace detail
323  {
324  template<typename T, typename Arg, typename = void>
325  struct to_euclidean_defined_for_impl: std::false_type {};
326 
327  template<typename T, typename Arg>
328  struct to_euclidean_defined_for_impl<T, Arg, std::void_t<
329  decltype(library_interface<std::decay_t<T>>::to_euclidean(std::declval<Arg>()))>>
330  : std::true_type {};
331  }
332 
333  template<typename T, typename Arg>
334  constexpr bool to_euclidean_defined_for = detail::to_euclidean_defined_for_impl<T, Arg>::value;
335 #endif
336 
337 
338  // ---------------- //
339  // from_euclidean //
340  // ---------------- //
341 
342 #ifdef __cpp_concepts
343  template<typename T, typename Arg, typename V>
344  concept from_euclidean_defined_for = requires (Arg arg, V v) {
345  library_interface<std::decay_t<T>>::from_euclidean(std::forward<Arg>(arg), std::forward<V>(v));
346  };
347 #else
348  namespace detail
349  {
350  template<typename T, typename Arg, typename V, typename = void>
351  struct from_euclidean_defined_for_impl: std::false_type {};
352 
353  template<typename T, typename Arg, typename V>
354  struct from_euclidean_defined_for_impl<T, Arg, V, std::void_t<
355  decltype(library_interface<std::decay_t<T>>::from_euclidean(std::declval<Arg>(), std::declval<V>()))>>
356  : std::true_type {};
357  }
358 
359  template<typename T, typename Arg, typename V>
360  constexpr bool from_euclidean_defined_for = detail::from_euclidean_defined_for_impl<T, Arg, V>::value;
361 #endif
362 
363 
364  // ------------- //
365  // wrap_angles //
366  // ------------- //
367 
368 #ifdef __cpp_concepts
369  template<typename T, typename Arg>
370  concept wrap_angles_defined_for = requires (Arg arg) {
371  library_interface<std::decay_t<T>>::wrap_angles(std::forward<Arg>(arg));
372  };
373 #else
374  namespace detail
375  {
376  template<typename T, typename Arg, typename = void>
377  struct wrap_angles_defined_for_impl: std::false_type {};
378 
379  template<typename T, typename Arg>
380  struct wrap_angles_defined_for_impl<T, Arg, std::void_t<
381  decltype(library_interface<std::decay_t<T>>::wrap_angles(std::declval<Arg>()))>>
382  : std::true_type {};
383  }
384 
385  template<typename T, typename Arg>
386  constexpr bool wrap_angles_defined_for = detail::wrap_angles_defined_for_impl<T, Arg>::value;
387 #endif
388 
389 
390  // ----------- //
391  // get_slice //
392  // ----------- //
393 
394 #ifdef __cpp_concepts
395  template<typename T, typename Arg, typename BeginTup, typename SizeTup>
396  concept get_slice_defined_for = requires(Arg arg, BeginTup begin_tup, SizeTup size_tup) {
397  library_interface<std::decay_t<T>>::set_slice(std::forward<Arg>(arg), begin_tup, size_tup);
398  };
399 #else
400  namespace detail
401  {
402  template<typename T, typename Arg, typename BeginTup, typename SizeTup, typename = void>
403  struct get_slice_defined_for_impl : std::false_type {};
404 
405  template<typename T, typename Arg, typename BeginTup, typename SizeTup>
406  struct get_slice_defined_for_impl<T, Arg, BeginTup, SizeTup, std::void_t<decltype(
407  library_interface<std::decay_t<T>>::set_slice(std::declval<Arg>(), std::declval<BeginTup>(), std::declval<SizeTup>()))>>
408  : std::true_type {};
409  }
410 
411  template<typename T, typename Arg, typename BeginTup, typename SizeTup>
412  constexpr bool get_slice_defined_for = detail::get_slice_defined_for_impl<T, Arg, BeginTup, SizeTup>::value;
413 #endif
414 
415 
416  // ----------- //
417  // set_slice //
418  // ----------- //
419 
420 #ifdef __cpp_concepts
421  template<typename T, typename Arg, typename Block, typename...Begin>
422  concept set_slice_defined_for = requires(Arg arg, Block block, Begin...begin) {
423  library_interface<std::decay_t<T>>::set_slice(std::forward<Arg>(arg), std::forward<Block>(block), std::forward<Begin>(begin)...);
424  };
425 #else
426  namespace detail
427  {
428  template<typename T, typename Arg, typename Block, typename = void, typename...Begin>
429  struct set_slice_defined_for_impl : std::false_type {};
430 
431  template<typename T, typename Arg, typename Block, typename...Begin>
432  struct set_slice_defined_for_impl<T, Arg, Block, std::void_t<decltype(
433  library_interface<std::decay_t<T>>::set_slice(std::declval<Arg>(), std::declval<Block>(), std::declval<Begin>()...))>, Begin...>
434  : std::true_type {};
435  }
436 
437  template<typename T, typename Arg, typename Block, typename...Begin>
438  constexpr bool set_slice_defined_for = detail::set_slice_defined_for_impl<T, Arg, Block, Begin...>::value;
439 #endif
440 
441 
442  // -------------- //
443  // set_triangle //
444  // -------------- //
445 
446 #ifdef __cpp_concepts
447  template<typename T, TriangleType triangle_type, typename A, typename B>
448  concept set_triangle_defined_for = requires(A a, B b) {
449  library_interface<std::decay_t<T>>::template set_triangle<triangle_type>(std::forward<A>(a), std::forward<B>(b));
450  };
451 #else
452  namespace detail
453  {
454  template<typename T, TriangleType triangle_type, typename A, typename B, typename = void>
455  struct set_triangle_defined_for_impl : std::false_type {};
456 
457  template<typename T, TriangleType triangle_type, typename A, typename B>
458  struct set_triangle_defined_for_impl<T, triangle_type, A, B, std::void_t<decltype(
459  library_interface<std::decay_t<T>>::template set_triangle<triangle_type>(std::declval<A>(), std::declval<B>()))>>
460  : std::true_type {};
461  }
462 
463  template<typename T, TriangleType triangle_type, typename A, typename B>
464  constexpr bool set_triangle_defined_for = detail::set_triangle_defined_for_impl<T, triangle_type, A, B>::value;
465 #endif
466 
467 
468  // ------------- //
469  // to_diagonal //
470  // ------------- //
471 
472 #ifdef __cpp_concepts
473  template<typename T, typename Arg>
474  concept to_diagonal_defined_for = requires (Arg arg) {
475  library_interface<std::decay_t<T>>::to_diagonal(std::forward<Arg>(arg));
476  };
477 #else
478  namespace detail
479  {
480  template<typename T, typename Arg, typename = void>
481  struct to_diagonal_defined_for_impl: std::false_type {};
482 
483  template<typename T, typename Arg>
484  struct to_diagonal_defined_for_impl<T, Arg, std::void_t<
485  decltype(library_interface<std::decay_t<T>>::to_diagonal(std::declval<Arg>()))>>
486  : std::true_type {};
487  }
488 
489  template<typename T, typename Arg>
490  constexpr bool to_diagonal_defined_for = detail::to_diagonal_defined_for_impl<T, Arg>::value;
491 #endif
492 
493 
494  // ------------- //
495  // diagonal_of //
496  // ------------- //
497 
498 #ifdef __cpp_concepts
499  template<typename T, typename Arg>
500  concept diagonal_of_defined_for = requires (Arg arg) {
501  library_interface<std::decay_t<T>>::diagonal_of(std::forward<Arg>(arg));
502  };
503 #else
504  namespace detail
505  {
506  template<typename T, typename Arg, typename = void>
507  struct diagonal_of_defined_for_impl: std::false_type {};
508 
509  template<typename T, typename Arg>
510  struct diagonal_of_defined_for_impl<T, Arg, std::void_t<
511  decltype(library_interface<std::decay_t<T>>::diagonal_of(std::declval<Arg>()))>>
512  : std::true_type {};
513  }
514 
515  template<typename T, typename Arg>
516  constexpr bool diagonal_of_defined_for = detail::diagonal_of_defined_for_impl<T, Arg>::value;
517 #endif
518 
519 
520  // ----------- //
521  // broadcast //
522  // ----------- //
523 
524 #ifdef __cpp_concepts
525  template<typename T, typename Arg, typename...Factors>
526  concept broadcast_defined_for = requires(Arg arg, Factors...factors) {
527  library_interface<std::decay_t<T>>::broadcast(std::forward<Arg>(arg), std::forward<Factors>(factors)...);
528  };
529 #else
530  namespace detail
531  {
532  template<typename T, typename Arg, typename = void, typename...Factors>
533  struct broadcast_defined_for_impl: std::false_type {};
534 
535  template<typename T, typename Arg, typename...Factors>
536  struct broadcast_defined_for_impl<T, Arg, std::void_t<
537  decltype(library_interface<std::decay_t<T>>::broadcast(std::declval<Arg>(), std::declval<Factors>()...))>, Factors...>
538  : std::true_type {};
539  }
540 
541  template<typename T, typename Arg, typename...Factors>
542  constexpr bool broadcast_defined_for = detail::broadcast_defined_for_impl<T, Arg, void, Factors...>::value;
543 #endif
544 
545 
546  // ----------------- //
547  // n_ary_operation //
548  // ----------------- //
549 
550 #ifdef __cpp_concepts
551  template<typename T, typename DTup, typename Op, typename...Args>
552  concept n_ary_operation_defined_for = requires(DTup d_tup, Op op, Args...args) {
553  library_interface<std::decay_t<T>>::n_ary_operation(d_tup, std::forward<Op>(op), std::forward<Args>(args)...);
554  };
555 #else
556  namespace detail
557  {
558  template<typename T, typename DTup, typename Op, typename = void, typename...Args>
559  struct n_ary_operation_defined_for_impl: std::false_type {};
560 
561  template<typename T, typename DTup, typename Op, typename...Args>
562  struct n_ary_operation_defined_for_impl<T, DTup, Op, std::void_t<
563  decltype(library_interface<std::decay_t<T>>::n_ary_operation(std::declval<DTup>(), std::declval<Op>(), std::declval<Args>()...))>, Args...>
564  : std::true_type {};
565  }
566 
567  template<typename T, typename DTup, typename Op, typename...Args>
568  constexpr bool n_ary_operation_defined_for = detail::n_ary_operation_defined_for_impl<T, DTup, Op, void, Args...>::value;
569 #endif
570 
571 
572  // -------- //
573  // reduce //
574  // -------- //
575 
576 #ifdef __cpp_concepts
577  template<typename T, typename BinaryFunction, typename Arg, std::size_t...indices>
578  concept reduce_defined_for = requires (BinaryFunction op, Arg arg) {
579  library_interface<std::decay_t<T>>::template reduce<indices...>(std::forward<BinaryFunction>(op), std::forward<Arg>(arg));
580  };
581 #else
582  namespace detail
583  {
584  template<typename T, typename BinaryFunction, typename Arg, typename = void, std::size_t...indices>
585  struct reduce_defined_for_impl: std::false_type {};
586 
587  template<typename T, typename BinaryFunction, typename Arg, std::size_t...indices>
588  struct reduce_defined_for_impl<T, BinaryFunction, Arg, std::void_t<
589  decltype(library_interface<std::decay_t<T>>::template reduce<indices...>(std::declval<BinaryFunction>(), std::declval<Arg>()))>, indices...>
590  : std::true_type {};
591  }
592 
593  template<typename T, typename BinaryFunction, typename Arg, std::size_t...indices>
594  constexpr bool reduce_defined_for = detail::reduce_defined_for_impl<T, BinaryFunction, Arg, void, indices...>::value;
595 #endif
596 
597 
598  // ----------- //
599  // conjugate //
600  // ----------- //
601 
602 #ifdef __cpp_concepts
603  template<typename T, typename Arg>
604  concept conjugate_defined_for = requires (Arg arg) {
605  library_interface<std::decay_t<T>>::conjugate(std::forward<Arg>(arg));
606  };
607 #else
608  namespace detail
609  {
610  template<typename T, typename Arg, typename = void>
611  struct conjugate_defined_for_impl: std::false_type {};
612 
613  template<typename T, typename Arg>
614  struct conjugate_defined_for_impl<T, Arg, std::void_t<
615  decltype(library_interface<std::decay_t<T>>::conjugate(std::declval<Arg>()))>>
616  : std::true_type {};
617  }
618 
619  template<typename T, typename Arg>
620  constexpr bool conjugate_defined_for = detail::conjugate_defined_for_impl<T, Arg>::value;
621 #endif
622 
623 
624  // ----------- //
625  // transpose //
626  // ----------- //
627 
628 #ifdef __cpp_concepts
629  template<typename T, typename Arg>
630  concept transpose_defined_for = requires (Arg arg) {
631  library_interface<std::decay_t<T>>::transpose(std::forward<Arg>(arg));
632  };
633 #else
634  namespace detail
635  {
636  template<typename T, typename Arg, typename = void>
637  struct transpose_defined_for_impl: std::false_type {};
638 
639  template<typename T, typename Arg>
640  struct transpose_defined_for_impl<T, Arg, std::void_t<
641  decltype(library_interface<std::decay_t<T>>::transpose(std::declval<Arg>()))>>
642  : std::true_type {};
643  }
644 
645  template<typename T, typename Arg>
646  constexpr bool transpose_defined_for = detail::transpose_defined_for_impl<T, Arg>::value;
647 #endif
648 
649 
650  // --------- //
651  // adjoint //
652  // --------- //
653 
654 #ifdef __cpp_concepts
655  template<typename T, typename Arg>
656  concept adjoint_defined_for = requires (Arg arg) {
657  library_interface<std::decay_t<T>>::adjoint(std::forward<Arg>(arg));
658  };
659 #else
660  namespace detail
661  {
662  template<typename T, typename Arg, typename = void>
663  struct adjoint_defined_for_impl: std::false_type {};
664 
665  template<typename T, typename Arg>
666  struct adjoint_defined_for_impl<T, Arg, std::void_t<
667  decltype(library_interface<std::decay_t<T>>::adjoint(std::declval<Arg>()))>>
668  : std::true_type {};
669  }
670 
671  template<typename T, typename Arg>
672  constexpr bool adjoint_defined_for = detail::adjoint_defined_for_impl<T, Arg>::value;
673 #endif
674 
675 
676  // ------------- //
677  // determinant //
678  // ------------- //
679 
680 #ifdef __cpp_concepts
681  template<typename T, typename Arg>
682  concept determinant_defined_for = requires (Arg arg) {
683  library_interface<std::decay_t<T>>::determinant(std::forward<Arg>(arg));
684  };
685 #else
686  namespace detail
687  {
688  template<typename T, typename Arg, typename = void>
689  struct determinant_defined_for_impl: std::false_type {};
690 
691  template<typename T, typename Arg>
692  struct determinant_defined_for_impl<T, Arg, std::void_t<
693  decltype(library_interface<std::decay_t<T>>::determinant(std::declval<Arg>()))>>
694  : std::true_type {};
695  }
696 
697  template<typename T, typename Arg>
698  constexpr bool determinant_defined_for = detail::determinant_defined_for_impl<T, Arg>::value;
699 #endif
700 
701 
702  // ----- //
703  // sum //
704  // ----- //
705 
706 #ifdef __cpp_concepts
707  template<typename T, typename...Args>
708  concept sum_defined_for = requires(Args...args) { library_interface<std::decay_t<T>>::sum(std::forward<Args>(args)...); };
709 #else
710  namespace detail
711  {
712  template<typename T, typename = void, typename...Args>
713  struct sum_defined_for_impl : std::false_type {};
714 
715  template<typename T, typename...Args>
716  struct sum_defined_for_impl<T, std::void_t<decltype(
717  library_interface<std::decay_t<T>>::sum(std::declval<Args>()...))>, Args...>
718  : std::true_type {};
719  }
720 
721  template<typename T, typename...Args>
722  constexpr bool sum_defined_for = detail::sum_defined_for_impl<T, void, Args...>::value;
723 #endif
724 
725 
726  // ---------------- //
727  // scalar_product //
728  // ---------------- //
729 
730 #ifdef __cpp_concepts
731  template<typename T, typename Arg, typename S>
732  concept scalar_product_defined_for = requires(Arg arg, S s) { library_interface<std::decay_t<T>>::scalar_product(std::forward<Arg>(arg), std::forward<S>(s)); };
733 #else
734  namespace detail
735  {
736  template<typename T, typename Arg, typename S, typename = void>
737  struct scalar_product_defined_for_impl : std::false_type {};
738 
739  template<typename T, typename Arg, typename S>
740  struct scalar_product_defined_for_impl<T, Arg, S, std::void_t<decltype(
741  library_interface<std::decay_t<T>>::scalar_product(std::declval<Arg>(), std::declval<S>()))>>
742  : std::true_type {};
743  }
744 
745  template<typename T, typename Arg, typename S>
746  constexpr bool scalar_product_defined_for = detail::scalar_product_defined_for_impl<T, Arg, S>::value;
747 #endif
748 
749 
750  // ---------------- //
751  // scalar_product //
752  // ---------------- //
753 
754 #ifdef __cpp_concepts
755  template<typename T, typename Arg, typename S>
756  concept scalar_quotient_defined_for = requires(Arg arg, S s) { library_interface<std::decay_t<T>>::scalar_quotient(std::forward<Arg>(arg), std::forward<S>(s)); };
757 #else
758  namespace detail
759  {
760  template<typename T, typename Arg, typename S, typename = void>
761  struct scalar_quotient_defined_for_impl : std::false_type {};
762 
763  template<typename T, typename Arg, typename S>
764  struct scalar_quotient_defined_for_impl<T, Arg, S, std::void_t<decltype(
765  library_interface<std::decay_t<T>>::scalar_quotient(std::declval<Arg>(), std::declval<S>()))>>
766  : std::true_type {};
767  }
768 
769  template<typename T, typename Arg, typename S>
770  constexpr bool scalar_quotient_defined_for = detail::scalar_quotient_defined_for_impl<T, Arg, S>::value;
771 #endif
772 
773 
774  // ---------- //
775  // contract //
776  // ---------- //
777 
778 #ifdef __cpp_concepts
779  template<typename T, typename A, typename B>
780  concept contract_defined_for = requires(A a, B b) {
781  library_interface<std::decay_t<T>>::contract(std::forward<A>(a), std::forward<B>(b));
782  };
783 #else
784  namespace detail
785  {
786  template<typename T, typename A, typename B, typename = void>
787  struct contract_defined_for_impl : std::false_type {};
788 
789  template<typename T, typename A, typename B>
790  struct contract_defined_for_impl<T, A, B, std::void_t<decltype(
791  library_interface<std::decay_t<T>>::contract(std::declval<A>(), std::declval<B>()))>>
792  : std::true_type {};
793  }
794 
795  template<typename T, typename A, typename B>
796  constexpr bool contract_defined_for = detail::contract_defined_for_impl<T, A, B>::value;
797 #endif
798 
799 
800  // ------------------- //
801  // contract_in_place //
802  // ------------------- //
803 
804 #ifdef __cpp_concepts
805  template<typename T, bool on_the_right, typename A, typename B>
806  concept contract_in_place_defined_for = requires(A a, B b) {
807  library_interface<std::decay_t<T>>::template contract_in_place<on_the_right>(std::forward<A>(a), std::forward<B>(b));
808  };
809 #else
810  namespace detail
811  {
812  template<typename T, bool on_the_right, typename A, typename B, typename = void>
813  struct contract_in_place_defined_for_impl : std::false_type {};
814 
815  template<typename T, bool on_the_right, typename A, typename B>
816  struct contract_in_place_defined_for_impl<T, on_the_right, A, B, std::void_t<decltype(
817  library_interface<std::decay_t<T>>::template contract_in_place<on_the_right>(std::declval<A>(), std::declval<B>()))>>
818  : std::true_type {};
819  }
820 
821  template<typename T, bool on_the_right, typename A, typename B>
822  constexpr bool contract_in_place_defined_for = detail::contract_in_place_defined_for_impl<T, on_the_right, A, B>::value;
823 #endif
824 
825 
826  // ----------------- //
827  // cholesky_factor //
828  // ----------------- //
829 
830 #ifdef __cpp_concepts
831  template<typename T, TriangleType triangle_type, typename Arg>
832  concept cholesky_factor_defined_for = requires (Arg arg) {
833  library_interface<std::decay_t<T>>::template cholesky_factor<triangle_type>(std::forward<Arg>(arg));
834  };
835 #else
836  namespace detail
837  {
838  template<typename T, TriangleType triangle_type, typename Arg, typename = void>
839  struct cholesky_factor_defined_for_impl: std::false_type {};
840 
841  template<typename T, TriangleType triangle_type, typename Arg>
842  struct cholesky_factor_defined_for_impl<T, triangle_type, Arg, std::void_t<
843  decltype(library_interface<std::decay_t<T>>::template cholesky_factor<triangle_type>(std::declval<Arg>()))>>
844  : std::true_type {};
845  }
846 
847  template<typename T, TriangleType triangle_type, typename Arg>
848  constexpr bool cholesky_factor_defined_for = detail::cholesky_factor_defined_for_impl<T, triangle_type, Arg>::value;
849 #endif
850 
851 
852  // ----------------------- //
853  // rank_update_hermitian //
854  // ----------------------- //
855 
856 #ifdef __cpp_concepts
857  template<typename T, HermitianAdapterType significant_triangle, typename A, typename U, typename Alpha>
858  concept rank_update_self_adjoint_defined_for = requires (A a, U u, Alpha alpha) {
859  library_interface<std::decay_t<T>>::template rank_update_hermitian<significant_triangle>(std::forward<A>(a), std::forward<U>(u), alpha);
860  };
861 #else
862  namespace detail
863  {
864  template<typename T, HermitianAdapterType significant_triangle, typename A, typename U, typename Alpha, typename = void>
865  struct rank_update_self_adjoint_defined_for_impl: std::false_type {};
866 
867  template<typename T, HermitianAdapterType significant_triangle, typename A, typename U, typename Alpha>
868  struct rank_update_self_adjoint_defined_for_impl<T, significant_triangle, A, U, Alpha, std::void_t<
869  decltype(library_interface<std::decay_t<T>>::template rank_update_hermitian<significant_triangle>(
870  std::declval<A>(), std::declval<U>(), std::declval<Alpha>()))>>
871  : std::true_type {};
872  }
873 
874  template<typename T, HermitianAdapterType significant_triangle, typename A, typename U, typename Alpha>
876 #endif
877 
878 
879  // ------------------------ //
880  // rank_update_triangular //
881  // ------------------------ //
882 
883 #ifdef __cpp_concepts
884  template<typename T, TriangleType triangle_type, typename A, typename U, typename Alpha>
885  concept rank_update_triangular_defined_for = requires (A a, U u, Alpha alpha) {
886  library_interface<std::decay_t<T>>::template rank_update_triangular<triangle_type>(std::forward<A>(a), std::forward<U>(u), alpha);
887  };
888 #else
889  namespace detail
890  {
891  template<typename T, TriangleType triangle_type, typename A, typename U, typename Alpha, typename = void>
892  struct rank_update_triangular_defined_for_impl: std::false_type {};
893 
894  template<typename T, TriangleType triangle_type, typename A, typename U, typename Alpha>
895  struct rank_update_triangular_defined_for_impl<T, triangle_type, A, U, Alpha, std::void_t<
896  decltype(library_interface<std::decay_t<T>>::template rank_update_triangular<triangle_type>(
897  std::declval<A>(), std::declval<U>(), std::declval<Alpha>()))>>
898  : std::true_type {};
899  }
900 
901  template<typename T, TriangleType triangle_type, typename A, typename U, typename Alpha>
902  constexpr bool rank_update_triangular_defined_for = detail::rank_update_triangular_defined_for_impl<T, triangle_type, A, U, Alpha>::value;
903 #endif
904 
905 
906  // ------- //
907  // solve //
908  // ------- //
909 
910 #ifdef __cpp_concepts
911  template<typename T, bool must_be_unique, bool must_be_exact, typename A, typename B>
912  concept solve_defined_for = requires(A a, B b) {
913  library_interface<std::decay_t<T>>::template solve<must_be_unique, must_be_exact>(std::forward<A>(a), std::forward<B>(b));
914  };
915 #else
916  namespace detail
917  {
918  template<typename T, bool must_be_unique, bool must_be_exact, typename A, typename B, typename = void>
919  struct solve_defined_for_impl : std::false_type {};
920 
921  template<typename T, bool must_be_unique, bool must_be_exact, typename A, typename B>
922  struct solve_defined_for_impl<T, must_be_unique, must_be_exact, A, B, std::void_t<decltype(
923  library_interface<std::decay_t<T>>::template solve<must_be_unique, must_be_exact>(std::declval<A>(), std::declval<B>()))>>
924  : std::true_type {};
925  }
926 
927  template<typename T, bool must_be_unique, bool must_be_exact, typename A, typename B>
929 #endif
930 
931 
932  // ------------------ //
933  // LQ_decomposition //
934  // ------------------ //
935 
936 #ifdef __cpp_concepts
937  template<typename T, typename Arg>
938  concept LQ_decomposition_defined_for = requires (Arg arg) {
940  };
941 #else
942  namespace detail
943  {
944  template<typename T, typename Arg, typename = void>
945  struct LQ_decomposition_defined_for_impl: std::false_type {};
946 
947  template<typename T, typename Arg>
948  struct LQ_decomposition_defined_for_impl<T, Arg, std::void_t<
949  decltype(library_interface<std::decay_t<T>>::LQ_decomposition(std::declval<Arg>()))>>
950  : std::true_type {};
951  }
952 
953  template<typename T, typename Arg>
954  constexpr bool LQ_decomposition_defined_for = detail::LQ_decomposition_defined_for_impl<T, Arg>::value;
955 #endif
956 
957 
958  // ------------------ //
959  // LQ_decomposition //
960  // ------------------ //
961 
962 #ifdef __cpp_concepts
963  template<typename T, typename Arg>
964  concept QR_decomposition_defined_for = requires (Arg arg) {
966  };
967 #else
968  namespace detail
969  {
970  template<typename T, typename Arg, typename = void>
971  struct QR_decomposition_defined_for_impl: std::false_type {};
972 
973  template<typename T, typename Arg>
974  struct QR_decomposition_defined_for_impl<T, Arg, std::void_t<
975  decltype(library_interface<std::decay_t<T>>::QR_decomposition(std::declval<Arg>()))>>
976  : std::true_type {};
977  }
978 
979  template<typename T, typename Arg>
980  constexpr bool QR_decomposition_defined_for = detail::QR_decomposition_defined_for_impl<T, Arg>::value;
981 #endif
982 
983 
984 } // namespace OpenKalman::interface
985 
986 
987 #endif //OPENKALMAN_LIBRARY_INTERFACES_DEFINED_HPP
decltype(auto) constexpr from_euclidean(Arg &&arg, const V &v)
Project the Euclidean vector space associated with index 0 to coordinates::pattern v after applying d...
Definition: from_euclidean.hpp:35
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
Definition: library-interfaces-defined.hpp:971
decltype(auto) constexpr contract(A &&a, B &&b)
Matrix multiplication of A * B.
Definition: contract.hpp:54
Definition: library-interfaces-defined.hpp:481
Definition: library-interfaces-defined.hpp:143
Definition: basics.hpp:41
Definition: library-interfaces-defined.hpp:663
Definition: library-interfaces-defined.hpp:761
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
decltype(auto) constexpr conjugate(Arg &&arg)
Take the conjugate of a matrix.
Definition: conjugate.hpp:33
Definition: library-interfaces-defined.hpp:737
Definition: library-interfaces-defined.hpp:169
Definition: library-interfaces-defined.hpp:325
decltype(auto) to_native_matrix(Arg &&arg)
If it isn&#39;t already, convert Arg to a native object in the library associated with LibraryObject...
Definition: to_native_matrix.hpp:35
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
Definition: tuple_reverse.hpp:103
Definition: library-interfaces-defined.hpp:455
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
decltype(auto) constexpr to_diagonal(Arg &&arg)
Convert an indexible object into a diagonal matrix.
Definition: to_diagonal.hpp:32
Definition: library-interfaces-defined.hpp:247
decltype(auto) constexpr reduce(BinaryFunction &&b, Arg &&arg)
Perform a partial reduction based on an associative binary function, across one or more indices...
Definition: reduce.hpp:143
decltype(auto) constexpr broadcast(Arg &&arg, const Factors &...factors)
Broadcast an object by replicating it by factors specified for each index.
Definition: broadcast.hpp:49
Definition: library-interfaces-defined.hpp:813
decltype(auto) constexpr transpose(Arg &&arg)
Take the transpose of a matrix.
Definition: transpose.hpp:58
Definition: library-interfaces-defined.hpp:377
Definition: library-interfaces-defined.hpp:713
Definition: library-interfaces-defined.hpp:787
Definition: library-interfaces-defined.hpp:91
An interface to various routines from the linear algebra library associated with indexible object T...
Definition: library_interface.hpp:37
Forward declaration of library_interface, which must be defined for all objects used in OpenKalman...
constexpr auto determinant(Arg &&arg)
Take the determinant of a matrix.
Definition: determinant.hpp:44
Definition: library-interfaces-defined.hpp:585
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
Definition: library-interfaces-defined.hpp:221
Definition: library-interfaces-defined.hpp:611
decltype(auto) constexpr to_euclidean(Arg &&arg)
Project the vector space associated with index 0 to a Euclidean space for applying directional statis...
Definition: to_euclidean.hpp:38
decltype(auto) constexpr adjoint(Arg &&arg)
Take the adjoint of a matrix.
Definition: adjoint.hpp:33
Definition: library-interfaces-defined.hpp:559
Definition: library-interfaces-defined.hpp:429
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
Definition: library-interfaces-defined.hpp:195
decltype(auto) constexpr sum(Ts &&...ts)
Element-by-element sum of one or more objects.
Definition: sum.hpp:112
Definition: library-interfaces-defined.hpp:533
Definition: library-interfaces-defined.hpp:637
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
Definition: library-interfaces-defined.hpp:39
Definition: library-interfaces-defined.hpp:351
constexpr auto make_constant(C &&c, Descriptors &&descriptors)
Make a constant object based on a particular library object.
Definition: make_constant.hpp:37
constexpr To && assign(To &&a, From &&b)
Assign a writable object from an indexible object.
Definition: assign.hpp:51
decltype(auto) constexpr get_component(Arg &&arg, const Indices &indices)
Get a component of an object at a particular set of indices.
Definition: get_component.hpp:54
Definition: library-interfaces-defined.hpp:689
Definition: library-interfaces-defined.hpp:945
Definition: library-interfaces-defined.hpp:117
Definition: library-interfaces-defined.hpp:919
Definition: library-interfaces-defined.hpp:839
Global definitions for OpenKalman.
Definition: library-interfaces-defined.hpp:507
A matrix with typed rows and columns.
Definition: forward-class-declarations.hpp:448
Definition: library-interfaces-defined.hpp:65
Definition: library-interfaces-defined.hpp:403
constexpr Arg && set_slice(Arg &&arg, Block &&block, const Begin &...begin)
Assign an object to a particular slice of a matrix or tensor.
Definition: set_slice.hpp:56