Simple Application Framework
1
|
00001 /* 00002 This file is part of Simple Application Framework (Saf) library. 00003 Copyright (C) 2010 - 2012 Ondrej Danek <ondrej.danek@gmail.com> 00004 00005 This library is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published 00007 by the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 Saf is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Simple Application Framework library. If not, 00017 see <http://www.gnu.org/licenses/>. 00018 */ 00019 00028 #ifndef SAF_MATH_ALGEBRA_MATRIX_H 00029 #define SAF_MATH_ALGEBRA_MATRIX_H 00030 00031 #include "../../Type.h" 00032 #include "../../Collection/StaticArray.h" 00033 #include "../Range.h" 00034 00035 namespace Saf 00036 { 00037 namespace Math 00038 { 00039 namespace Algebra 00040 { 00041 // Forward declaration 00042 template <Size N, class T> class Vector; 00043 00050 template <Size N, Size M, class T> 00051 class Matrix 00052 : public Collection::StaticArray<N*M,T> 00053 { 00054 protected: 00055 typedef Collection::StaticArray<N*M,T> BaseType; 00056 typedef Matrix<N,M,T> MyType; 00057 00058 protected: 00059 using BaseType::m_data; 00060 00061 public: 00066 Matrix() 00067 {} 00068 00073 explicit Matrix(const T &v) 00074 : BaseType(v) 00075 {} 00076 00078 Matrix(const MyType& m) 00079 { 00080 *this = m; 00081 } 00082 00084 MyType& operator=(const MyType& m) 00085 { 00086 BaseType::operator=(m); 00087 return *this; 00088 } 00089 00091 Size Rows() const 00092 { 00093 return N; 00094 } 00095 00097 Size Columns() const 00098 { 00099 return M; 00100 } 00101 00107 T& operator()(Size i, Size j) 00108 { 00109 return m_data[i * M + j]; 00110 } 00111 00117 const T& operator()(Size i, Size j) const 00118 { 00119 return m_data[i * M + j]; 00120 } 00121 00123 Matrix<M,N,T> Transpose() const 00124 { 00125 Matrix<M,N,T> m; 00126 Size p1 = 0, p2; 00127 00128 for (Size i = 0; i < N; i++) 00129 { 00130 p2 = i; 00131 00132 for (Size j = 0; j < M; j++, p1++, p2 += N) 00133 { 00134 m[p2] = m_data[p1]; 00135 } 00136 } 00137 00138 return m; 00139 } 00140 00142 MyType operator-(const MyType& m) const 00143 { 00144 MyType n; 00145 00146 for (Size i = 0; i < N * M; ++i) 00147 { 00148 n.m_data[i] = m_data[i] - m.m_data[i]; 00149 } 00150 00151 return n; 00152 } 00153 00155 MyType& operator-=(const MyType& m) 00156 { 00157 for (Size i = 0; i < N * M; ++i) 00158 { 00159 m_data[i] -= m.m_data[i]; 00160 } 00161 00162 return *this; 00163 } 00164 00166 MyType operator+(const MyType& m) const 00167 { 00168 MyType n; 00169 00170 for (Size i = 0; i < N * M; ++i) 00171 { 00172 n.m_data[i] = m_data[i] + m.m_data[i]; 00173 } 00174 00175 return n; 00176 } 00177 00179 MyType& operator+=(const MyType& m) 00180 { 00181 for (Size i = 0; i < N * M; ++i) 00182 { 00183 m_data[i] += m.m_data[i]; 00184 } 00185 00186 return *this; 00187 } 00188 00190 MyType operator*(const MyType& m) const 00191 { 00192 MyType n; 00193 00194 for (Size i = 0; i < N * M; ++i) 00195 { 00196 n.m_data[i] = m_data[i] * m.m_data[i]; 00197 } 00198 00199 return n; 00200 } 00201 00203 MyType& operator*=(const MyType& m) 00204 { 00205 for (Size i = 0; i < N * M; ++i) 00206 { 00207 m_data[i] *= m.m_data[i]; 00208 } 00209 00210 return *this; 00211 } 00212 00214 MyType operator/(const MyType& m) const 00215 { 00216 MyType n; 00217 00218 for (Size i = 0; i < N * M; ++i) 00219 { 00220 n.m_data[i] = m_data[i] * m.m_data[i]; 00221 } 00222 00223 return n; 00224 } 00225 00227 MyType& operator/=(const MyType& m) 00228 { 00229 for (Size i = 0; i < N * M; ++i) 00230 { 00231 m_data[i] /= m.m_data[i]; 00232 } 00233 00234 return *this; 00235 } 00236 00238 MyType operator*(T v) const 00239 { 00240 MyType n; 00241 00242 for (Size i = 0; i < N * M; ++i) 00243 { 00244 n.m_data[i] = m_data[i] * v; 00245 } 00246 00247 return n; 00248 } 00249 00251 MyType& operator*=(T v) 00252 { 00253 for (Size i = 0; i < N * M; ++i) 00254 { 00255 m_data[i] *= v; 00256 } 00257 00258 return *this; 00259 } 00260 00262 MyType operator/(T v) const 00263 { 00264 MyType n; 00265 00266 for (Size i = N * M; i-- > 0; ) 00267 { 00268 n.m_data[i] = m_data[i] / v; 00269 } 00270 00271 return n; 00272 } 00273 00275 MyType& operator/=(T v) 00276 { 00277 for (Size i = N * M; i-- > 0; ) 00278 { 00279 m_data[i] /= v; 00280 } 00281 00282 return *this; 00283 } 00284 00286 T Sum() const 00287 { 00288 return Range::Sum(this->Begin(), this->End()); 00289 } 00290 00292 T Product() const 00293 { 00294 return Range::Product(this->Begin(), this->End()); 00295 } 00296 00298 Vector<M,T> Row(Size r) const 00299 { 00300 Vector<M,T> v; 00301 Size p = r * M; 00302 00303 for (Size i = 0; i < M; i++, p++) 00304 { 00305 v[i] = m_data[p]; 00306 } 00307 00308 return v; 00309 } 00310 00312 MyType& SetRow(Size r, const Vector<M,T> &v) 00313 { 00314 Size p = r * M; 00315 00316 for (Size i = 0; i < M; i++, p++) 00317 { 00318 m_data[p] = v[i]; 00319 } 00320 00321 return *this; 00322 } 00323 00325 Vector<N,T> Column(Size c) const 00326 { 00327 Vector<N,T> v; 00328 Size p = c; 00329 00330 for (Size i = 0; i < M; i++, p += M) 00331 { 00332 v[i] = m_data[p]; 00333 } 00334 00335 return v; 00336 } 00337 00339 MyType& SetColumn(Size c, const Vector<N,T> &v) 00340 { 00341 Size p = c; 00342 00343 for (Size i = 0; i < N; i++, p += M) 00344 { 00345 m_data[p] = v[i]; 00346 } 00347 00348 return *this; 00349 } 00350 00352 template <Size K> 00353 Matrix<N,K,T> Mul(const Matrix<M,K,T> &m) const 00354 { 00355 Matrix<N,K,T> n; 00356 Size p3 = 0; 00357 00358 for (Size i = 0; i < N; i++) 00359 { 00360 for (Size j = 0; j < K; j++) 00361 { 00362 Size p1 = i * M, p2 = j; 00363 T sum = 0; 00364 00365 for (Size k = 0; k < M; k++) 00366 { 00367 sum += m_data[p1] * m[p2]; 00368 00369 p1++; 00370 p2 += K; 00371 } 00372 00373 n[p3++] = sum; 00374 } 00375 } 00376 00377 return n; 00378 } 00379 00381 Vector<N,T> Mul(const Vector<M,T> &v) const 00382 { 00383 Vector<N,T> w; 00384 00385 for (Size i = 0; i < N; i++) 00386 { 00387 Size p = i * M; 00388 T sum = 0; 00389 00390 for (Size k = 0; k < M; k++, p++) 00391 { 00392 sum += m_data[p] * v[k]; 00393 } 00394 00395 w[i] = sum; 00396 } 00397 00398 return w; 00399 } 00400 00402 MyType& SetZero() 00403 { 00404 Algo::Range::Fill(this->Begin(), this->End(), 0); 00405 return *this; 00406 } 00407 }; 00408 00410 template <Size N, Size M, class T> 00411 Matrix<N,M,T> operator*(const T &v, const Matrix<N,M,T> &m) 00412 { 00413 return m * v; 00414 } 00415 00417 template <Size N, Size M, class T> 00418 Matrix<N,M,T> operator/(const T &v, const Matrix<N,M,T> &m) 00419 { 00420 Matrix<N,M,T> n; 00421 00422 for (Size i = 0; i < N * M; ++i) 00423 { 00424 n[i] = v / m[i]; 00425 } 00426 00427 return n; 00428 } 00429 } 00430 } 00431 } 00432 00433 #endif