1 #ifndef MSP_LINAL_SQUAREMATRIX_H_
2 #define MSP_LINAL_SQUAREMATRIX_H_
10 class not_invertible: public std::domain_error
13 not_invertible(): domain_error(std::string()) { }
14 virtual ~not_invertible() throw() { }
17 template<typename T, unsigned S>
18 class SquareMatrix: public Matrix<T, S, S>
22 SquareMatrix(const T *);
24 SquareMatrix(const Matrix<U, S, S> &);
26 static SquareMatrix identity();
28 SquareMatrix &operator*=(const SquareMatrix &);
30 SquareMatrix &invert();
33 template<typename T, unsigned S>
34 SquareMatrix<T, S>::SquareMatrix(const T *d):
38 template<typename T, unsigned S>
40 SquareMatrix<T, S>::SquareMatrix(const Matrix<U, S, S> &m):
44 template<typename T, unsigned S>
45 inline SquareMatrix<T, S> SquareMatrix<T, S>::identity()
48 for(unsigned i=0; i<S; ++i)
53 template<typename T, unsigned S>
54 SquareMatrix<T, S> &SquareMatrix<T, S>::operator*=(const SquareMatrix<T, S> &m)
56 Matrix<T, S, S>::operator*=(m);
60 template<typename T, unsigned S>
61 SquareMatrix<T, S> &SquareMatrix<T, S>::invert()
63 SquareMatrix<T, S> r = identity();
64 for(unsigned i=0; i<S; ++i)
66 if(this->element(i, i)==T(0))
69 for(unsigned j=i+1; j<S; ++j)
70 if(abs(this->element(j, i))>abs(this->element(pivot, i)))
74 throw not_invertible();
76 this->exchange_rows(i, pivot);
77 r.exchange_rows(i, pivot);
80 for(unsigned j=i+1; j<S; ++j)
82 T a = -this->element(j, i)/this->element(i, i);
83 this->add_row(i, j, a);
87 T a = T(1)/this->element(i, i);
88 this->multiply_row(i, a);
92 for(unsigned i=S; i-->0; )
93 for(unsigned j=i; j-->0; )
94 r.add_row(i, j, -this->element(j, i));
99 template<typename T, unsigned S>
100 inline SquareMatrix<T, S> invert(const SquareMatrix<T, S> &m)
102 SquareMatrix<T, S> r = m;