| 2 | template <> bool eq<double>(double a, double b) { |
| 3 | return abs(a - b) < EPS; } |
| 4 | template <class T> struct matrix { |
| 5 | int rows, cols, cnt; vector<T> data; |
| 6 | inline T& at(int i, int j) { return data[i * cols + j]; } |
| 7 | matrix(int r, int c) : rows(r), cols(c), cnt(r * c) { |
| 8 | data.assign(cnt, T(0)); } |
| 9 | matrix(const matrix& other) : rows(other.rows), |
| 10 | cols(other.cols), cnt(other.cnt), data(other.data) { } |
| 11 | T& operator()(int i, int j) { return at(i, j); } |
| 12 | matrix<T> operator +(const matrix& other) { |
| 13 | matrix<T> res(*this); rep(i,0,cnt) |
| 14 | res.data[i] += other.data[i]; return res; } |
| 15 | matrix<T> operator -(const matrix& other) { |
| 16 | matrix<T> res(*this); rep(i,0,cnt) |
| 17 | res.data[i] -= other.data[i]; return res; } |
| 18 | matrix<T> operator *(T other) { |
| 19 | matrix<T> res(*this); |
| 20 | rep(i,0,cnt) res.data[i] *= other; return res; } |
| 21 | matrix<T> operator *(const matrix& other) { |
| 22 | matrix<T> res(rows, other.cols); |
| 23 | rep(i,0,rows) rep(k,0,cols) rep(j,0,other.cols) |
| 24 | res(i, j) += at(i, k) * other.data[k * other.cols + j]; |
| 25 | return res; } |
| 26 | matrix<T> pow(ll p) { |
| 27 | matrix<T> res(rows, cols), sq(*this); |
| 28 | rep(i,0,rows) res(i, i) = T(1); |
| 29 | while (p) { |
| 30 | if (p & 1) res = res * sq; |
| 31 | p >>= 1; |
| 32 | if (p) sq = sq * sq; |
| 33 | } return res; } |
| 34 | matrix<T> rref(T &det, int &rank) { |
| 35 | matrix<T> mat(*this); det = T(1), rank = 0; |
| 36 | for (int r = 0, c = 0; c < cols; c++) { |
| 37 | int k = r; |
| 38 | rep(i,k+1,rows) if (abs(mat(i,c)) > abs(mat(k,c))) k = i; |
| 39 | if (k >= rows || eq<T>(mat(k, c), T(0))) continue; |
| 40 | if (k != r) { |
| 41 | det *= T(-1); |
| 42 | rep(i,0,cols) swap(mat.at(k, i), mat.at(r, i)); |
| 43 | } det *= mat(r, r); rank++; |
| 44 | T d = mat(r,c); |
| 45 | rep(i,0,cols) mat(r, i) /= d; |
| 46 | rep(i,0,rows) { |
| 47 | T m = mat(i, c); |
| 48 | if (i != r && !eq<T>(m, T(0))) |
| 49 | rep(j,0,cols) mat(i, j) -= m * mat(r, j); |
| 50 | } r++; |
| 51 | } return mat; } |
| 52 | matrix<T> transpose() { |
| 53 | matrix<T> res(cols, rows); |
| 54 | rep(i,0,rows) rep(j,0,cols) res(j, i) = at(i, j); |
| 55 | return res; } }; |
| 56 | // vim: cc=60 ts=2 sts=2 sw=2: |
nothing calls this directly
no outgoing calls
no test coverage detected