<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1
4//
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_ARRAY_CONCEPTS_HH
12#define TLAPACK_ARRAY_CONCEPTS_HH
13
14#if __cplusplus >= 202002L
15 #include <cmath>
16 #include <concepts>
17 #include <cstddef>
18 #include <type_traits>
19
21 #include "tlapack/base/types.hpp"
22
23namespace tlapack {
24
25// C++ standard math functions:
26using std::abs;
27using std::ceil;
28using std::floor;
29using std::isinf;
30using std::isnan;
31using std::log2;
32using std::max;
33using std::min;
34using std::pow; // We only use pow(int, T), see below in the concept Real.
35using std::sqrt;
36
37// C++ standard types:
38using std::pair;
39
40namespace concepts {
53 template <typename T>
54 concept Arithmetic = requires(const T& a, const T& b, T& c)
55 {
56 // Arithmetic and assignment operations
57 c = a + b;
58 c = a - b;
59 c = a * b;
60 c = a / b;
61 c = -a;
62
63 // Arithmetic operations with assignment
64 c += a;
65 c -= a;
66 c *= a;
67 c /= a;
68 };
69
104 template <typename T>
105 concept Real = Arithmetic<T>&& std::totally_ordered<T>&&
106 std::numeric_limits<T>::is_specialized&& requires(const T& a, T& b)
107 {
108 // Constructors
109 T();
110 T(0);
111 T(0.0);
112
113 // Assignment
114 b = a;
115
116 // Inf and NaN checks
117 {
118 isinf(a)
119 }
120 ->std::same_as<bool>;
121 {
122 isnan(a)
123 }
124 ->std::same_as<bool>;
125
126 // Math functions
127 abs(a);
128 sqrt(a);
129 pow(2, a);
130 log2(a);
131 ceil(a);
132 floor(a);
133 min(a, b);
134 max(a, b);
135 };
136
163 template <typename T>
164 concept Complex = Arithmetic<T>&& std::equality_comparable<T>&&
165 Real<real_type<T>>&& requires(const T& a, T& b)
166 {
167 // Constructors
168 T();
169 T(real_type<T>(), real_type<T>());
170
171 // Assignment
172 b = a;
173 b = real(a);
174
175 // Accessors
176 {
177 real(a)
178 }
179 ->std::same_as<real_type<T>>;
180 {
181 imag(a)
182 }
183 ->std::same_as<real_type<T>>;
184 {
185 conj(a)
186 }
187 ->std::same_as<T>;
188
189 // Math functions
190 abs(a);
191 sqrt(a);
192 };
193
211 template <typename T>
212 concept Scalar = Arithmetic<T>&& std::equality_comparable<T>&&
213 Real<real_type<T>>&& Complex<complex_type<T>>&& requires(T&& a)
214 {
215 // Assignable from a rvalue reference
216 a = std::forward<T>(a);
217
218 // Math functions
219 abs(a);
220 sqrt(a);
221 };
222
251 template <typename vector_t>
252 concept Vector = requires(const vector_t& v)
253 {
254 // Entry access using operator[i]
255 v[0];
256
257 // Number of entries
258 {
259 size(v)
260 }
261 ->std::integral<>;
262 };
263
285 template <typename vector_t>
286 concept SliceableVector = Vector<vector_t>&& requires(const vector_t& v)
287 {
288 // Subvector view
289 {
290 slice(v, pair{0, 0})
291 }
292 ->Vector<>;
293 };
294
329 template <typename matrix_t>
330 concept Matrix = requires(const matrix_t& A)
331 {
332 // Entry access using operator(i,j)
333 A(0, 0);
334
335 // Number of rows
336 {
337 nrows(A)
338 }
339 ->std::integral<>;
340
341 // Number of columns
342 {
343 ncols(A)
344 }
345 ->std::integral<>;
346
347 // Number of entries
348 {
349 size(A)
350 }
351 ->std::integral<>;
352 };
353
416 template <typename matrix_t>
417 concept SliceableMatrix = Matrix<matrix_t>&& requires(const matrix_t& A)
418 {
419 // Submatrix view (matrix)
420 {
421 slice(A, pair{0, 1}, pair{0, 1})
422 }
423 ->Matrix<>;
424
425 // View of multiple rows (matrix)
426 {
427 rows(A, pair{0, 1})
428 }
429 ->Matrix<>;
430
431 // View of multiple columns (matrix)
432 {
433 cols(A, pair{0, 1})
434 }
435 ->Matrix<>;
436
437 // Row view (vector)
438 {
439 row(A, 0)
440 }
441 ->Vector<>;
442
443 // Column view (vector)
444 {
445 col(A, 0)
446 }
447 ->Vector<>;
448
449 // View of a slice of a row (vector)
450 {
451 slice(A, 0, pair{0, 1})
452 }
453 ->Vector<>;
454
455 // View of a slice of a column (vector)
456 {
457 slice(A, pair{0, 1}, 0)
458 }
459 ->Vector<>;
460
461 // Diagonal view (vector)
462 {
463 diag(A)
464 }
465 ->Vector<>;
466
467 // Off-diagonal view (vector)
468 {
469 diag(A, 1)
470 }
471 ->Vector<>;
472 };
473
488 template <typename matrix_t>
489 concept TransposableMatrix = Matrix<matrix_t>&& requires(const matrix_t& A)
490 {
491 // Transpose view
492 {
493 transpose_view(A)
494 }
495 ->Matrix<>;
496 };
497
498 // Workspace matrices
499
500 namespace internal {
501 template <typename pair_t>
504
505 template <typename pair_t>
507 } // namespace internal
508
537 template <typename work_t>
538 concept Workspace = requires(work_t& work)
539 {
540 // Reshape into a matrix
541 {
542 reshape(work, 0, 0)
543 }
544 ->internal::PairOfTransposableMatrixAndOther<>;
545
546 // Reshape into a vector
547 {
548 reshape(work, 0)
549 }
550 ->internal::PairOfVectorAndOther<>;
551 };
552
553 // Other scalar concepts
554
562 template <typename T>
563 concept Index = std::integral<T>;
564
572 template <typename T>
573 concept Side = std::convertible_to<T, tlapack::Side>;
574
583 template <typename T>
584 concept Direction = std::convertible_to<T, tlapack::Direction>;
585
593 template <typename T>
594 concept Op = std::convertible_to<T, tlapack::Op>;
595
604 template <typename T>
605 concept StoreV = std::convertible_to<T, tlapack::StoreV>;
606
614 template <typename T>
615 concept Norm = std::convertible_to<T, tlapack::Norm>;
616
624 template <typename T>
625 concept Uplo = std::convertible_to<T, tlapack::Uplo>;
626
634 template <typename T>
635 concept Diag = std::convertible_to<T, tlapack::Diag>;
636
637 // Legacy vector and matrix types
638
651 template <typename T>
652 concept LegacyArray = requires(const T& A)
653 {
654 {
655 (legacy_matrix(A)).layout
656 }
657 ->std::convertible_to<tlapack::Layout>;
658 {
659 (legacy_matrix(A)).m
660 }
661 ->std::convertible_to<size_type<T>>;
662 {
663 (legacy_matrix(A)).n
664 }
665 ->std::convertible_to<size_type<T>>;
666 {
667 (legacy_matrix(A)).ptr[0]
668 }
669 ->std::convertible_to<type_t<T>>;
670 {
671 (legacy_matrix(A)).ldim
672 }
673 ->std::convertible_to<size_type<T>>;
674 };
675
689 template <typename matrix_t>
691 ((layout<matrix_t> == Layout::ColMajor) ||
692 (layout<matrix_t> == Layout::RowMajor));
693
709 template <typename vector_t>
711 ((layout<vector_t> == Layout::ColMajor) ||
712 (layout<vector_t> == Layout::RowMajor) ||
713 (layout<vector_t> == Layout::Strided)) &&
714 requires(const vector_t& v)
715 {
716 {
717 (legacy_vector(v)).n
718 }
719 ->std::convertible_to<size_type<vector_t>>;
720 {
721 (legacy_vector(v)).ptr[0]
722 }
723 ->std::convertible_to<type_t<vector_t>>;
724 {
725 (legacy_vector(v)).inc
726 }
727 ->std::convertible_to<size_type<vector_t>>;
728 };
729
730 // Matrix and vector types that can be created
731
766 template <typename array_t>
768 Vector<vector_type<array_t>>&& requires(std::vector<type_t<array_t>>& v,
769 type_t<array_t>* ptr)
770 {
771 {
772 Create<matrix_type<array_t>>()(v, 2, 3)
773 }
774 ->Matrix<>;
775 {
776 Create<vector_type<array_t>>()(v, 2)
777 }
778 ->Vector<>;
779 {
780 CreateStatic<matrix_type<array_t>, 5, 6>()(ptr)
781 }
782 ->Matrix<>;
783 {
784 CreateStatic<vector_type<array_t>, 5>()(ptr)
785 }
786 ->Vector<>;
787 };
788
813 template <typename matrix_t>
816 std::vector<type_t<matrix_t>>& v, type_t<matrix_t>* ptr)
817 {
818 {
819 Create<matrix_t>()(v, 2, 3)
820 }
821 ->Matrix<>;
822 {
823 CreateStatic<matrix_t, 5, 6>()(ptr)
824 }
825 ->Matrix<>;
826 };
827
837 template <typename matrix_t>
840
864 template <typename vector_t>
867 std::vector<type_t<vector_t>>& v, type_t<vector_t>* ptr)
868 {
869 {
870 Create<vector_t>()(v, 2)
871 }
872 ->Vector<>;
873 {
874 CreateStatic<vector_t, 5>()(ptr)
875 }
876 ->Vector<>;
877 };
878
888 template <typename vector_t>
891
892} // namespace concepts
893} // namespace tlapack
894
896 #define TLAPACK_MATRIX tlapack::concepts::Matrix
897
899 #define TLAPACK_SMATRIX tlapack::concepts::SliceableMatrix
900
903 #define TLAPACK_STMATRIX tlapack::concepts::SliceableTransposeMatrix
904
906 #define TLAPACK_VECTOR tlapack::concepts::Vector
907
909 #define TLAPACK_SVECTOR tlapack::concepts::SliceableVector
910
912 #define TLAPACK_WORKSPACE tlapack::concepts::Workspace
913
915 #define TLAPACK_SCALAR tlapack::concepts::Scalar
916
918 #define TLAPACK_REAL tlapack::concepts::Real
919
921 #define TLAPACK_COMPLEX tlapack::concepts::Complex
922
924 #define TLAPACK_INDEX tlapack::concepts::Index
925
927 #define TLAPACK_SIDE tlapack::concepts::Side
928
930 #define TLAPACK_DIRECTION tlapack::concepts::Direction
931
933 #define TLAPACK_OP tlapack::concepts::Op
934
936 #define TLAPACK_STOREV tlapack::concepts::StoreV
937
939 #define TLAPACK_NORM tlapack::concepts::Norm
940
942 #define TLAPACK_UPLO tlapack::concepts::Uplo
943
945 #define TLAPACK_DIAG tlapack::concepts::Diag
946
948 #define TLAPACK_LEGACY_ARRAY tlapack::concepts::LegacyArray
949
951 #define TLAPACK_LEGACY_MATRIX tlapack::concepts::LegacyMatrix
952
954 #define TLAPACK_LEGACY_VECTOR tlapack::concepts::LegacyVector
955
957 #define TLAPACK_CMATRIX tlapack::concepts::ConstructableMatrix
958
961 #define TLAPACK_CSMATRIX tlapack::concepts::ConstructableAndSliceableMatrix
962
964 #define TLAPACK_CVECTOR tlapack::concepts::ConstructableVector
965
968 #define TLAPACK_CSVECTOR tlapack::concepts::ConstructableAndSliceableVector
969#else
970 // Concepts are a C++20 feature, so just define them as `class` for earlier
971 // versions
972 #define TLAPACK_MATRIX class
973 #define TLAPACK_SMATRIX class
974 #define TLAPACK_STMATRIX class
975
976 #define TLAPACK_VECTOR class
977 #define TLAPACK_SVECTOR class
978
979 #define TLAPACK_WORKSPACE class
980
981 #define TLAPACK_SCALAR class
982 #define TLAPACK_REAL class
983 #define TLAPACK_COMPLEX class
984 #define TLAPACK_INDEX class
985
986 #define TLAPACK_SIDE class
987 #define TLAPACK_DIRECTION class
988 #define TLAPACK_OP class
989 #define TLAPACK_STOREV class
990 #define TLAPACK_NORM class
991 #define TLAPACK_UPLO class
992 #define TLAPACK_DIAG class
993
994 #define TLAPACK_LEGACY_ARRAY class
995 #define TLAPACK_LEGACY_MATRIX class
996 #define TLAPACK_LEGACY_VECTOR class
997
998 #define TLAPACK_CMATRIX class
999 #define TLAPACK_CSMATRIX class
1000 #define TLAPACK_CVECTOR class
1001 #define TLAPACK_CSVECTOR class
1002#endif
1003
1004#endif // TLAPACK_ARRAY_CONCEPTS_HH
constexpr Layout layout
Layout of a matrix or vector.
Definition arrayTraits.hpp:232
Layout
Definition types.hpp:24
constexpr bool isnan(const T &x) noexcept
Extends std::isnan() to complex numbers.
Definition utils.hpp:125
constexpr real_type< T > real(const T &x) noexcept
Extends std::real() to real datatypes.
Definition utils.hpp:71
constexpr T conj(const T &x) noexcept
Extends std::conj() to real datatypes.
Definition utils.hpp:100
constexpr real_type< T > imag(const T &x) noexcept
Extends std::imag() to real datatypes.
Definition utils.hpp:86
constexpr bool isinf(const T &x) noexcept
Extends std::isinf() to complex numbers.
Definition utils.hpp:117
Definition concepts.hpp:54
Definition concepts.hpp:164
Definition concepts.hpp:767
Definition concepts.hpp:814
Definition concepts.hpp:865
Definition concepts.hpp:635
Definition concepts.hpp:584
Definition concepts.hpp:563
Definition concepts.hpp:652
Definition concepts.hpp:690
Definition concepts.hpp:710
Definition concepts.hpp:330
Definition concepts.hpp:615
Definition concepts.hpp:594
Definition concepts.hpp:105
Definition concepts.hpp:212
Definition concepts.hpp:573
Definition concepts.hpp:417
Definition concepts.hpp:286
Definition concepts.hpp:605
Definition concepts.hpp:489
Definition concepts.hpp:625
Definition concepts.hpp:252
Definition concepts.hpp:538
constexpr auto diag(T &A, int diagIdx=0) noexcept
Get the Diagonal of an Eigen Matrix.
Definition eigen.hpp:576