GSI_Toolbox 1.0.0 A toolbox for Gas-Surface Interaction simulations

Loading...
Searching...
No Matches
Matrix.h
Go to the documentation of this file.
1
6#include <iostream>
7#include <sstream>
8#include <cstdlib>
9#include <ctime>
10#include <iomanip>
11#include <fstream>
12#include <exception>
13#include <initializer_list>
14
24template <typename T>
25 class Matrix {
26
27 private:
28
29 long rows, cols;
30 T* data;
31
32 public:
33
37 Matrix();
38
47 Matrix(long dim_x, long dim_y);
48
60 Matrix(long dim_x, long dim_y, std::initializer_list<T> l);
61
65 ~Matrix();
66
75 Matrix(const Matrix& other);
76
86 Matrix(Matrix&& other);
87
88 T* getData() {return this->data;}
89 long get_rows() const {return rows;}
90 long get_cols() const {return cols;}
91
100 Matrix& operator=(const Matrix& other);
101
110 Matrix& operator=(Matrix&& other);
111
118 Matrix& operator=(T constant);
119
129 Matrix& operator+=(const Matrix& other);
130
140 Matrix& operator-=(const Matrix& other);
141
152 Matrix& operator*=(const Matrix& other);
153
164 Matrix& operator/=(const Matrix& other);
165
175 Matrix& operator+=(T other);
176
186 Matrix& operator-=(T other);
187
197 Matrix& operator*=(T other);
198
209 Matrix& operator/=(T other);
210
211
222 T& operator()( const long i, const long j ) { return data[i*cols + j]; }
223
234 const T& operator()( const long i, const long j ) const { return data[i*cols + j]; }
235
245 T& operator()( const long n ) { return data[n]; }
246
256 const T& operator()( const long n ) const { return data[n]; }
257
258 Matrix operator+(const Matrix& other);
259 Matrix operator-(const Matrix& other);
260 Matrix operator*(const Matrix& other);
261 Matrix operator/(const Matrix& other);
262
263 Matrix operator*(T constant);
264 Matrix operator/(T constant);
265 Matrix operator^(T constant);
266 Matrix operator+(T constant);
267 Matrix operator-(T constant);
268
278 Matrix dot(const Matrix& other);
279
289 Matrix cross(const Matrix& other);
290
300 Matrix outer(const Matrix& other);
301
311 std::tuple<Matrix<T>, Matrix<T>> meshgrid(const Matrix& other);
312
320 Matrix tr();
321
329 T norm();
330
338 T max();
339
347 T min();
348
355 void print();
356
357};
358
359template <typename T>
360Matrix<T>::Matrix() : rows(0), cols(0), data(nullptr) {}
361
362template <typename T>
363 Matrix<T>::Matrix(long dim_x, long dim_y) : rows(dim_x), cols(dim_y), data(new T[rows * cols]) {
364 for(long i = 0; i < rows * cols; i ++) {
365 data[i] = 0.0;
366 }
367}
368
369template <typename T>
370 Matrix<T>::Matrix(long dim_x, long dim_y, std::initializer_list<T> l) : rows(dim_x), cols(dim_y), data(new T[rows * cols]) {
371
372 if(rows * cols != l.size()) {
373 std::cout<<"The size of the list ("<<l.size()<<") does not match the matrix shape ("<<dim_x<<", "<<dim_y<<")\n";
374 }
375 else{
376 std::uninitialized_copy(l.begin(), l.end(), data);
377 }
378}
379
380template<typename T>
381Matrix<T>::~Matrix() {
382 this->rows = 0;
383 this->cols = 0;
384 delete[] data;
385 data = nullptr;
386}
387
388template <typename T>
389 Matrix<T>::Matrix(const Matrix<T>& other) {
390 if(this != &other) {
391 this->rows = other.rows;
392 this->cols = other.cols;
393 this->data = new T[rows * cols];
394
395 for(long i = 0; i < rows * cols; i ++){
396 this->data[i] = other.data[i];
397 }
398 }
399}
400
401template <typename T>
402 Matrix<T>::Matrix(Matrix<T>&& other) {
403 if(this != &other) {
404 this->rows = other.rows;
405 this->cols = other.cols;
406 other.rows = 0;
407 other.cols = 0;
408
409 this->data = other.data;
410 other.data = nullptr;
411 }
412
413}
414
415template <typename T>
416 Matrix<T>& Matrix<T>::operator=(const Matrix<T>& other) {
417 if(this != &other) {
418 delete[] data;
419 this->rows = other.rows;
420 this->cols = other.cols;
421 data = new T[rows * cols];
422
423 for(long i = 0; i < rows * cols; i ++) {
424 this->data[i] = other.data[i];
425 }
426 }
427 return *this;
428}
429
430template <typename T>
431 Matrix<T>& Matrix<T>::operator=(Matrix<T>&& other) {
432 if(this != &other) {
433 delete[] data;
434 this->rows = other.rows;
435 this->cols = other.cols;
436 this->data = other.data;
437 other.rows = 0;
438 other.cols = 0;
439 other.data = nullptr;
440 }
441 return *this;
442}
443
444template <typename T>
445 Matrix<T>& Matrix<T>::operator=(T constant) {
446 for(long i = 0; i < rows * cols; i ++) {
447 this->data[i] = constant;
448 }
449 return *this;
450}
451
452template <typename T>
453 Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& other) {
454 if(this->rows != other.rows || this->cols != other.cols) {
455 std::cout<<"Matrix dimensions do not match!\n";
456 }
457 else{
458 for(long i = 0; i < rows * cols; i ++){
459 this->data[i] += other.data[i];
460 }
461 }
462 return *this;
463}
464
465template <typename T>
466 Matrix<T>& Matrix<T>::operator-=(const Matrix<T>& other) {
467 if(this->rows != other.rows || this->cols != other.cols) {
468 std::cout<<"Matrix dimensions do not match!\n";
469 }
470 else{
471 for(long i = 0; i < rows * cols; i ++){
472 this->data[i] -= other.data[i];
473 }
474 }
475 return *this;
476}
477
478template <typename T>
479 Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& other) {
480 if(this->rows != other.rows || this->cols != other.cols) {
481 std::cout<<"Matrix dimensions do not match!\n";
482 }
483 else{
484 for(long i = 0; i < rows * cols; i ++){
485 this->data[i] *= other.data[i];
486 }
487 }
488 return *this;
489}
490
491template <typename T>
492 Matrix<T>& Matrix<T>::operator/=(const Matrix<T>& other) {
493 if(this->rows != other.rows || this->cols != other.cols) {
494 std::cout<<"Matrix dimensions do not match!\n";
495 }
496 else{
497 for(long i = 0; i < rows * cols; i ++){
498 this->data[i] /= other.data[i];
499 }
500 }
501 return *this;
502}
503
504template <typename T>
505 Matrix<T>& Matrix<T>::operator*=(T other) {
506 for(long i = 0; i < rows * cols; i ++){
507 data[i] *= other;
508 }
509 return *this;
510}
511
512template <typename T>
513 Matrix<T>& Matrix<T>::operator/=(T other) {
514 for(long i = 0; i < rows * cols; i ++){
515 data[i] /= other;
516 }
517 return *this;
518}
519
520template <typename T>
521 Matrix<T>& Matrix<T>::operator+=(T other) {
522 for(long i = 0; i < rows * cols; i ++){
523 data[i] += other;
524 }
525 return *this;
526}
527
528template <typename T>
529 Matrix<T>& Matrix<T>::operator-=(T other) {
530 for(long i = 0; i < rows * cols; i ++){
531 data[i] -= other;
532 }
533 return *this;
534}
535
536template <typename T>
537 Matrix<T> Matrix<T>::operator+(const Matrix<T>& other) {
538 Matrix<T> res(*this);
539 res += other;
540 return res;
541}
542
543template <typename T>
544 Matrix<T> Matrix<T>::operator+(T other) {
545 Matrix<T> res(*this);
546 res += other;
547 return res;
548}
549
550template <typename T>
551 Matrix<T> Matrix<T>::operator-(const Matrix<T>& other) {
552 Matrix<T> res(*this);
553 res -= other;
554 return res;
555}
556
557template <typename T>
558 Matrix<T> Matrix<T>::operator-(T other) {
559 Matrix<T> res(*this);
560 res -= other;
561 return res;
562}
563
564template <typename T>
565 Matrix<T> Matrix<T>::operator*(const Matrix<T>& other) {
566 Matrix<T> res(*this);
567 res *= other;
568 return res;
569}
570
571template <typename T>
572 Matrix<T> Matrix<T>::operator*(T other) {
573 Matrix<T> res(*this);
574 res *= other;
575 return res;
576}
577
578template <typename T>
579 Matrix<T> Matrix<T>::operator/(T other) {
580 Matrix<T> res(*this);
581 res /= other;
582 return res;
583}
584
585template <typename T>
586 Matrix<T> Matrix<T>::operator/(const Matrix<T>& other) {
587 Matrix<T> res(*this);
588 res /= other;
589 return res;
590}
591
592template <typename T>
593 Matrix<T> Matrix<T>::operator^(T constant) {
594 Matrix<T> res(*this);
595 for(long i = 0; i < rows; i ++){
596 for(long j = 0; j < cols; j ++) {
597 res(i, j) = pow(this->data[i * cols + j], constant);
598 }
599 }
600 return res;
601}
602
603template <typename T>
604 Matrix<T> Matrix<T>::dot(const Matrix<T>& other) {
605
606 Matrix<T> res(this->rows, other.cols);
607
608 if(this->cols != other.rows) {
609 std::cout<<"Matrix dimensions of ("<<this->rows<<", "<<this->cols<<") and ("<<other.rows<<", "<<other.cols<<") are not compatible!\n";
610 }
611 else{
612 for(long i = 0; i < this->rows; i ++) {
613 for(long j = 0; j < other.cols; j ++) {
614 for(long k = 0; k < this->cols; k ++) {
615 res.data[i * other.cols + j] += this->data[i * this->cols + k] * other.data[k * other.cols + j];
616 }
617 }
618 }
619 }
620 return res;
621}
622
623template <typename T>
624 Matrix<T> Matrix<T>::cross(const Matrix<T>& other) {
625
626 Matrix<T> result(3, 1);
627 if(this->rows != 3 || this->cols != 1 || other.rows != 3 || other.cols != 1) {
628 std::cerr<<"Dimensions incompatible with the cross product operation!\n";
629 }
630 else{
631 result(0, 0) = this->data[1 * cols + 0] * other(2, 0) - this->data[2 * cols + 0] * other(1, 0);
632 result(1, 0) = this->data[2 * cols + 0] * other(0, 0) - this->data[0 * cols + 0] * other(2, 0);
633 result(2, 0) = this->data[0 * cols + 0] * other(1, 0) - this->data[1 * cols + 0] * other(0, 0);
634 }
635 return result;
636}
637
638template <typename T>
639 Matrix<T> Matrix<T>::outer(const Matrix<T>& other) {
640
641 Matrix<T> result(this->rows, other.rows);
642 if(this->cols != 1 || other.cols != 1) {
643 std::cerr<<"Dimensions incompatible with the outer product operation!\n";
644 }
645 else{
646 for(long i = 0; i < this->rows; i ++) {
647 for(long j = 0; j < other.rows; j ++) {
648 result(i, j) = this->data[j] * other(i);
649 }
650 }
651 }
652 return result;
653}
654
655template <typename T>
656std::tuple<Matrix<T>, Matrix<T>> Matrix<T>::meshgrid(const Matrix<T>& other) {
657
658 Matrix<T> mat1(this->rows, other.rows), mat2(this->rows, other.rows);
659 if(this->cols != 1 || other.cols != 1) {
660 std::cerr<<"Dimensions incompatible with the outer product operation!\n";
661 }
662 else{
663 for(long i = 0; i < this->rows; i ++) {
664 for(long j = 0; j < other.rows; j ++) {
665 mat1(i, j) = this->data[i];
666 mat2(i, j) = other(j);
667 }
668 }
669 }
670 return std::make_tuple(mat1, mat2);
671}
672
673template <typename T>
674T Matrix<T>::norm() {
675 T res = 0.0;
676
677 for(long i = 0; i < rows * cols; i ++) {
678 res += this->data[i] * this->data[i];
679 }
680
681 return sqrt(res);
682}
683
684template <typename T>
685T Matrix<T>::max() {
686 T max_value = -1e13;
687
688 for(auto i = 0; i < rows * cols; i ++) {
689 if(max_value < data[i]) max_value = data[i];
690 }
691 return max_value;
692}
693
694template <typename T>
695T Matrix<T>::min() {
696 T min_value = 1e13;
697
698 for(auto i = 0; i < rows * cols; i ++) {
699 if(min_value > data[i]) min_value = data[i];
700 }
701 return min_value;
702}
703
704template <typename T>
705 Matrix<T> Matrix<T>::tr() {
706 Matrix<T> new_matrix(cols, rows);
707
708 for(auto i = 0; i < rows; i ++) {
709 for(auto j = 0; j < cols; j ++) {
710 new_matrix(j, i) = data[i * cols + j];
711 }
712 }
713
714 return new_matrix;
715}
716
717template <typename T>
718 Matrix<T> cos(const Matrix<T>& other) {
719
720 Matrix<T> result(other.get_rows(), other.get_cols());
721
722 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
723 result(i) = std::cos(other(i));
724 }
725 return result;
726}
727
728template <typename T>
729 Matrix<T> sin(const Matrix<T>& other) {
730
731 Matrix<T> result(other.get_rows(), other.get_cols());
732
733 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
734 result(i) = std::sin(other(i));
735 }
736 return result;
737}
738
739template <typename T>
740 Matrix<T> tan(const Matrix<T>& other) {
741
742 Matrix<T> result(other.get_rows(), other.get_cols());
743
744 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
745 result(i) = std::tan(other(i));
746 }
747 return result;
748}
749
750template <typename T>
751 Matrix<T> exp(const Matrix<T>& other) {
752
753 Matrix<T> result(other.get_rows(), other.get_cols());
754
755 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
756 result(i) = std::exp(other(i));
757 }
758 return result;
759}
760
761template <typename T>
762 Matrix<T> erf(const Matrix<T>& other) {
763
764 Matrix<T> result(other.get_rows(), other.get_cols());
765
766 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
767 result(i) = std::erf(other(i));
768 }
769 return result;
770}
771
772template <typename T>
773 Matrix<T> erfc(const Matrix<T>& other) {
774
775 Matrix<T> result(other.get_rows(), other.get_cols());
776
777 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
778 result(i) = std::erfc(other(i));
779 }
780 return result;
781}
782
783template <typename T>
784T sum(const Matrix<T>& other) {
785 T res = 0.0;
786 for(long i = 0; i < other.get_rows() * other.get_cols(); i ++){
787 res += other(i);
788 }
789 return res;
790}
791
792template <typename T>
793 void Matrix<T>::print() {
794 for(auto i = 0; i < rows; i ++) {
795 for(auto j = 0; j < cols; j ++) {
796 std::cout<<data[i * cols + j] <<" ";
797 }
798 std::cout<<"\n";
799 }
800}
Matrix
This class implements a matrix object used for linear algebra and vectorized operations.
Definition Matrix.h:25
Matrix::cross
Matrix cross(const Matrix &other)
Calculates the cross product of two matrices.
Definition Matrix.h:624
Matrix::operator()
T & operator()(const long n)
Subscript operator for element access in a single row (read/write).
Definition Matrix.h:245
Matrix::operator()
T & operator()(const long i, const long j)
Subscript operator for element access (read/write).
Definition Matrix.h:222
Matrix::operator+=
Matrix & operator+=(const Matrix &other)
Compound assignment operator (addition). Adds another Matrix to this Matrix.
Definition Matrix.h:453
Matrix::meshgrid
std::tuple< Matrix< T >, Matrix< T > > meshgrid(const Matrix &other)
Calculates the meshgrid of 2 1D matrices.
Definition Matrix.h:656
Matrix::operator-=
Matrix & operator-=(const Matrix &other)
Compound assignment operator (subtraction). Subtracts another Matrix from this Matrix.
Definition Matrix.h:466
Matrix::max
T max()
Finds the maximum element in the matrix.
Definition Matrix.h:685
Matrix::dot
Matrix dot(const Matrix &other)
Calculates the dot product of two matrices.
Definition Matrix.h:604
Matrix::operator()
const T & operator()(const long n) const
Subscript operator for element access in a single row (read-only).
Definition Matrix.h:256
Matrix::operator*=
Matrix & operator*=(const Matrix &other)
Compound assignment operator (multiplication). Multiplies this Matrix with another Matrix.
Definition Matrix.h:479
Matrix::norm
T norm()
Calculates the Frobenius norm of the matrix.
Definition Matrix.h:674
Matrix::~Matrix
~Matrix()
Destructor. Cleans up the allocated memory.
Definition Matrix.h:381
Matrix::min
T min()
Finds the minimum element in the matrix.
Definition Matrix.h:695
Matrix::outer
Matrix outer(const Matrix &other)
Calculates the outer product of two matrices.
Definition Matrix.h:639
Matrix::Matrix
Matrix()
Default constructor. Initializes an empty matrix.
Definition Matrix.h:360
Matrix::operator()
const T & operator()(const long i, const long j) const
Subscript operator for element access (read-only).
Definition Matrix.h:234
Matrix::operator=
Matrix & operator=(const Matrix &other)
Copy assignment operator. Copies the data from the given Matrix object.
Definition Matrix.h:416
Matrix::print
void print()
Prints the matrix to the console.
Definition Matrix.h:793
Matrix::operator/=
Matrix & operator/=(const Matrix &other)
Compound assignment operator (division). Divides this Matrix by another Matrix.
Definition Matrix.h:492
Matrix::tr
Matrix tr()
Transposes the matrix.
Definition Matrix.h:705