a

Dependencies:   mbed mbed-rtos

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers linalg.h Source File

linalg.h

00001 #ifndef LINALG_H
00002 #define LINALG_H
00003 
00004 // #include <mbed.h>
00005 #include <stdint.h>
00006 #include <array>
00007 
00008 namespace linalg
00009 {
00010     template <class T, uint32_t M, uint32_t N>
00011     class CMatrix
00012     {
00013     public:
00014         using CThisType = CMatrix<T,M,N>;
00015         using CTransposeType = CMatrix<T,N,M>;
00016         using CContainerType = std::array<std::array<T,N>,M>;
00017         using CDataType =T;
00018 
00019         template <uint32_t P>
00020         using CLeftMultipliableType = CMatrix<T,P,M>;
00021 
00022         template <uint32_t P>
00023         using CRightMultipliableType = CMatrix<T,N,P>;
00024 
00025         template <uint32_t P>
00026         using CLeftMultiplicationResultType = CMatrix<T,P,N>;
00027 
00028         template <uint32_t P>
00029         using CRightMultiplicationResultType = CMatrix<T,M,P>;
00030 
00031         friend class CMatrix<T,N,M>; 
00032 
00033         CMatrix() : m_data() {}
00034         CMatrix(const CThisType& f_matrix) : m_data(f_matrix.m_data) {}
00035         CMatrix(const CThisType&& f_matrix) : m_data(f_matrix.m_data) {}
00036         CMatrix(const CContainerType& f_data) : m_data(f_data) {}
00037         CMatrix(const CContainerType&& f_data) : m_data(f_data) {}
00038 
00039         CThisType& operator=(const CThisType& f_matrix)
00040         {
00041             for (uint32_t l_row = 0; l_row < M; ++l_row)
00042             {
00043                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00044                 {
00045                     this->m_data[l_row][l_col] = f_matrix.m_data[l_row][l_col];
00046                 }
00047             }
00048             return *this;
00049         }
00050         CThisType& operator=(const CThisType&& f_matrix)
00051         {
00052             for (uint32_t l_row = 0; l_row < M; ++l_row)
00053             {
00054                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00055                 {
00056                     this->m_data[l_row][l_col] = f_matrix.m_data[l_row][l_col];
00057                 }
00058             }
00059             return *this;
00060         }
00061 
00062         std::array<T,N>& operator[](uint32_t f_row)
00063         {
00064             return m_data[f_row];
00065         }
00066 
00067         CDataType& operator()(uint32_t f_row, uint32_t f_col)
00068         {
00069             return m_data[f_row][f_col];
00070         }
00071 
00072         const std::array<T,N>& operator[](uint32_t f_row) const
00073         {
00074             return m_data[f_row];
00075         }
00076 
00077         const CDataType& operator()(uint32_t f_row, uint32_t f_col) const
00078         {
00079             return m_data[f_row][f_col];
00080         }
00081 
00082         // template<>
00083         // CMatrix<T,1,1>::operator CDataType()
00084         // {
00085         //     return m_data[0][0];
00086         // }
00087 
00088         CThisType& operator+() {return *this;}
00089         CThisType operator-()
00090         {
00091             CThisType l_matrix;
00092             for (uint32_t l_row = 0; l_row < M; ++l_row)
00093             {
00094                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00095                 {
00096                     l_matrix.m_data[l_row][l_col] = -this->m_data[l_row][l_col];
00097                 }
00098             }
00099             return l_matrix;
00100         }
00101         CThisType operator+(const CThisType& f_matrix)
00102         {
00103             CThisType l_matrix;
00104             for (uint32_t l_row = 0; l_row < M; ++l_row)
00105             {
00106                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00107                 {
00108                     l_matrix.m_data[l_row][l_col] = this->m_data[l_row][l_col] + f_matrix.m_data[l_row][l_col];
00109                 }
00110             }
00111             return l_matrix;
00112         }
00113         CThisType operator-(const CThisType& f_matrix)
00114         {
00115             CThisType l_matrix;
00116             for (uint32_t l_row = 0; l_row < M; ++l_row)
00117             {
00118                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00119                 {
00120                     l_matrix.m_data[l_row][l_col] = this->m_data[l_row][l_col] - f_matrix.m_data[l_row][l_col];
00121                 }
00122             }
00123             return l_matrix;
00124         }
00125         CThisType& operator+=(const CThisType& f_matrix)
00126         {
00127             for (uint32_t l_row = 0; l_row < M; ++l_row)
00128             {
00129                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00130                 {
00131                     this->m_data[l_row][l_col] += f_matrix.m_data[l_row][l_col];
00132                 }
00133             }
00134             return *this;
00135         }
00136         CThisType& operator-=(const CThisType& f_matrix)
00137         {
00138             for (uint32_t l_row = 0; l_row < M; ++l_row)
00139             {
00140                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00141                 {
00142                     this->m_data[l_row][l_col] -= f_matrix.m_data[l_row][l_col];
00143                 }
00144             }
00145             return *this;
00146         }
00147 
00148         CThisType operator+(const CDataType& f_val)
00149         {
00150             CThisType l_matrix;
00151             for (uint32_t l_row = 0; l_row < M; ++l_row)
00152             {
00153                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00154                 {
00155                     l_matrix.m_data[l_row][l_col] = this->m_data[l_row][l_col] + f_val;
00156                 }
00157             }
00158             return l_matrix;
00159         }
00160         CThisType operator-(const CDataType& f_val)
00161         {
00162             CThisType l_matrix;
00163             for (uint32_t l_row = 0; l_row < M; ++l_row)
00164             {
00165                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00166                 {
00167                     l_matrix.m_data[l_row][l_col] = this->m_data[l_row][l_col] - f_val;
00168                 }
00169             }
00170             return l_matrix;
00171         }
00172         CThisType& operator+=(const CDataType& f_val)
00173         {
00174             for (uint32_t l_row = 0; l_row < M; ++l_row)
00175             {
00176                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00177                 {
00178                     this->m_data[l_row][l_col] += f_val;
00179                 }
00180             }
00181             return *this;
00182         }
00183         CThisType& operator-=(const CDataType& f_val)
00184         {
00185             for (uint32_t l_row = 0; l_row < M; ++l_row)
00186             {
00187                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00188                 {
00189                     this->m_data[l_row][l_col] -= f_val;
00190                 }
00191             }
00192             return *this;
00193         }
00194         CThisType& operator*=(const CDataType& f_val)
00195         {
00196             for (uint32_t l_row = 0; l_row < M; ++l_row)
00197             {
00198                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00199                 {
00200                     this->m_data[l_row][l_col] *= f_val;
00201                 }
00202             }
00203             return *this;
00204         }
00205         CThisType& operator*=(const CThisType& f_val)
00206         {
00207             CThisType& l_thisRef(*this);
00208             l_thisRef = l_thisRef * f_val;
00209             return l_thisRef;
00210         }
00211         CThisType& operator/=(const CDataType& f_val)
00212         {
00213             for (uint32_t l_row = 0; l_row < M; ++l_row)
00214             {
00215                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00216                 {
00217                     this->m_data[l_row][l_col] /= f_val;
00218                 }
00219             }
00220             return *this;
00221         }
00222         CThisType operator*(const CDataType& f_val)
00223         {
00224             CThisType l_matrix;
00225             for (uint32_t l_row = 0; l_row < M; ++l_row)
00226             {
00227                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00228                 {
00229                     l_matrix.m_data[l_row][l_col] = this->m_data[l_row][l_col] * f_val;
00230                 }
00231             }
00232             return l_matrix;
00233         }
00234         template <uint32_t P>
00235         CRightMultiplicationResultType<P> operator*(const CRightMultipliableType<P>& f_matrix)
00236         {
00237             CRightMultiplicationResultType<P> l_matrix;
00238             for (uint32_t l_row = 0; l_row < M; ++l_row)
00239             {
00240                 for (uint32_t l_col = 0; l_col < P; ++l_col)
00241                 {
00242                     l_matrix[l_row][l_col] = 0;
00243                     for (uint32_t l_idx = 0; l_idx < N; ++l_idx)
00244                     {
00245                         l_matrix[l_row][l_col] += this->m_data[l_row][l_idx] * f_matrix[l_idx][l_col];
00246                     }
00247                 }
00248             }
00249             return l_matrix;
00250         }
00251         CThisType inv();
00252 
00253         CTransposeType transpose()
00254         {
00255             CTransposeType l_trsp;
00256 
00257             for (uint32_t l_row = 0; l_row < M; ++l_row)
00258             {
00259                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00260                 {
00261                     l_trsp.m_data[l_col][l_row] = this->m_data[l_row][l_col];
00262                 }
00263             }
00264 
00265             return l_trsp;
00266         }
00267 
00268         template <uint32_t P>
00269         CRightMultiplicationResultType<P> solve(const CRightMultipliableType<P>& f_B)
00270         {
00271             return CLUDecomposition(*this).solve();
00272         }
00273 
00274         static CThisType zeros()
00275         {
00276             CThisType l_res;
00277 
00278             for (uint32_t l_row = 0; l_row < M; ++l_row)
00279             {
00280                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00281                 {
00282                     l_res[l_row][l_col] = 0;
00283                 }
00284             }
00285 
00286             return l_res;
00287         }
00288 
00289         static CThisType ones()
00290         {
00291             CThisType l_res;
00292 
00293             for (uint32_t l_row = 0; l_row < M; ++l_row)
00294             {
00295                 for (uint32_t l_col = 0; l_col < N; ++l_col)
00296                 {
00297                     l_res[l_row][l_col] = 1;
00298                 }
00299             }
00300 
00301             return l_res;
00302         }
00303 
00304         static CThisType eye()
00305         {
00306             CThisType l_res(CThisType::zeros());
00307             uint32_t l_minDim = std::min(M,N);
00308 
00309             for (uint32_t l_row = 0; l_row < l_minDim; ++l_row)
00310             {
00311                 l_res[l_row][l_row] = 1;
00312             }
00313 
00314             return l_res;
00315         }
00316 
00317     protected:
00318         std::array<std::array<T,N>,M> m_data;
00319     };
00320 
00321     template<class T, uint32_t N>
00322     class CLUDecomposition
00323     {
00324     public:
00325         using CThisType = CLUDecomposition<T,N>;
00326         using COriginalType = CMatrix<T,N,N>;
00327         using CDataType =T;
00328 
00329         template <uint32_t P>
00330         using CLeftMultipliableType = CMatrix<T,P,N>;
00331 
00332         template <uint32_t P>
00333         using CRightMultipliableType = CMatrix<T,N,P>;
00334 
00335         template <uint32_t P>
00336         using CLeftMultiplicationResultType = CMatrix<T,P,N>;
00337 
00338         template <uint32_t P>
00339         using CRightMultiplicationResultType = CMatrix<T,N,P>;
00340 
00341         CLUDecomposition(const CThisType& f_decomposition) : m_L(f_decomposition.m_L), m_U(f_decomposition.m_U), m_P(f_decomposition.m_P) {}
00342         CLUDecomposition(const CThisType&& f_decomposition) : m_L(f_decomposition.m_L), m_U(f_decomposition.m_U), m_P(f_decomposition.m_P) {}
00343         CLUDecomposition(const COriginalType& f_matrix) : m_L(), m_U(), m_P() {decompose(f_matrix);}
00344         CLUDecomposition(const COriginalType&& f_matrix) : m_L(), m_U(), m_P() {decompose(f_matrix);}
00345 
00346         operator COriginalType()
00347         {
00348             return m_L * m_U;
00349         }
00350 
00351         COriginalType inv()
00352         {
00353             return triUInv() * triLInv();
00354         }
00355 
00356         COriginalType triLInv()
00357         {
00358             COriginalType l_invL(m_L);
00359 
00360             for (uint32_t l_jdx = 0; l_jdx < N; ++l_jdx)
00361             {
00362                 l_invL[l_jdx][l_jdx] = 1/l_invL[l_jdx][l_jdx];
00363 
00364                 for (uint32_t l_idx = l_jdx+1; l_idx < N; ++l_idx)
00365                 {
00366                     l_invL[l_idx][l_jdx] = 0;
00367 
00368                     for (uint32_t l_kdx = l_jdx; l_kdx < l_idx; ++l_kdx)
00369                     {
00370                         l_invL[l_idx][l_jdx] -= m_L[l_idx][l_kdx]*l_invL[l_kdx][l_jdx];
00371                     }
00372 
00373                     l_invL[l_idx][l_jdx] /= l_invL[l_idx][l_idx];
00374                 }
00375             }
00376 
00377             return l_invL;
00378         }
00379 
00380         COriginalType triUInv()
00381         {
00382             COriginalType l_invU(m_U);
00383 
00384             for (int32_t l_jdx = (N-1); l_jdx >= 0; --l_jdx)
00385             {
00386                 l_invU[l_jdx][l_jdx] = 1/l_invU[l_jdx][l_jdx];
00387 
00388                 for (int32_t l_idx = (l_jdx-1); l_idx >= 0; --l_idx)
00389                 {
00390                     l_invU[l_idx][l_jdx] = 0;
00391 
00392                     for (int32_t l_kdx = (l_idx+1); l_kdx < (l_jdx+1); ++l_kdx)
00393                     {
00394                         l_invU[l_idx][l_jdx] -= m_U[l_idx][l_kdx]*l_invU[l_kdx][l_jdx];
00395                     }
00396 
00397                     l_invU[l_idx][l_jdx] /= l_invU[l_idx][l_idx];
00398                 }
00399             }
00400 
00401             return l_invU;
00402         }
00403 
00404         template <uint32_t P>
00405         CRightMultiplicationResultType<P> solve(const CRightMultipliableType<P>& f_B)
00406         {
00407             CRightMultipliableType<P> l_B;
00408 
00409             for (uint32_t l_idx = 0; l_idx < N; ++l_idx)
00410             {
00411                 for (uint32_t l_jdx = 0; l_jdx < P; ++l_jdx)
00412                 {
00413                     l_B[l_idx][l_jdx] = f_B[m_P[l_idx]][l_jdx];
00414                 }
00415             }
00416 
00417             return sTriL(sTriU(l_B));
00418         }
00419 
00420         template <uint32_t P>
00421         CRightMultiplicationResultType<P> sTriU(const CRightMultipliableType<P>& f_B)
00422         {
00423             return triUInv()*f_B;
00424         }
00425 
00426         template <uint32_t P>
00427         CRightMultiplicationResultType<P> sTriL(const CRightMultipliableType<P>& f_B)
00428         {
00429             // return triLInv()*f_B;
00430         }
00431 
00432 
00433     // private:
00434         void decompose(const CMatrix<T,N,N>& f_matrix)
00435                 {
00436             m_U = f_matrix;
00437             for (uint32_t l_kdx = 0; l_kdx < (N-1); ++l_kdx)
00438             {
00439                 m_L[l_kdx][l_kdx] = 1;
00440                 m_P[l_kdx] = l_kdx;
00441 
00442                 for(uint32_t l_idx = l_kdx+1; l_idx < N; ++l_idx)
00443                 {
00444                     m_L[l_idx][l_kdx] = m_U[l_idx][l_kdx]/m_U[l_kdx][l_kdx];
00445                     m_U[l_idx][l_kdx] = 0;
00446                     for(uint32_t l_jdx = l_kdx+1; l_jdx < N; ++l_jdx)
00447                     {
00448                         m_U[l_idx][l_jdx] = m_U[l_idx][l_jdx] - m_L[l_idx][l_kdx]*m_U[l_kdx][l_jdx];
00449                     }
00450                 }
00451             }
00452             m_L[N-1][N-1] = 1;
00453             m_P[N-1] = N-1;
00454         }
00455         CMatrix<T,N,N> m_L;
00456         CMatrix<T,N,N> m_U;
00457         std::array<uint32_t,N> m_P;
00458     };
00459 
00460     template <class T, uint32_t N>
00461     using CColVector = CMatrix<T,N,1>;
00462 
00463     template <class T, uint32_t N>
00464     using CVector = CColVector<T,N>;
00465 
00466     template <class T, uint32_t N>
00467     using CRowVector = CMatrix<T,1,N>;
00468 };
00469 
00470 #include "linalg.inl"
00471 
00472 #endif // LINALG_H
00473