PhysicsBasedAnimationToolkit 0.0.10
Cross-platform C++20 library of algorithms and data structures commonly used in computer graphics research on physically-based simulation.
Loading...
Searching...
No Matches
Transpose.h
1#ifndef PBAT_MATH_LINALG_MINI_TRANSPOSE_H
2#define PBAT_MATH_LINALG_MINI_TRANSPOSE_H
3
4#include "Assign.h"
5#include "Concepts.h"
6#include "pbat/HostDevice.h"
7
8#include <type_traits>
9#include <utility>
10
11namespace pbat {
12namespace math {
13namespace linalg {
14namespace mini {
15
16template <class /*CMatrix*/ TMatrix>
18
19template <class /*CMatrix*/ TMatrix>
20class TransposeView;
21
22// NOTE:
23// There is a cyclic dependency between transpose and submatrix views. This is because a submatrix
24// should have a transpose, but you should also be able to get a submatrix from a transposed matrix.
25// To break the dependency, we create a type TransposeSubMatrix (and its const version), which has
26// the exact same implementation as SubMatrix (and its const version), specifically for
27// (Const)TransposeView.
28
29template <class /*CMatrix*/ TMatrix, int M, int N>
30class ConstTransposeSubMatrix
31{
32 public:
33 using NestedType = TMatrix;
34 using ScalarType = typename NestedType::ScalarType;
35 using SelfType = ConstTransposeSubMatrix<NestedType, M, N>;
36
37 static auto constexpr kRows = M;
38 static auto constexpr kCols = N;
39 static bool constexpr bRowMajor = NestedType::bRowMajor;
40
41 PBAT_HOST_DEVICE ConstTransposeSubMatrix(NestedType const& _A, int _ib = 0, int _jb = 0)
42 : A(_A), ib(_ib), jb(_jb)
43 {
44 static_assert(
45 NestedType::kRows >= M and NestedType::kCols >= N and M > 0 and N > 0,
46 "Invalid submatrix dimensions");
47 }
48
49 PBAT_HOST_DEVICE constexpr auto Rows() const { return kRows; }
50 PBAT_HOST_DEVICE constexpr auto Cols() const { return kCols; }
51
52 PBAT_HOST_DEVICE ScalarType operator()(auto i, auto j) const { return A(ib + i, jb + j); }
53
54 // Vector(ized) access
55 PBAT_HOST_DEVICE ScalarType operator()(auto i) const { return (*this)(i % kRows, i / kRows); }
56 PBAT_HOST_DEVICE ScalarType operator[](auto i) const { return (*this)(i); }
57
58 template <auto S, auto T>
59 PBAT_HOST_DEVICE auto Slice(int i, int j) const
60 {
61 return ConstTransposeSubMatrix<SelfType, S, T>(*this, i, j);
62 }
63 PBAT_HOST_DEVICE auto Col(int j) const { return Slice<kRows, 1>(0, j); }
64 PBAT_HOST_DEVICE auto Row(int i) const { return Slice<1, kCols>(i, 0); }
65 PBAT_HOST_DEVICE auto Transpose() const { return ConstTransposeView<SelfType>(*this); }
66
67 private:
68 NestedType const& A;
69 int ib, jb;
70};
71
72template <class /*CMatrix*/ TMatrix, int M, int N>
73class TransposeSubMatrix
74{
75 public:
76 using NestedType = TMatrix;
77 using ScalarType = typename NestedType::ScalarType;
78 using SelfType = TransposeSubMatrix<NestedType, M, N>;
79
80 static auto constexpr kRows = M;
81 static auto constexpr kCols = N;
82 static bool constexpr bRowMajor = NestedType::bRowMajor;
83
84 PBAT_HOST_DEVICE TransposeSubMatrix(NestedType& _A, int _ib = 0, int _jb = 0)
85 : A(_A), ib(_ib), jb(_jb)
86 {
87 static_assert(
88 NestedType::kRows >= M and NestedType::kCols >= N and M > 0 and N > 0,
89 "Invalid submatrix dimensions");
90 }
91
92 template <class /*CMatrix*/ TOtherMatrix>
93 PBAT_HOST_DEVICE SelfType& operator=(TOtherMatrix&& B)
94 {
95 Assign(*this, std::forward<TOtherMatrix>(B));
96 return *this;
97 }
98
99 PBAT_HOST_DEVICE constexpr auto Rows() const { return kRows; }
100 PBAT_HOST_DEVICE constexpr auto Cols() const { return kCols; }
101
102 PBAT_HOST_DEVICE ScalarType operator()(auto i, auto j) const { return A(ib + i, jb + j); }
103 PBAT_HOST_DEVICE ScalarType& operator()(auto i, auto j) { return A(ib + i, jb + j); }
104
105 // Vector(ized) access
106 PBAT_HOST_DEVICE ScalarType operator()(auto i) const { return (*this)(i % kRows, i / kRows); }
107 PBAT_HOST_DEVICE ScalarType& operator()(auto i) { return (*this)(i % kRows, i / kRows); }
108 PBAT_HOST_DEVICE ScalarType operator[](auto i) const { return (*this)(i); }
109 PBAT_HOST_DEVICE ScalarType& operator[](auto i) { return (*this)(i); }
110
111 template <auto S, auto T>
112 PBAT_HOST_DEVICE auto Slice(int i, int j)
113 {
114 return TransposeSubMatrix<SelfType, S, T>(*this, i, j);
115 }
116 PBAT_HOST_DEVICE auto Col(int j) { return Slice<kRows, 1>(0, j); }
117 PBAT_HOST_DEVICE auto Row(int i) { return Slice<1, kCols>(i, 0); }
118
119 template <auto S, auto T>
120 PBAT_HOST_DEVICE auto Slice(int i, int j) const
121 {
122 return ConstTransposeSubMatrix<SelfType, S, T>(*this, i, j);
123 }
124 PBAT_HOST_DEVICE auto Col(int j) const { return Slice<kRows, 1>(0, j); }
125 PBAT_HOST_DEVICE auto Row(int i) const { return Slice<1, kCols>(i, 0); }
126
127 PBAT_HOST_DEVICE auto Transpose() { return TransposeView<SelfType>(*this); }
128 PBAT_HOST_DEVICE auto Transpose() const { return ConstTransposeView<SelfType>(*this); }
129
130 void SetConstant(auto k) { AssignScalar(*this, k); }
131
132 private:
133 NestedType& A;
134 int ib, jb;
135};
136
137template <class /*CMatrix*/ TMatrix>
138class TransposeView
139{
140 public:
141 using NestedType = TMatrix;
142 using ScalarType = typename NestedType::ScalarType;
143 using SelfType = TransposeView<NestedType>;
144
145 static auto constexpr kRows = NestedType::kCols;
146 static auto constexpr kCols = NestedType::kRows;
147 static bool constexpr bRowMajor = not NestedType::bRowMajor;
148
149 PBAT_HOST_DEVICE TransposeView(NestedType& _A) : A(_A) {}
150
151 template <class TOtherMatrix>
152 PBAT_HOST_DEVICE SelfType& operator=(TOtherMatrix&& B)
153 {
154 Assign(*this, std::forward<TOtherMatrix>(B));
155 return *this;
156 }
157
158 PBAT_HOST_DEVICE void SetConstant(ScalarType k)
159 {
160 using IntegerType = std::remove_const_t<decltype(kCols)>;
161 auto fRows =
162 [&]<IntegerType... I>(IntegerType j, std::integer_sequence<IntegerType, I...>) {
163 (((*this)(I, j) = k), ...);
164 };
165 auto fCols = [&]<IntegerType... J>(std::integer_sequence<IntegerType, J...>) {
166 (fRows(J, std::make_integer_sequence<IntegerType, kRows>()), ...);
167 };
168 fCols(std::make_integer_sequence<IntegerType, kCols>());
169 }
170
171 PBAT_HOST_DEVICE constexpr auto Rows() const { return A.Cols(); }
172 PBAT_HOST_DEVICE constexpr auto Cols() const { return A.Rows(); }
173
174 PBAT_HOST_DEVICE ScalarType operator()(auto i, auto j) const { return A(j, i); }
175 PBAT_HOST_DEVICE ScalarType& operator()(auto i, auto j) { return A(j, i); }
176
177 // Vector(ized) access
178 PBAT_HOST_DEVICE ScalarType operator()(auto i) const { return (*this)(i % kRows, i / kRows); }
179 PBAT_HOST_DEVICE ScalarType& operator()(auto i) { return (*this)(i % kRows, i / kRows); }
180 PBAT_HOST_DEVICE ScalarType operator[](auto i) const { return (*this)(i); }
181 PBAT_HOST_DEVICE ScalarType& operator[](auto i) { return (*this)(i); }
182
183 template <auto S, auto T>
184 PBAT_HOST_DEVICE auto Slice(auto i, auto j)
185 {
186 return TransposeSubMatrix<SelfType, S, T>(*this, i, j);
187 }
188 PBAT_HOST_DEVICE auto Col(auto j) { return Slice<kRows, 1>(0, j); }
189 PBAT_HOST_DEVICE auto Row(auto i) { return Slice<1, kCols>(i, 0); }
190
191 template <auto S, auto T>
192 PBAT_HOST_DEVICE auto Slice(auto i, auto j) const
193 {
194 return ConstTransposeSubMatrix<SelfType, S, T>(*this, i, j);
195 }
196 PBAT_HOST_DEVICE auto Col(auto j) const { return Slice<kRows, 1>(0, j); }
197 PBAT_HOST_DEVICE auto Row(auto i) const { return Slice<1, kCols>(i, 0); }
198
199 PBAT_HOST_DEVICE NestedType const& Transpose() const { return A; }
200 PBAT_HOST_DEVICE NestedType& Transpose() { return A; }
201
202 void SetConstant(auto k) { AssignScalar(*this, k); }
203
204 private:
205 NestedType& A;
206};
207
208template <class /*CMatrix*/ TMatrix>
209class ConstTransposeView
210{
211 public:
212 using NestedType = TMatrix;
213 using ScalarType = typename NestedType::ScalarType;
214 using SelfType = ConstTransposeView<NestedType>;
215
216 static auto constexpr kRows = NestedType::kCols;
217 static auto constexpr kCols = NestedType::kRows;
218 static bool constexpr bRowMajor = not NestedType::bRowMajor;
219
220 PBAT_HOST_DEVICE ConstTransposeView(NestedType const& _A) : A(_A) {}
221
222 PBAT_HOST_DEVICE constexpr auto Rows() const { return A.Cols(); }
223 PBAT_HOST_DEVICE constexpr auto Cols() const { return A.Rows(); }
224
225 PBAT_HOST_DEVICE ScalarType operator()(auto i, auto j) const { return A(j, i); }
226
227 // Vector(ized) access
228 PBAT_HOST_DEVICE ScalarType operator()(auto i) const { return (*this)(i % kRows, i / kRows); }
229
230 template <auto S, auto T>
231 PBAT_HOST_DEVICE auto Slice(auto i, auto j) const
232 {
233 return ConstTransposeSubMatrix<SelfType, S, T>(*this, i, j);
234 }
235 PBAT_HOST_DEVICE auto Col(auto j) const { return Slice<kRows, 1>(0, j); }
236 PBAT_HOST_DEVICE auto Row(auto i) const { return Slice<1, kCols>(i, 0); }
237
238 PBAT_HOST_DEVICE NestedType const& Transpose() const { return A; }
239
240 private:
241 NestedType const& A;
242};
243
244#define PBAT_MINI_TRANSPOSE_API(SelfType) \
245 PBAT_HOST_DEVICE [[maybe_unused]] auto Transpose() \
246 { \
247 return TransposeView<SelfType>(*this); \
248 }
249
250#define PBAT_MINI_CONST_TRANSPOSE_API(SelfType) \
251 PBAT_HOST_DEVICE [[maybe_unused]] auto Transpose() const \
252 { \
253 return ConstTransposeView<SelfType>(*this); \
254 }
255
256} // namespace mini
257} // namespace linalg
258} // namespace math
259} // namespace pbat
260
261#endif // PBAT_MATH_LINALG_MINI_TRANSPOSE_H
Definition Transpose.h:139
Mini linear algebra related functionality.
Definition Assign.h:12
Linear Algebra related functionality.
Definition FilterEigenvalues.h:7
Math related functionality.
Definition Concepts.h:19
The main namespace of the library.
Definition Aliases.h:15