내가 class Matrix를 아직도 이 블로그에 안 올려놨다니,,,
덧셈, 뺄셈, 곱셈, 스칼라배, 기본행/기본열 연산 등의 기능을 지원한다. 근데 뭐 이거 구현한다고 250줄을 잡아먹냐.
template<class T>
class Matrix {
private:
T** p;
unsigned int n; // size
public:
explicit Matrix(int _n) : n(_n) {
this->init();
}
~Matrix() {
if (p) {
for (int i = 0; i < n; ++i) {
delete[] p[i];
}
delete[] p;
}
}
Matrix(const Matrix& rhs) : n(rhs.n) {
this->init();
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
p[i][j] = rhs.p[i][j];
}
}
}
Matrix(Matrix&& rhs) noexcept : n(rhs.n) {
p = rhs.p;
rhs.p = nullptr;
}
Matrix& operator=(const Matrix& rhs) {
if (p) {
for (int i = 0; i < n; ++i) {
delete[] p[i];
}
delete[] p;
}
n = rhs.n;
this->init();
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
p[i][j] = rhs.p[i][j];
}
}
return *this;
}
Matrix& operator=(Matrix&& rhs) {
if (p) {
for (int i = 0; i < n; ++i) {
delete[] p[i];
}
delete[] p;
}
n = rhs.n;
p = rhs.p;
rhs.p = nullptr;
return *this;
}
private:
void init() {
p = new T*[n];
for (int i = 0; i < n; ++i) {
p[i] = new T[n];
for (int j = 0; j < n; ++j) {
p[i][j] = 0;
}
}
}
public:
Matrix& put(T t, int i, int j) {
p[i][j] = t;
return *this;
}
Matrix operator+(const Matrix& rhs) const {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
Matrix hold(*this);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
hold.p[i][j] += rhs.p[i][j];
}
}
return hold;
}
}
Matrix& operator+=(const Matrix& rhs) {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
p[i][j] += rhs.p[i][j];
}
}
return *this;
}
}
Matrix operator-(const Matrix& rhs) const {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
Matrix hold(*this);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
hold.p[i][j] -= rhs.p[i][j];
}
}
return hold;
}
}
Matrix& operator-=(const Matrix& rhs) {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
p[i][j] -= rhs.p[i][j];
}
}
return *this;
}
}
Matrix operator*(T k) const {
Matrix hold(*this);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
hold.p[i][j] *= k;
}
}
return hold;
}
Matrix& operator*=(T k) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
p[i][j] *= k;
}
}
return *this;
}
Matrix operator*(const Matrix& rhs) const {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
Matrix hold(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
hold.p[i][j] += p[i][k] * rhs.p[k][j];
}
}
}
return hold;
}
}
Matrix& operator*=(const Matrix& rhs) {
if (n != rhs.n) {
throw "NO CORRECT SIZE ERROR";
} else {
*this = *this * rhs;
return *this;
}
}
Matrix& exchange(Matrix& rhs) {
swap(n, rhs.n);
swap(p, rhs.p);
return *this;
}
Matrix& substract_identity(T rhs) {
for (int i = 0; i < n; ++i) {
p[i][i] -= rhs;
}
return *this;
}
Matrix& elem1_row(int r, T k, int first_nonzero_idx = 0) {
for (int j = first_nonzero_idx; j < n; ++j) {
p[r][j] *= k;
}
return *this;
}
Matrix& elem1_col(int c, T k, int first_nonzero_idx = 0) {
for (int i = first_nonzero_idx; i < n; ++i) {
p[i][c] *= k;
}
return *this;
}
Matrix& elem2_row(int r1, int r2) {
T* hold = p[r1];
p[r1] = p[r2];
p[r2] = hold;
return *this;
}
Matrix& elem2_col(int c1, int c2) {
T hold;
for (int i = 0; i < n; ++i) {
hold = p[i][c1];
p[i][c1] = p[i][c2];
p[i][c2] = hold;
}
return *this;
}
Matrix& elem3_row(int from, int to, T k, int first_nonzero_idx = 0) {
for (int j = first_nonzero_idx; j < n; ++j) {
p[to][j] += p[from][j] * k;
}
return *this;
}
Matrix& elem3_col(int from, int to, T k, int first_nonzero_idx = 0) {
for (int i = first_nonzero_idx; i < n; ++i) {
p[i][to] += p[i][from] * k;
}
return *this;
}
};
'Computer Science' 카테고리의 다른 글
아름다운 함수형 프로그래밍 (0) | 2022.11.02 |
---|---|
[C++] 표준 라이브러리 클래스 상속받기 (feat. Maybe 모나드 구현) (0) | 2022.09.27 |
[C++] Disjoint Set 기초 구현 (0) | 2022.09.09 |
[C++] Segment Tree 라이브러리 만들기 (0) | 2022.08.16 |
유용한 비트 연산들 (0) | 2022.08.11 |
댓글