Documentation
Tools for embedded systems
Loading...
Searching...
No Matches
mat.hpp
1
9#ifndef QLIBS_MAT
10#define QLIBS_MAT
11
12#include <include/qlibs_types.hpp>
13#include <include/ffmath.hpp>
14
18namespace qlibs {
19
26
30// Fixed-size matrix class without dynamic memory allocation
31 template <size_t Rows, size_t Cols>
32 class mat {
33 template <size_t R, size_t C>
34 friend class mat;
35 private:
36 real_t m[Rows][Cols]; // Statically allocated memory for the matrix
37 public:
39 {
40 for (size_t i = 0; i < Rows; ++i) {
41 for (size_t j = 0; j < Cols; ++j) {
42 m[i][j] = 0.0_re; // Initialize matrix elements to zero
43 }
44 }
45 }
46
47 mat( const matSpecial type, const real_t value = 1.0_re )
48 {
49 switch( type ) {
50 case MAT_IDENTITY:
51 static_assert(Rows == Cols, "Identity matrix must be square");
52
53 for (size_t i = 0; i < Rows; ++i) {
54 for (size_t j = 0; j < Cols; ++j) {
55 if (i == j) {
56 m[i][j] = value;
57 } else {
58 m[i][j] = 0.0_re;
59 }
60 }
61 }
62 break;
63 case MAT_ALL:
64 for (size_t i = 0; i < Rows; ++i) {
65 for (size_t j = 0; j < Cols; ++j) {
66 m[i][j] = value;
67 }
68 }
69 break;
70 case MAT_MAGIC:
71
72 break;
73 default:
74 for (size_t i = 0; i < Rows; ++i) {
75 for (size_t j = 0; j < Cols; ++j) {
76 m[i][j] = 0.0_re; // Initialize matrix elements to zero
77 }
78 }
79 break;
80 }
81 }
82
83 template <typename... Args>
84 mat(Args... args)
85 {
86 static_assert(sizeof...(args) == Rows * Cols, "Incorrect number of elements provided");
87 real_t elements[] = {static_cast<real_t>(args)...};
88 for (size_t i = 0; i < Rows; ++i) {
89 for (size_t j = 0; j < Cols; ++j) {
90 m[i][j] = elements[i * Cols + j];
91 }
92 }
93 }
94
95 //inline real_t& operator()(int row, int col)
96 //{
97 // return m[row][col];
98 //}
99
100 inline real_t& operator()(size_t row, size_t col)
101 {
102 return m[row][col];
103 }
104
105 inline real_t& operator()(size_t index)
106 {
107 return m[index / Cols][index % Cols];
108 }
109
110 inline const real_t& operator()(size_t index) const
111 {
112 return m[index / Cols][index % Cols];
113 }
114
115 // Copy constructor declaration and definition
116 mat(const mat<Rows, Cols>& other)
117 {
118 for (size_t i = 0; i < Rows; ++i) {
119 for (size_t j = 0; j < Cols; ++j) {
120 m[i][j] = other.m[i][j]; // Copy elements
121 }
122 }
123 }
124
125 // Overload the + operator to perform matrix addition
127 {
128 mat<Rows, Cols> result;
129 for (size_t i = 0; i < Rows; ++i) {
130 for (size_t j = 0; j < Cols; ++j) {
131 result.m[i][j] = m[i][j] + other.m[i][j];
132 }
133 }
134 return result;
135 }
136 // Overload the subtraction operator to perform matrix subtraction
138 {
139 mat<Rows, Cols> result;
140 for (size_t i = 0; i < Rows; ++i) {
141 for (size_t j = 0; j < Cols; ++j) {
142 result.m[i][j] = m[i][j] - other.m[i][j];
143 }
144 }
145 return result;
146 }
147 // Overload the * operator to perform matrix multiplication
148 template <size_t N>
150 {
151 mat<Rows, N> result;
152 for (size_t i = 0; i < Rows; ++i) {
153 for (size_t j = 0; j < N; ++j) {
154 result.m[i][j] = 0;
155 for (size_t k = 0; k < Cols; ++k) {
156 result.m[i][j] += m[i][k] * other.m[k][j];
157 }
158 }
159 }
160 return result;
161 }
162
163 // Overload the multiplication operator for scalar multiplication
164 mat<Rows, Cols> operator*(const real_t& scalar) const
165 {
166 mat<Rows, Cols> result;
167 for (size_t i = 0; i < Rows; ++i) {
168 for (size_t j = 0; j < Cols; ++j) {
169 result.m[i][j] = m[i][j] * scalar;
170 }
171 }
172 return result;
173 }
174
175 // Overload the division operator for scalar multiplication
176 mat<Rows, Cols> operator/(const real_t& scalar) const
177 {
178 mat<Rows, Cols> result;
179 for (size_t i = 0; i < Rows; ++i) {
180 for (size_t j = 0; j < Cols; ++j) {
181 result.m[i][j] = m[i][j] / scalar;
182 }
183 }
184 return result;
185 }
186
187 // Overload the multiplication operator for scalar * matrix
188 friend mat<Rows, Cols> operator*(const real_t& scalar, const mat<Rows, Cols>& matrix)
189 {
190 mat<Rows, Cols> result;
191 for (size_t i = 0; i < Rows; ++i) {
192 for (size_t j = 0; j < Cols; ++j) {
193 result.m[i][j] = scalar * matrix.m[i][j];
194 }
195 }
196 return result;
197 }
198
199 // Overload the division operator for scalar / matrix
200 //friend mat<Rows, Cols> operator/(const real_t& scalar, const mat<Rows, Cols>& matrix)
201 //{
202 // mat<Rows, Cols> result;
203 // for (size_t i = 0; i < Rows; ++i) {
204 // for (size_t j = 0; j < Cols; ++j) {
205 // result.m[i][j] = scalar / matrix.m[i][j];
206 // }
207 // }
208 // return result;
209 //}
210
211 mat<Rows, Cols> operator+(const real_t& scalar) const
212 {
213 mat<Rows, Cols> result;
214 for (size_t i = 0; i < Rows; ++i) {
215 for (size_t j = 0; j < Cols; ++j) {
216 result.m[i][j] = m[i][j] + scalar;
217 }
218 }
219 return result;
220 }
221
222 // Overload the unary increment operator
224 {
225 for (size_t i = 0; i < Rows; ++i) {
226 for (size_t j = 0; j < Cols; ++j) {
227 ++m[i][j];
228 }
229 }
230 return *this;
231 }
232 // Overload the post-increment operator (++)
234 {
235 mat<Rows, Cols> temp = *this; // Make a copy of the current matrix
236 for (size_t i = 0; i < Rows; ++i) {
237 for (size_t j = 0; j < Cols; ++j) {
238 ++m[i][j];
239 }
240 }
241 return temp; // Return the matrix before incrementing
242 }
243
244 mat<Rows, Cols> operator-(const real_t& scalar) const
245 {
246 mat<Rows, Cols> result;
247 for (size_t i = 0; i < Rows; ++i) {
248 for (size_t j = 0; j < Cols; ++j) {
249 result.m[i][j] = m[i][j] - scalar;
250 }
251 }
252 return result;
253 }
254
255 // Overload the unary increment operator
257 {
258 for (size_t i = 0; i < Rows; ++i) {
259 for (size_t j = 0; j < Cols; ++j) {
260 ++m[i][j];
261 }
262 }
263 return *this;
264 }
265 // Overload the post-increment operator (++)
267 {
268 mat<Rows, Cols> temp = *this; // Make a copy of the current matrix
269 for (size_t i = 0; i < Rows; ++i) {
270 for (size_t j = 0; j < Cols; ++j) {
271 --m[i][j];
272 }
273 }
274 return temp; // Return the matrix before incrementing
275 }
276
277 // Overload the compound addition operator (+=) for matrices
279 for (size_t i = 0; i < Rows; ++i) {
280 for (size_t j = 0; j < Cols; ++j) {
281 m[i][j] += other.m[i][j];
282 }
283 }
284 return *this;
285 }
286
287 // Overload the compound subtraction operator (-=) for matrices
289 for (size_t i = 0; i < Rows; ++i) {
290 for (size_t j = 0; j < Cols; ++j) {
291 m[i][j] -= other.m[i][j];
292 }
293 }
294 return *this;
295 }
296
297 // Overload the compound multiplication operator (*=) with another matrix
298 template <size_t N>
300 mat<Rows, N> result;
301
302 for (size_t i = 0; i < Rows; ++i) {
303 for (size_t j = 0; j < N; ++j) {
304 result.m[i][j] = 0;
305 for (size_t k = 0; k < Cols; ++k) {
306 result.m[i][j] += m[i][k] * other.m[k][j];
307 }
308 }
309 }
310
311 *this = result; // Update the current matrix with the result
312 return *this;
313 }
314
315 // Overload the compound multiplication operator (*=) with scalar
317 for (size_t i = 0; i < Rows; ++i) {
318 for (size_t j = 0; j < Cols; ++j) {
319 m[i][j] *= scalar;
320 }
321 }
322 return *this;
323 }
324
325 // Overload the compound multiplication operator (*=) with scalar
327 for (size_t i = 0; i < Rows; ++i) {
328 for (size_t j = 0; j < Cols; ++j) {
329 m[i][j] /= scalar;
330 }
331 }
332 return *this;
333 }
334
335 // Overload the compound addition operator (+=) with a scalar
337 {
338 for (size_t i = 0; i < Rows; ++i) {
339 for (size_t j = 0; j < Cols; ++j) {
340 m[i][j] += scalar;
341 }
342 }
343 return *this;
344 }
345
346 // Overload the compound subtraction operator (-=) with a scalar
348 {
349 for (size_t i = 0; i < Rows; ++i) {
350 for (size_t j = 0; j < Cols; ++j) {
351 m[i][j] -= scalar;
352 }
353 }
354 return *this;
355 }
356
357 // Overload the addition operator for scalar + matrix
358 friend mat<Rows, Cols> operator+(const real_t& scalar, const mat<Rows, Cols>& matrix)
359 {
360 mat<Rows, Cols> result;
361 for (size_t i = 0; i < Rows; ++i) {
362 for (size_t j = 0; j < Cols; ++j) {
363 result.m[i][j] = scalar + matrix.m[i][j];
364 }
365 }
366 return result;
367 }
368
369 // Overload the addition operator for scalar + matrix
370 friend mat<Rows, Cols> operator-(const real_t& scalar, const mat<Rows, Cols>& matrix)
371 {
372 mat<Rows, Cols> result;
373 for (size_t i = 0; i < Rows; ++i) {
374 for (size_t j = 0; j < Cols; ++j) {
375 result.m[i][j] = scalar - matrix.m[i][j];
376 }
377 }
378 return result;
379 }
380
381 // Overload the assignment operator
383 {
384 if (this != &other) { // Avoid self-assignment
385 for (size_t i = 0; i < Rows; ++i) {
386 for (size_t j = 0; j < Cols; ++j) {
387 m[i][j] = other.m[i][j]; // Copy elements
388 }
389 }
390 }
391 return *this;
392 }
393
394 // Overload the unary minus operator
396 {
397 mat<Rows, Cols> result;
398 for (size_t i = 0; i < Rows; ++i) {
399 for (size_t j = 0; j < Cols; ++j) {
400 result.m[i][j] = -m[i][j]; // Negate elements
401 }
402 }
403 return result;
404 }
405
406 // Display matrix elements
407 void display() const
408 {
409 for (size_t i = 0; i < Rows; ++i) {
410 for (size_t j = 0; j < Cols; ++j) {
411 std::cout << m[i][j] << " ";
412 }
413 std::cout << std::endl;
414 }
415 std::cout << std::endl;
416 }
417
419 mat<Cols, Rows> transposed;
420
421 for (size_t i = 0; i < Rows; ++i) {
422 for (size_t j = 0; j < Cols; ++j) {
423 transposed[j][i] = m[i][j];
424 }
425 }
426
427 return transposed;
428 }
429
430 // Overload the [][] operator to access elements of the matrix
431 real_t* operator[](size_t index)
432 {
433 return m[index];
434 }
435
436 const real_t* operator[](size_t index) const
437 {
438 return m[index];
439 }
440
442 {
443 static_assert(Rows == Cols, "Inverse exists only for square matrices");
444 mat<Rows,Rows> X = *this;
446
447 for ( size_t i = 0; i < Rows; ++i ) {
448 real_t pivot = X(i, i);
449 // Make the diagonal element 1
450 for ( size_t j = 0; j < Rows; ++j ) {
451 X(i, j) /= pivot;
452 I(i, j) /= pivot;
453 }
454 for ( size_t j = 0; j < Rows; ++j) { // Make other elements in the column 0
455 if ( j != i ) {
456 real_t factor = X(j, i);
457 for ( size_t k = 0; k < Rows; ++k ) {
458 X(j, k) -= factor * X(i, k);
459 I(j, k) -= factor * I(i, k);
460 }
461 }
462 }
463 }
464
465 return I;
466 }
467
469 {
470 size_t i,j;
471 real_t maxM =0.0_re, sum = 0.0_re;
472
473 for ( i = 0U ; i < Cols; i++ ) {
474 sum = 0.0_re;
475 for ( j = 0U ; j < Rows ; ++j ) {
476 sum += ( m[i][j] < 0.0_re ) ? -m[i][j] : m[i][j];
477 }
478 if ( 0U == i ) {
479 maxM = sum;
480 }
481 maxM = ( sum > maxM ) ? sum : maxM;
482 }
483 return maxM;
484 }
485 };
486
487
488
490}
491
492
493#endif /*QLIBS_MAT*/
Matrix object.
Definition mat.hpp:32
real_t & operator()(size_t row, size_t col)
Definition mat.hpp:100
mat< Rows, Cols > operator*(const real_t &scalar) const
Definition mat.hpp:164
mat< Rows, Cols > operator-() const
Definition mat.hpp:395
mat(const matSpecial type, const real_t value=1.0_re)
Definition mat.hpp:47
mat(const mat< Rows, Cols > &other)
Definition mat.hpp:116
mat< Rows, Cols > operator+(const real_t &scalar) const
Definition mat.hpp:211
mat< Rows, Cols > operator--(int)
Definition mat.hpp:266
mat< Rows, Cols > & operator-=(const real_t &scalar)
Definition mat.hpp:347
mat()
Definition mat.hpp:38
friend mat< Rows, Cols > operator-(const real_t &scalar, const mat< Rows, Cols > &matrix)
Definition mat.hpp:370
mat(Args... args)
Definition mat.hpp:84
real_t & operator()(size_t index)
Definition mat.hpp:105
void display() const
Definition mat.hpp:407
real_t * operator[](size_t index)
Definition mat.hpp:431
const real_t * operator[](size_t index) const
Definition mat.hpp:436
mat< Rows, Cols > operator/(const real_t &scalar) const
Definition mat.hpp:176
mat< Rows, Cols > & operator--()
Definition mat.hpp:256
const real_t & operator()(size_t index) const
Definition mat.hpp:110
mat< Rows, Cols > operator+(const mat< Rows, Cols > &other) const
Definition mat.hpp:126
mat< Rows, Cols > & operator/=(const real_t &scalar)
Definition mat.hpp:326
mat< Rows, Rows > inv() const
Definition mat.hpp:441
friend mat< Rows, Cols > operator+(const real_t &scalar, const mat< Rows, Cols > &matrix)
Definition mat.hpp:358
mat< Rows, Cols > & operator++()
Definition mat.hpp:223
mat< Rows, N > & operator*=(const mat< Cols, N > &other)
Definition mat.hpp:299
mat< Rows, N > operator*(const mat< Cols, N > &other) const
Definition mat.hpp:149
mat< Rows, Cols > & operator*=(const real_t &scalar)
Definition mat.hpp:316
mat< Rows, Cols > & operator-=(const mat< Rows, Cols > &other)
Definition mat.hpp:288
mat< Rows, Cols > operator++(int)
Definition mat.hpp:233
mat< Rows, Cols > operator-(const real_t &scalar) const
Definition mat.hpp:244
mat< Rows, Cols > & operator=(const mat< Rows, Cols > &other)
Definition mat.hpp:382
mat< Rows, Cols > & operator+=(const real_t &scalar)
Definition mat.hpp:336
mat< Cols, Rows > operator!() const
Definition mat.hpp:418
real_t normInf() const
Definition mat.hpp:468
friend mat< Rows, Cols > operator*(const real_t &scalar, const mat< Rows, Cols > &matrix)
Definition mat.hpp:188
mat< Rows, Cols > operator-(const mat< Rows, Cols > &other) const
Definition mat.hpp:137
mat< Rows, Cols > & operator+=(const mat< Rows, Cols > &other)
Definition mat.hpp:278
The qLibs++ library namespace.
Definition fp16.cpp:4
matSpecial
Definition mat.hpp:20
@ MAT_ZERO
Definition mat.hpp:21
@ MAT_MAGIC
Definition mat.hpp:24
@ MAT_ALL
Definition mat.hpp:23
@ MAT_IDENTITY
Definition mat.hpp:22
float real_t
A type to instantiate a real variable double-precision of 64-bits IEEE 754.
Definition qlibs_types.hpp:43