1 #ifndef MSP_LINAL_SQUAREMATRIX_H_
2 #define MSP_LINAL_SQUAREMATRIX_H_
11 class not_invertible: public std::domain_error
14 not_invertible(): domain_error(std::string()) { }
15 virtual ~not_invertible() throw() { }
19 A mathematical matrix with S rows and columns. Some operations are provided
20 here that are only possible for square matrices.
22 template<typename T, unsigned S>
23 class SquareMatrix: public Matrix<T, S, S>
27 SquareMatrix(const T *d): Matrix<T, S, S>(d) { }
29 SquareMatrix(const Matrix<U, S, S> &m): Matrix<T, S, S>(m) { }
31 static SquareMatrix identity();
33 SquareMatrix &operator*=(const SquareMatrix &);
35 SquareMatrix &invert();
38 template<typename T, unsigned S>
39 inline SquareMatrix<T, S> SquareMatrix<T, S>::identity()
42 for(unsigned i=0; i<S; ++i)
47 template<typename T, unsigned S>
48 SquareMatrix<T, S> &SquareMatrix<T, S>::operator*=(const SquareMatrix<T, S> &m)
50 return *this = *this*m;
53 template<typename T, unsigned S>
54 SquareMatrix<T, S> &SquareMatrix<T, S>::invert()
58 SquareMatrix<T, S> r = identity();
59 for(unsigned i=0; i<S; ++i)
62 for(unsigned j=i+1; j<S; ++j)
63 if(abs(this->element(j, i))>abs(this->element(pivot, i)))
66 if(this->element(pivot, i)==T(0))
67 throw not_invertible();
71 this->exchange_rows(i, pivot);
72 r.exchange_rows(i, pivot);
75 for(unsigned j=i+1; j<S; ++j)
77 T a = -this->element(j, i)/this->element(i, i);
78 this->add_row(i, j, a);
82 T a = T(1)/this->element(i, i);
83 this->multiply_row(i, a);
87 for(unsigned i=S; i-->0; )
88 for(unsigned j=i; j-->0; )
89 r.add_row(i, j, -this->element(j, i));
94 template<typename T, unsigned S>
95 inline SquareMatrix<T, S> invert(const SquareMatrix<T, S> &m)
97 SquareMatrix<T, S> r = m;