Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Math/Algebra/Matrix.h
Go to the documentation of this file.
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