본문 바로가기
Computer Science

[C++] class Matrix 구현

by invrtd.h 2022. 9. 24.

내가 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;
    }
};

댓글