1 #ifndef MSP_LINAL_MATRIX_H_
2 #define MSP_LINAL_MATRIX_H_
12 A general mathematical matrix with M rows and N columns.
14 template<typename T, unsigned M, unsigned N>
18 typedef T ElementType;
27 Matrix(const Matrix<U, M, N> &);
29 static Matrix from_columns(const Vector<T, M> *);
30 static Matrix from_rows(const Vector<T, N> *);
32 unsigned rows() const { return M; }
33 unsigned columns() const { return N; }
35 T &element(unsigned i, unsigned j) { return data[i+M*j]; }
36 const T &element(unsigned i, unsigned j) const { return data[i+M*j]; }
37 T &operator()(unsigned i, unsigned j) { return element(i, j); }
38 const T &operator()(unsigned i, unsigned j) const { return element(i, j); }
40 Vector<T, M> column(unsigned i) const { return Vector<T, M>(data+M*i); }
41 Vector<T, N> row(unsigned i) const { return Vector<T, N>(data+i, M); }
43 template<unsigned P, unsigned Q>
44 Matrix<T, P, Q> select(const Vector<unsigned, P> &, const Vector<unsigned, Q> &) const;
46 template<unsigned P, unsigned Q>
47 Matrix<T, P, Q> block(unsigned, unsigned) const;
49 Matrix &operator*=(T);
50 Matrix &operator/=(T);
51 Matrix &operator+=(const Matrix &);
52 Matrix &operator-=(const Matrix &);
54 Matrix &exchange_rows(unsigned, unsigned);
55 Matrix &multiply_row(unsigned, T);
56 Matrix &add_row(unsigned, unsigned, T);
59 template<typename T, unsigned M, unsigned N>
60 inline Matrix<T, M, N>::Matrix()
62 std::fill(data, data+M*N, T());
65 template<typename T, unsigned M, unsigned N>
66 inline Matrix<T, M, N>::Matrix(const T *d)
68 std::copy(d, d+M*N, data);
71 template<typename T, unsigned M, unsigned N>
73 inline Matrix<T, M, N>::Matrix(const Matrix<U, M, N> &other)
75 for(unsigned i=0; i<M; ++i)
76 for(unsigned j=0; j<N; ++j)
77 element(i, j) = other(i, j);
80 template<typename T, unsigned M, unsigned N>
81 inline Matrix<T, M, N> Matrix<T, M, N>::from_columns(const Vector<T, M> *v)
84 for(unsigned i=0; i<M; ++i)
85 for(unsigned j=0; j<N; ++j)
90 template<typename T, unsigned M, unsigned N>
91 inline Matrix<T, M, N> Matrix<T, M, N>::from_rows(const Vector<T, N> *v)
94 for(unsigned i=0; i<M; ++i)
95 for(unsigned j=0; j<N; ++j)
100 template<typename T, unsigned M, unsigned N>
101 template<unsigned P, unsigned Q>
102 inline Matrix<T, P, Q> Matrix<T, M, N>::select(const Vector<unsigned, P> &row_indices, const Vector<unsigned, Q> &col_indices) const
105 for(unsigned j=0; j<P; ++j)
106 for(unsigned i=0; i<Q; ++i)
107 r(j, i) = element(row_indices[j], col_indices[i]);
111 template<typename T, unsigned M, unsigned N>
112 template<unsigned P, unsigned Q>
113 inline Matrix<T, P, Q> Matrix<T, M, N>::block(unsigned y, unsigned x) const
116 for(unsigned j=0; j<P; ++j)
117 for(unsigned i=0; i<Q; ++i)
118 r(j, i) = element(y+j, x+i);
122 template<typename T, unsigned M, unsigned N>
123 inline Matrix<T, M, N> &Matrix<T, M, N>::operator*=(T s)
125 for(unsigned i=0; i<M*N; ++i)
130 template<typename T, unsigned M, unsigned N>
131 inline Matrix<T, M, N> operator*(const Matrix<T, M, N> &m, T s)
133 Matrix<T, M, N> r(m);
137 template<typename T, unsigned M, unsigned N>
138 inline Matrix<T, M, N> operator*(T s, const Matrix<T, M, N> &m)
143 template<typename T, unsigned M, unsigned P, unsigned N>
144 inline Matrix<T, M, N> operator*(const Matrix<T, M, P> &m1, const Matrix<T, P, N> &m2)
147 for(unsigned i=0; i<M; ++i)
148 for(unsigned j=0; j<N; ++j)
149 for(unsigned k=0; k<P; ++k)
150 r(i, j) += m1(i, k)*m2(k, j);
154 template<typename T, unsigned M, unsigned N>
155 inline Vector<T, M> operator*(const Matrix<T, M, N> &m, const Vector<T, N> &v)
158 for(unsigned i=0; i<M; ++i)
159 for(unsigned j=0; j<N; ++j)
160 r[i] += m(i, j)*v[j];
164 template<typename T, unsigned M, unsigned N>
165 inline Vector<T, N> operator*(const Vector<T, M> &v, const Matrix<T, M, N> &m)
168 for(unsigned j=0; j<N; ++j)
169 for(unsigned i=0; i<M; ++i)
170 r[j] += v[i]*m(i, j);
174 template<typename T, unsigned M, unsigned N>
175 inline Matrix<T, M, N> &Matrix<T, M, N>::operator/=(T s)
177 for(unsigned i=0; i<M*N; ++i)
182 template<typename T, unsigned M, unsigned N>
183 inline Matrix<T, M, N> operator/(const Matrix<T, M, N> &m, T s)
185 Matrix<T, M, N> r(m);
189 template<typename T, unsigned M, unsigned N>
190 inline Matrix<T, M, N> &Matrix<T, M, N>::operator+=(const Matrix<T, M, N> &m)
192 for(unsigned i=0; i<M*N; ++i)
193 data[i] += m.data[i];
197 template<typename T, unsigned M, unsigned N>
198 inline Matrix<T, M, N> operator+(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
200 Matrix<T, M, N> r(m1);
204 template<typename T, unsigned M, unsigned N>
205 inline Matrix<T, M, N> &Matrix<T, M, N>::operator-=(const Matrix<T, M, N> &m)
207 for(unsigned i=0; i<M*N; ++i)
208 data[i] -= m.data[i];
212 template<typename T, unsigned M, unsigned N>
213 inline Matrix<T, M, N> operator-(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
215 Matrix<T, M, N> r(m1);
219 template<typename T, unsigned M, unsigned N>
220 inline bool operator==(const Matrix<T, M, N> &a, const Matrix<T, M, N> &b)
222 for(unsigned j=0; j<N; ++j)
223 for(unsigned i=0; i<M; ++i)
229 template<typename T, unsigned M, unsigned N>
230 inline Matrix<T, M, N> &Matrix<T, M, N>::exchange_rows(unsigned i, unsigned j)
233 for(unsigned k=0; k<N; ++k)
234 swap(element(i, k), element(j, k));
238 template<typename T, unsigned M, unsigned N>
239 inline Matrix<T, M, N> &Matrix<T, M, N>::multiply_row(unsigned i, T s)
241 for(unsigned k=0; k<N; ++k)
246 template<typename T, unsigned M, unsigned N>
247 inline Matrix<T, M, N> &Matrix<T, M, N>::add_row(unsigned i, unsigned j, T s)
249 for(unsigned k=0; k<N; ++k)
250 element(j, k) += element(i, k)*s;
254 template<typename T, unsigned M, unsigned N>
255 inline Matrix<T, N, M> transpose(const Matrix<T, M, N> &m)
258 for(unsigned j=0; j<N; ++j)
259 for(unsigned i=0; i<M; ++i)
264 template<typename T, unsigned M, unsigned N>
265 inline std::ostream &operator<<(std::ostream &s, const Matrix<T, M, N> &m)
267 s << "Matrix" << M << 'x' << N << '(';
268 for(unsigned i=0; i<N; ++i)
273 for(unsigned j=0; j<M; ++j)