1 #ifndef MSP_LINAL_DYNAMICMATRIX_H_
2 #define MSP_LINAL_DYNAMICMATRIX_H_
5 #include "dynamicvector.h"
12 A general mathematical matrix. Size is specified at runtime. May be slower
13 than a fixed-size matrix. There are no compile-time diagnostics for mismatched
20 typedef T ElementType;
28 DynamicMatrix(unsigned, unsigned);
29 DynamicMatrix(unsigned, unsigned, const T *);
30 DynamicMatrix(const DynamicMatrix &);
31 DynamicMatrix &operator=(const DynamicMatrix &);
34 unsigned rows() const { return rows_; }
35 unsigned columns() const { return columns_; }
37 T &element(unsigned, unsigned);
38 const T &element(unsigned, unsigned) const;
39 T &operator()(unsigned i, unsigned j) { return element(i, j); }
40 const T &operator()(unsigned i, unsigned j) const { return element(i, j); }
42 DynamicMatrix &operator*=(T);
43 DynamicMatrix &operator/=(T);
44 DynamicMatrix &operator+=(const DynamicMatrix &);
45 DynamicMatrix &operator-=(const DynamicMatrix &);
47 DynamicMatrix &exchange_rows(unsigned, unsigned);
48 DynamicMatrix &multiply_row(unsigned, T);
49 DynamicMatrix &add_row(unsigned, unsigned, T);
51 DynamicMatrix &invert();
56 inline DynamicMatrix<T>::DynamicMatrix(unsigned r, unsigned c):
59 data(new T[rows_*columns_])
61 std::fill(data, data+rows_*columns_, T());
65 inline DynamicMatrix<T>::DynamicMatrix(unsigned r, unsigned c, const T *d):
68 data(new T[rows_*columns_])
70 std::copy(d, d+rows_*columns_, data);
74 inline DynamicMatrix<T>::DynamicMatrix(const DynamicMatrix &other):
76 columns_(other.columns()),
77 data(new T[rows_*columns_])
79 std::copy(other.data, other.data+rows_*columns_, data);
83 inline DynamicMatrix<T> &DynamicMatrix<T>::operator=(const DynamicMatrix &other)
85 if(rows_!=other.rows() || columns_!=other.columns())
89 columns_ = other.columns();
90 data = new T[rows_*columns_];
93 std::copy(other.data, other.data+rows_*columns_, data);
99 inline DynamicMatrix<T>::~DynamicMatrix()
105 inline T &DynamicMatrix<T>::element(unsigned i, unsigned j)
107 if(i>=rows_ || j>=columns_)
108 throw std::out_of_range("DynamicMatrix::element");
110 return data[i+rows_*j];
114 inline const T &DynamicMatrix<T>::element(unsigned i, unsigned j) const
116 if(i>=rows_ || j>=columns_)
117 throw std::out_of_range("DynamicMatrix::element");
119 return data[i+rows_*j];
123 inline DynamicMatrix<T> &DynamicMatrix<T>::operator*=(T s)
125 for(unsigned i=0; i<rows_*columns_; ++i)
131 inline DynamicMatrix<T> operator*(const DynamicMatrix<T> &m, T s)
133 DynamicMatrix<T> r(m);
138 inline DynamicMatrix<T> operator*(T s, const DynamicMatrix<T> &m)
144 inline DynamicMatrix<T> operator*(const DynamicMatrix<T> &m1, const DynamicMatrix<T> &m2)
146 if(m1.columns()!=m2.rows())
147 throw size_mismatch("matrix*matrix");
149 DynamicMatrix<T> r(m1.rows(), m2.columns());
150 for(unsigned i=0; i<m1.rows(); ++i)
151 for(unsigned j=0; j<m2.columns(); ++j)
152 for(unsigned k=0; k<m1.columns(); ++k)
153 r(i, j) += m1(i, k)*m2(k, j);
159 inline DynamicVector<T> operator*(const DynamicMatrix<T> &m, const DynamicVector<T> &v)
161 if(m.columns()!=v.size())
162 throw size_mismatch("matrix*vector");
164 DynamicVector<T> r(m.rows());
165 for(unsigned i=0; i<m.rows(); ++i)
166 for(unsigned j=0; j<m.columns(); ++j)
167 r[i] += m(i, j)*v[j];
173 inline DynamicVector<T> operator*(const DynamicVector<T> &v, const DynamicMatrix<T> &m)
175 if(v.size()!=m.rows())
176 throw size_mismatch("vector*matrix");
178 DynamicVector<T> r(m.columns());
179 for(unsigned j=0; j<m.columns(); ++j)
180 for(unsigned i=0; i<m.rows(); ++i)
181 r[i] += v[i]*m(i, j);
187 inline DynamicMatrix<T> &DynamicMatrix<T>::operator/=(T s)
189 for(unsigned i=0; i<rows_*columns_; ++i)
195 inline DynamicMatrix<T> operator/(const DynamicMatrix<T> &m, T s)
197 DynamicMatrix<T> r(m);
202 inline DynamicMatrix<T> &DynamicMatrix<T>::operator+=(const DynamicMatrix<T> &m)
204 if(rows_!=m.rows_ || columns_!=m.columns_)
205 throw size_mismatch("matrix+matrix");
207 for(unsigned i=0; i<rows_*columns_; ++i)
208 data[i] += m.data[i];
214 inline DynamicMatrix<T> operator+(const DynamicMatrix<T> &m1, const DynamicMatrix<T> &m2)
216 DynamicMatrix<T> r(m1);
221 inline DynamicMatrix<T> &DynamicMatrix<T>::operator-=(const DynamicMatrix<T> &m)
223 if(rows_!=m.rows_ || columns_!=m.columns_)
224 throw size_mismatch("matrix-matrix");
226 for(unsigned i=0; i<rows_*columns_; ++i)
227 data[i] += m.data[i];
233 inline DynamicMatrix<T> operator-(const DynamicMatrix<T> &m1, const DynamicMatrix<T> &m2)
235 DynamicMatrix<T> r(m1);
240 inline bool operator==(const DynamicMatrix<T> &m1, const DynamicMatrix<T> &m2)
242 if(m1.rows()!=m2.rows() || m1.columns()!=m2.columns())
243 throw size_mismatch("matrix==matrix");
245 for(unsigned i=0; i<m1.rows(); ++i)
246 for(unsigned j=0; j<m1.columns(); ++j)
247 if(m1(i, j)!=m2(i, j))
254 inline DynamicMatrix<T> &DynamicMatrix<T>::exchange_rows(unsigned i, unsigned j)
256 if(i>=rows_ || j>=rows_)
257 throw std::out_of_range("DynamicMatrix::exchange_rows");
260 for(unsigned k=0; k<columns_; ++k)
261 swap(element(i, k), element(j, k));
267 inline DynamicMatrix<T> &DynamicMatrix<T>::multiply_row(unsigned i, T s)
270 throw std::out_of_range("DynamicMatrix::multiply_row");
272 for(unsigned k=0; k<columns_; ++k)
279 inline DynamicMatrix<T> &DynamicMatrix<T>::add_row(unsigned i, unsigned j, T s)
281 if(i>=rows_ || j>=rows_)
282 throw std::out_of_range("DynamicMatrix::exchange_rows");
284 for(unsigned k=0; k<columns_; ++k)
285 element(j, k) += element(i, k)*s;
291 inline DynamicMatrix<T> transpose(const DynamicMatrix<T> &m)
293 DynamicMatrix<T> r(m.columns(), m.rows());
294 for(unsigned i=0; i<m.rows(); ++i)
295 for(unsigned j=0; j<m.columns(); ++j)
301 inline DynamicMatrix<T> &DynamicMatrix<T>::invert()
304 throw size_mismatch("matrix invert");
306 DynamicMatrix<T> r(rows_, columns_);
307 for(unsigned i=0; i<rows_; ++i)
310 return invert_matrix(*this, r);
314 inline DynamicMatrix<T> invert(const DynamicMatrix<T> &m)
316 DynamicMatrix<T> r = m;