Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FixedMatrix.h
Go to the documentation of this file.
00001 /********************************************************************
00002 **                Image Component Library (ICL)                    **
00003 **                                                                 **
00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld          **
00005 **                         Neuroinformatics Group                  **
00006 ** Website: www.iclcv.org and                                      **
00007 **          http://opensource.cit-ec.de/projects/icl               **
00008 **                                                                 **
00009 ** File   : ICLMath/src/ICLMath/FixedMatrix.h                      **
00010 ** Module : ICLMath                                                **
00011 ** Authors: Christof Elbrechter                                    **
00012 **                                                                 **
00013 **                                                                 **
00014 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00015 ** This file may be used under the terms of the GNU Lesser General **
00016 ** Public License version 3.0 as published by the                  **
00017 **                                                                 **
00018 ** Free Software Foundation and appearing in the file LICENSE.GPL  **
00019 ** included in the packaging of this file.  Please review the      **
00020 ** following information to ensure the license requirements will   **
00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00022 **                                                                 **
00023 ** The development of this software was supported by the           **
00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00026 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00027 ** Excellence Initiative.                                          **
00028 **                                                                 **
00029 ********************************************************************/
00030 
00031 #pragma once
00032 
00033 #include <iterator>
00034 #include <algorithm>
00035 #include <numeric>
00036 #include <functional>
00037 #include <iostream>
00038 #include <vector>
00039 #include <cmath>
00040 
00041 #include <ICLUtils/Exception.h>
00042 #include <ICLMath/DynMatrix.h>
00043 #include <ICLUtils/ClippedCast.h>
00044 #include <ICLMath/MatrixSubRectIterator.h>
00045 #include <ICLUtils/FixedArray.h>
00046 
00047 #ifdef HAVE_IPP
00048 #include <ippm.h>
00049 #endif
00050 
00051 namespace icl{
00052   namespace math{
00053   
00055     struct FixedMatrixBase{
00057       template<class SrcIterator, class DstIterator, unsigned int N>
00058       static void optimized_copy(SrcIterator srcBegin, SrcIterator srcEnd, DstIterator dstBegin){
00059         if(N>30){
00060           std::copy(srcBegin,srcEnd,dstBegin);
00061         }else{
00062           while(srcBegin != srcEnd){
00063             //          *dstBegin++ = *srcBegin++;
00064             *dstBegin =
00065             *srcBegin;
00066   
00067             dstBegin++;
00068             srcBegin++;
00069           }
00070         }
00071       }
00072     };
00073       
00075 
00076     template<class T,unsigned int COLS,unsigned int ROWS> class FixedMatrix;
00080 
00081 
00090     template<class T,unsigned int N, class Iterator>
00091     class FixedMatrixPart : public FixedMatrixBase{
00092   
00093       public:
00095       Iterator begin;
00096       
00098       Iterator end;
00099     
00101       FixedMatrixPart(Iterator begin, Iterator end):begin(begin),end(end){}
00102       
00104       FixedMatrixPart& operator=(const T &value){
00105         std::fill(begin,end,value);
00106         return *this;
00107       }
00109 
00110       FixedMatrixPart& operator=(const FixedMatrixPart &other){
00111         FixedMatrixBase::optimized_copy<Iterator,Iterator,N>(other.begin,other.end,begin);
00112         return *this;
00113       }
00114       
00116 
00118       template<class OtherIterator, class OtherT>
00119       FixedMatrixPart& operator=(const FixedMatrixPart<OtherT,N,OtherIterator> &other){
00120         std::transform(other.begin,other.end,begin,utils::clipped_cast<OtherT,T>);
00121         return *this;
00122       }
00123       
00125 
00126       template<unsigned int COLS>
00127       FixedMatrixPart& operator=(const FixedMatrix<T,COLS,N/COLS> &m);
00128   
00130 
00131       template<class T2, unsigned int COLS>
00132       FixedMatrixPart& operator=(const FixedMatrix<T2,COLS,N/COLS> &m);
00133       
00134     };
00135   
00136   
00137   
00139 
00170     template<class T,unsigned int COLS,unsigned int ROWS>
00171     class FixedMatrix : public utils::FixedArray<T,COLS*ROWS>, public FixedMatrixBase{
00172       public:
00173       
00175 
00176       DynMatrix<T> dyn() { return DynMatrix<T>(COLS,ROWS,begin(),false); }
00177   
00179       const DynMatrix<T> dyn() const { return DynMatrix<T>(COLS,ROWS,const_cast<T*>(begin()),false); }
00180       
00182       static const FixedMatrix &null(){
00183         static FixedMatrix null_matrix(T(0));
00184         return null_matrix;
00185       }
00186   
00188       static const unsigned int DIM = COLS*ROWS;
00189       
00190       public:
00191       
00193 
00194       FixedMatrix(){}
00195       
00197       FixedMatrix(const T &initValue){
00198         std::fill(begin(),end(),initValue);
00199       }
00200   
00202 
00206       FixedMatrix(const T *srcdata){
00207         FixedMatrixBase::optimized_copy<const T*,T*,DIM>(srcdata,srcdata+dim(),begin());
00208         //std::copy(srcdata,srcdata+dim(),begin());
00209       }
00210   
00212 
00215       FixedMatrix(const T& v0,const T& v1,const T& v2=0,const T& v3=0,
00216                   const T& v4=0,const T& v5=0,const T& v6=0,const T& v7=0,  
00217                   const T& v8=0,const T& v9=0,const T& v10=0,const T& v11=0,  
00218                   const T& v12=0,const T& v13=0,const T& v14=0,const T& v15=0){
00219   #define C1(N) if(DIM>N) utils::FixedArray<T,COLS*ROWS>::m_data[N]=v##N
00220   #define C4(A,B,C,D) C1(A);C1(B);C1(C);C1(D)
00221         C4(0,1,2,3);C4(4,5,6,7);C4(8,9,10,11);C4(12,13,14,15);
00222   #undef C1
00223   #undef C2
00224       } 
00225   
00227 
00228       template<class OtherIterator>
00229       FixedMatrix(OtherIterator begin, OtherIterator end){
00230         FixedMatrixBase::optimized_copy<OtherIterator,T*,DIM>(begin,end,this->begin());
00231         //      std::copy(begin,end,begin());
00232       }
00233   
00234       // Explicit Copy template based constructor (deep copy)
00235       FixedMatrix(const FixedMatrix &other){
00236         FixedMatrixBase::optimized_copy<const T*,T*,DIM>(other.begin(),other.end(),begin());
00237         //std::copy(other.begin(),other.end(),begin());
00238       }
00239   
00240       // Explicit Copy template based constructor (deep copy)
00241       template<class otherT>
00242       FixedMatrix(const FixedMatrix<otherT,COLS,ROWS> &other){
00243         std::transform(other.begin(),other.end(),begin(),utils::clipped_cast<otherT,T>);
00244       }
00245   
00247       template<class Iterator>
00248       FixedMatrix (const FixedMatrixPart<T,DIM,Iterator> &r){ 
00249         FixedMatrixBase::optimized_copy<Iterator,T*,DIM>(r.begin,r.end,begin());
00250       }
00251   
00253       template<class otherT, class Iterator>
00254       FixedMatrix(const FixedMatrixPart<otherT,DIM,Iterator> &r){ 
00255         std::transform(r.begin,r.end,begin(),utils::clipped_cast<otherT,T>);
00256       }
00257       
00259       FixedMatrix &operator=(const FixedMatrix &other){
00260         if(this == &other) return *this;
00261         FixedMatrixBase::optimized_copy<const T*,T*,DIM>(other.begin(),other.end(),begin());
00262         //std::copy(other.begin(),other.end(),begin());
00263         return *this;
00264       }
00265       
00267 
00268       template<class otherT>
00269       FixedMatrix &operator=(const FixedMatrix<otherT,COLS,ROWS> &other){
00270         if(this == &other) return *this;
00271         std::transform(other.begin(),other.end(),begin(),utils::clipped_cast<otherT,T>);
00272         return *this;
00273       }
00274       
00276       FixedMatrix &operator=(const T &t){
00277         std::fill(begin(),end(),t);
00278         return *this;
00279       }
00280   
00282       template<class Iterator>
00283       FixedMatrix &operator=(const FixedMatrixPart<T,DIM,Iterator> &r){ 
00284         //      std::copy(r.begin,r.end,begin());
00285         FixedMatrixBase::optimized_copy<Iterator,T*,DIM>(r.begin,r.end,begin());
00286         return *this;
00287       }
00288   
00290       template<class otherT, class Iterator>
00291       FixedMatrix &operator=(const FixedMatrixPart<otherT,DIM,Iterator> &r){ 
00292         std::transform(r.begin,r.end,begin(),utils::clipped_cast<otherT,T>);
00293         return *this;
00294       }
00295   
00297 
00301       FixedMatrix operator/(const FixedMatrix &m) const 
00302         throw (IncompatibleMatrixDimensionException,
00303                InvalidMatrixDimensionException,
00304                SingularMatrixException){
00305         return this->operator*(m.inv());
00306       }
00307   
00309       FixedMatrix &operator/=(const FixedMatrix &m) const 
00310         throw (IncompatibleMatrixDimensionException,
00311                InvalidMatrixDimensionException,
00312                SingularMatrixException){
00313         return *this = this->operator*(m.inv());
00314       }
00315   
00317       FixedMatrix operator*(T f) const{
00318         FixedMatrix d;
00319         std::transform(begin(),end(),d.begin(),std::bind2nd(std::multiplies<T>(),f));
00320         return d;
00321       }
00322   
00324       FixedMatrix &operator*=(T f){
00325         std::transform(begin(),end(),begin(),std::bind2nd(std::multiplies<T>(),f));
00326         return *this;
00327       }
00328   
00330       FixedMatrix operator/(T f) const{
00331         FixedMatrix d;
00332         std::transform(begin(),end(),d.begin(),std::bind2nd(std::divides<T>(),f));
00333         return d;
00334       }
00335   
00337       FixedMatrix &operator/=(T f){
00338         std::transform(begin(),end(),begin(),std::bind2nd(std::divides<T>(),f));
00339         return *this;
00340       }
00341   
00343       FixedMatrix operator+(const T &t) const{
00344         FixedMatrix d;
00345         std::transform(begin(),end(),d.begin(),std::bind2nd(std::plus<T>(),t));
00346         return d;
00347       }
00348   
00350       FixedMatrix &operator+=(const T &t){
00351         std::transform(begin(),end(),begin(),std::bind2nd(std::plus<T>(),t));
00352         return *this;
00353       }
00354   
00355   
00357       FixedMatrix operator-(const T &t) const{
00358         FixedMatrix d;
00359         std::transform(begin(),end(),d.begin(),std::bind2nd(std::minus<T>(),t));
00360         return d;
00361       }
00362   
00364       FixedMatrix &operator-=(const T &t){
00365         std::transform(begin(),end(),begin(),std::bind2nd(std::minus<T>(),t));
00366         return *this;
00367       }
00368   
00370       FixedMatrix operator+(const FixedMatrix &m) const{
00371         FixedMatrix d;
00372         std::transform(begin(),end(),m.begin(),d.begin(),std::plus<T>());
00373         return d;
00374       }
00375   
00377       FixedMatrix &operator+=(const FixedMatrix &m){
00378         std::transform(begin(),end(),m.begin(),begin(),std::plus<T>());
00379         return *this;
00380       }
00381   
00383       FixedMatrix operator-(const FixedMatrix &m) const{
00384         FixedMatrix d;
00385         std::transform(begin(),end(),m.begin(),d.begin(),std::minus<T>());
00386         return d;
00387       }
00389       FixedMatrix &operator-=(const FixedMatrix &m){
00390         std::transform(begin(),end(),m.begin(),begin(),std::minus<T>());
00391         return *this;
00392       }
00393   
00395 
00397       FixedMatrix operator-() const {
00398         FixedMatrix cpy(*this);
00399         std::transform(cpy.begin(),cpy.end(),cpy.begin(),std::negate<T>());
00400         return cpy;
00401       }
00402   
00403   
00405       T &operator()(unsigned int col,unsigned int row){
00406         return begin()[col+cols()*row];
00407       }
00408   
00410       const T &operator() (unsigned int col,unsigned int row) const{
00411         return begin()[col+cols()*row];
00412       }
00413   
00415       T &at(unsigned int col,unsigned int row) throw (InvalidIndexException){
00416         if(col>=cols() || row >= rows()) throw InvalidIndexException("row or col index too large");
00417         return begin()[col+cols()*row];
00418       }
00419   
00421       const T &at(unsigned int col,unsigned int row) const throw (InvalidIndexException){
00422         return const_cast<FixedMatrix*>(this)->at(col,row);
00423       }
00424       
00426 
00428       T &operator[](unsigned int idx){
00429         return begin()[idx];
00430       }
00432 
00434       const T &operator[](unsigned int idx) const{
00435         return begin()[idx];
00436       }
00437       
00438   
00440       typedef T* iterator;
00441       
00443       typedef const T* const_iterator;
00444   
00446       typedef T* row_iterator;
00447   
00449       typedef const T* const_row_iterator;
00450     
00452       static unsigned int rows(){ return ROWS; }
00453     
00455       static unsigned int cols(){ return COLS; }
00456   
00458       T *data() { return utils::FixedArray<T,COLS*ROWS>::m_data; }
00459   
00461       const T *data() const { return utils::FixedArray<T,COLS*ROWS>::m_data; }
00462   
00464       static unsigned int dim() { return DIM; }
00465     
00467       struct col_iterator : public std::iterator<std::random_access_iterator_tag,T>{
00468   
00470         typedef unsigned int difference_type;
00471         
00473         mutable T *p;
00474         
00476         static const unsigned int STRIDE = COLS;
00477         
00479         col_iterator(T *col_begin):p(col_begin){}
00480         
00482         col_iterator &operator++(){
00483           p+=STRIDE;
00484           return *this;
00485         }
00487         const col_iterator &operator++() const{
00488           p+=STRIDE;
00489           return *this;
00490         }
00492         col_iterator operator++(int){
00493           col_iterator tmp = *this;
00494           ++(*this);
00495           return tmp;
00496         }
00498         const col_iterator operator++(int) const{
00499           col_iterator tmp = *this;
00500           ++(*this);
00501           return tmp;
00502         }
00503   
00505         col_iterator &operator--(){
00506           p-=STRIDE;
00507           return *this;
00508         }
00509   
00511         const col_iterator &operator--() const{
00512           p-=STRIDE;
00513           return *this;
00514         }
00515   
00517         col_iterator operator--(int){
00518           col_iterator tmp = *this;
00519           --(*this);
00520           return tmp;
00521         }
00522   
00524         const col_iterator operator--(int) const{
00525           col_iterator tmp = *this;
00526           --(*this);
00527           return tmp;
00528         }
00529   
00531         col_iterator &operator+=(difference_type n){
00532           p += n * STRIDE;
00533           return *this;
00534         }
00535   
00537         const col_iterator &operator+=(difference_type n) const{
00538           p += n * STRIDE;
00539           return *this;
00540         }
00541   
00542   
00544         col_iterator &operator-=(difference_type n){
00545           p -= n * STRIDE;
00546           return *this;
00547         }
00548   
00550         const col_iterator &operator-=(difference_type n) const{
00551           p -= n * STRIDE;
00552           return *this;
00553         }
00554   
00555   
00557         col_iterator operator+(difference_type n) {
00558           col_iterator tmp = *this;
00559           tmp+=n;
00560           return tmp;
00561         }
00562   
00564         const col_iterator operator+(difference_type n) const{
00565           col_iterator tmp = *this;
00566           tmp+=n;
00567           return tmp;
00568         }
00569   
00571         col_iterator operator-(difference_type n) {
00572           col_iterator tmp = *this;
00573           tmp-=n;
00574           return tmp;
00575         }
00576   
00578         const col_iterator operator-(difference_type n) const {
00579           col_iterator tmp = *this;
00580           tmp-=n;
00581           return tmp;
00582         }
00583   
00585         difference_type operator-(const col_iterator &i) const{
00586           return (p-i.p)/STRIDE;
00587         }
00588         
00590         T &operator*(){
00591           return *p;
00592         }
00593   
00595         const T &operator*() const{
00596           return *p;
00597         }
00598   
00600         bool operator==(const col_iterator &i) const{ return p == i.p; }
00601   
00603         bool operator!=(const col_iterator &i) const{ return p != i.p; }
00604   
00606         bool operator<(const col_iterator &i) const{ return p < i.p; }
00607   
00609         bool operator<=(const col_iterator &i) const{ return p <= i.p; }
00610   
00612         bool operator>=(const col_iterator &i) const{ return p >= i.p; }
00613   
00615         bool operator>(const col_iterator &i) const{ return p > i.p; }
00616   
00617       };
00618     
00619       // const column operator typedef
00620       typedef const col_iterator const_col_iterator;
00621   
00623       iterator begin() { return utils::FixedArray<T,COLS*ROWS>::m_data; }
00624   
00626       iterator end() { return utils::FixedArray<T,COLS*ROWS>::m_data+dim(); }
00627     
00629       const_iterator begin() const { return utils::FixedArray<T,COLS*ROWS>::m_data; }
00630   
00632       const_iterator end() const { return utils::FixedArray<T,COLS*ROWS>::m_data+dim(); }
00633     
00635       col_iterator col_begin(unsigned int col) { return col_iterator(begin()+col); }
00636   
00638       col_iterator col_end(unsigned int col) { return col_iterator(begin()+col+dim()); }
00639     
00641       const_col_iterator col_begin(unsigned int col) const { return col_iterator(const_cast<T*>(begin())+col); }
00642   
00644       const_col_iterator col_end(unsigned int col) const { return col_iterator(const_cast<T*>(begin())+col+dim()); }
00645   
00647       row_iterator row_begin(unsigned int row) { return begin()+row*cols(); }
00648   
00650       row_iterator row_end(unsigned int row) { return begin()+(row+1)*cols(); }
00651   
00653       const_row_iterator row_begin(unsigned int row) const { return begin()+row*cols(); }
00654   
00656       const_row_iterator row_end(unsigned int row) const { return begin()+(row+1)*cols(); }
00657   
00659 
00671       template<unsigned int MCOLS>
00672       void mult(const FixedMatrix<T,MCOLS,COLS> &m,  FixedMatrix<T,MCOLS,ROWS> &dst) const{
00673         for(unsigned int c=0;c<MCOLS;++c){
00674           for(unsigned int r=0;r<ROWS;++r){
00675             //          std::cout << "calling inner_product" << std::endl;
00676             dst(c,r) = std::inner_product(m.col_begin(c),m.col_end(c),row_begin(r),T(0));
00677           }
00678         }      
00679       }
00681 
00704       template<unsigned int MCOLS>
00705       FixedMatrix<T,MCOLS,ROWS> operator*(const FixedMatrix<T,MCOLS,COLS> &m) const{
00706         FixedMatrix<T,MCOLS,ROWS> d;
00707         mult(m,d);
00708         return d;
00709       }
00710    
00711   
00712   
00714 
00720       FixedMatrix inv() const throw (InvalidMatrixDimensionException,SingularMatrixException){
00721         return FixedMatrix(dyn().inv().data());
00722       }
00723       
00725 
00728       T det() const throw(InvalidMatrixDimensionException){
00729         return dyn().det();
00730       }
00731     
00733       FixedMatrix<T,ROWS,COLS> transp() const{
00734         FixedMatrix<T,ROWS,COLS> d;
00735         for(unsigned int i=0;i<cols();++i){
00736           FixedMatrixBase::optimized_copy<const_col_iterator, typename FixedMatrix<T,ROWS,COLS>::row_iterator,DIM>(col_begin(i),col_end(i),d.row_begin(i));
00737           //        std::copy(col_begin(i),col_end(i),d.row_begin(i));
00738         }
00739         return d;
00740       }
00741   
00743 
00744       template<unsigned int OTHER_COLS>
00745       T element_wise_inner_product(const FixedMatrix<T,OTHER_COLS,DIM/OTHER_COLS> &other) const {
00746         return std::inner_product(begin(),end(),other.begin(),T(0));
00747       }
00748   
00749   
00751 
00754       template<unsigned int OTHER_COLS>
00755       FixedMatrix<T,OTHER_COLS,COLS> dot(const FixedMatrix<T,OTHER_COLS,ROWS> &M) const{
00756         return this->transp() * M;
00757       }
00758       
00760       double cond(const double p=2) const {
00761         DynMatrix<T> mat = this->dyn();
00762         return mat.cond();
00763       }
00764   
00766       T trace() const{
00767         ICLASSERT_RETURN_VAL(COLS==ROWS,0);
00768         double accu = 0;
00769         for(int i=0;i<DIM;i+=COLS+1){
00770           accu += begin()[i];
00771         }
00772         return accu;
00773       }
00774   
00776       FixedMatrixPart<T,COLS,row_iterator> row(unsigned int idx){
00777         return FixedMatrixPart<T,COLS,row_iterator>(row_begin(idx),row_end(idx));
00778       }
00779   
00781       FixedMatrixPart<T,COLS,const_row_iterator> row(unsigned int idx) const{
00782         return FixedMatrixPart<T,COLS,const_row_iterator>(row_begin(idx),row_end(idx));
00783       }
00784   
00786       FixedMatrixPart<T,ROWS,col_iterator> col(unsigned int idx){
00787         return FixedMatrixPart<T,ROWS,col_iterator>(col_begin(idx),col_end(idx));
00788       }
00789   
00791       FixedMatrixPart<T,ROWS,const_col_iterator> col(unsigned int idx) const{
00792         return FixedMatrixPart<T,ROWS,const_col_iterator>(col_begin(idx),col_end(idx));
00793       }
00794   
00796       template<unsigned int X,unsigned int Y,unsigned int WIDTH,unsigned int HEIGHT>
00797       FixedMatrixPart<T,WIDTH*HEIGHT,MatrixSubRectIterator<T> > part(){
00798         return FixedMatrixPart<T,WIDTH*HEIGHT,MatrixSubRectIterator<T> >( 
00799                    MatrixSubRectIterator<T>(begin(),COLS,X,Y,WIDTH,HEIGHT),
00800                    MatrixSubRectIterator<T>::create_end_iterator(begin(),COLS,X,Y,WIDTH,HEIGHT));
00801       }
00802   
00804       template<unsigned int X,unsigned int Y,unsigned int WIDTH,unsigned int HEIGHT>
00805       const FixedMatrixPart<T,WIDTH*HEIGHT,MatrixSubRectIterator<T> > part() const{
00806         return const_cast<FixedMatrix<T,COLS,ROWS>*>(this)->part<X,Y,WIDTH,HEIGHT>();
00807       }
00808       
00810 
00815       template<unsigned int NEW_WIDTH,unsigned int NEW_HEIGHT>
00816       inline FixedMatrix<T,NEW_WIDTH,NEW_HEIGHT> resize(const T &init=T(0)) const {
00817         FixedMatrix<T,NEW_WIDTH,NEW_HEIGHT> M(init);
00818         for(unsigned int x=0;x<COLS && x < NEW_WIDTH; ++x){
00819           for(unsigned int y=0;y<ROWS && y < NEW_HEIGHT; ++y){
00820             M(x,y) = (*this)(x,y);
00821           }
00822         }
00823         return M;
00824       }
00825       
00827 
00831       static FixedMatrix<T,ROWS,COLS> id(){
00832         FixedMatrix<T,ROWS,COLS> m(T(0));
00833         for(unsigned int i=0;i<ROWS && i<COLS;++i){
00834           m(i,i) = 1;
00835         }
00836         return m;
00837       }
00838   
00840       inline double length(T norm=2) const{ 
00841         double sumSquares = 0;
00842         for(unsigned int i=0;i<DIM;++i){
00843           sumSquares += ::pow((*this)[i],(double)norm);
00844         }
00845         return ::pow( sumSquares, 1.0/norm);
00846       }
00847   
00849       inline void normalize(T norm=2){
00850         T l = (T)length(norm);
00851         if(l) (*this) /= l;
00852       }
00853       
00855       inline FixedMatrix<T,COLS,ROWS> normalized(T norm=2) const{
00856         T l = (T)length(norm);
00857         return l ?  (*this)/l : *this;
00858       }
00859   
00861       template<class otherT>
00862       bool operator==(const FixedMatrix<otherT,COLS,ROWS> &m) const{
00863         for(unsigned int i=0;i<DIM;++i){
00864           if(begin()[i] != m[i]) return false;
00865         }
00866         return true;
00867       }    
00869       template<class otherT>
00870       bool operator!=(const FixedMatrix<otherT,COLS,ROWS> &m) const{
00871         return !this->operator==(m);
00872       }   
00873   
00874   
00876       FixedMatrix<T,1,ROWS> diag() const throw (InvalidMatrixDimensionException){
00877         if(ROWS != COLS) throw InvalidMatrixDimensionException("trace is only possible for sqaure matrices");
00878         FixedMatrix<T,1,ROWS> t;
00879         for(unsigned int i=0;i<ROWS;++i){
00880           t[i] = (*this)(i,i);
00881         }
00882         return t;
00883       }
00884   
00886 
00887       void decompose_QR(FixedMatrix<T,COLS,ROWS> &Q, FixedMatrix<T,COLS,COLS> &R) const{
00888         DynMatrix<T> Qd = Q.dyn(), Rd = R.dyn();
00889         dyn().decompose_QR(Qd,Rd);
00890       }
00891       
00893 
00894       void decompose_RQ(FixedMatrix<T,ROWS,ROWS> &R, FixedMatrix<T,ROWS,ROWS> &Q) const{
00895         DynMatrix<T> Rd = R.dyn(), Qd = Q.dyn();
00896         dyn().decompose_RQ(Rd,Qd);
00897       }
00898       
00900 
00901       void svd(FixedMatrix<T,COLS,ROWS> &U, FixedMatrix<T,1,COLS> &s, FixedMatrix<T,COLS,COLS> &V) const{
00902         DynMatrix<T> Ud = U.dyn(), sd = s.dyn(), Vd = V.dyn();
00903         return dyn().svd(Ud,sd,Vd);
00904       }
00905       
00907 
00908       FixedMatrix<T,ROWS,COLS> pinv(bool useSVD=0, float zeroThreshold=0.00000000000000001) const {
00909         return FixedMatrix<T,ROWS,COLS>(dyn().pinv(useSVD,zeroThreshold).begin());
00910       }
00911       
00913 
00926       void eigen(FixedMatrix &eigenvectors, FixedMatrix<T,1,COLS> &eigenvalues) const{
00927         if(ROWS != COLS) throw InvalidMatrixDimensionException("eigenvalue decomposition is only possible for sqaure matrices (use svd instead!)");
00928         DynMatrix<T> evecs = eigenvectors.dyn(), evals = eigenvalues.dyn();
00929         return dyn().eigen(evecs,evals);
00930       }
00931       
00932       
00933     };
00934   
00936 
00937     template<class T,unsigned  int WIDTH,unsigned  int HEIGHT, unsigned int HEIGHT2>
00938     inline FixedMatrix<T,WIDTH,HEIGHT+HEIGHT2> operator%(const FixedMatrix<T,WIDTH,HEIGHT> &a,
00939                                                          const FixedMatrix<T,WIDTH,HEIGHT2> &b){
00940       FixedMatrix<T,WIDTH,HEIGHT+HEIGHT2> M;
00941       for(unsigned int i=0;i<HEIGHT;++i) M.row(i) = a.row(i);
00942       for(unsigned int i=0;i<HEIGHT2;++i) M.row(i+HEIGHT) = b.row(i);
00943       return M;
00944     }
00945   
00947 
00948     template<class T,unsigned  int WIDTH,unsigned  int HEIGHT, unsigned int WIDTH2>
00949     inline FixedMatrix<T,WIDTH+WIDTH2,HEIGHT> operator,(const FixedMatrix<T,WIDTH,HEIGHT> &a,
00950                                                          const FixedMatrix<T,WIDTH2,HEIGHT> &b){
00951       FixedMatrix<T,WIDTH+WIDTH2,HEIGHT> M;
00952       for(unsigned int i=0;i<WIDTH;++i) M.col(i) = a.col(i);
00953       for(unsigned int i=0;i<WIDTH2;++i) M.col(i+WIDTH) = b.col(i);
00954       return M;
00955     }
00956    
00957   
00958   
00959   
00961 
00963     template<class T, unsigned int M_ROWS_AND_COLS,unsigned int V_COLS>
00964     inline FixedMatrix<T,V_COLS,M_ROWS_AND_COLS> &operator*=(FixedMatrix<T,V_COLS,M_ROWS_AND_COLS> &v,
00965                                                              const FixedMatrix<T,M_ROWS_AND_COLS,M_ROWS_AND_COLS> &m){
00966       return v = (m*v);
00967     } 
00968   
00970 
00971     template<class T, unsigned int COLS, unsigned int ROWS>
00972     inline std::ostream &operator<<(std::ostream &s,const FixedMatrix<T,COLS,ROWS> &m){
00973       return s << m.dyn();
00974     }
00975   
00977 
00978     template<class T, unsigned int COLS, unsigned int ROWS>
00979     inline std::istream &operator>>(std::istream &s,FixedMatrix<T,COLS,ROWS> &m){
00980       DynMatrix<T> dyn = m.dyn();
00981       return s >> dyn;
00982     }
00983   
00984   
00986     template<class T>
00987     FixedMatrix<T,2,2> create_rot_2D(T angle);
00988   
00990     template<class T>
00991     FixedMatrix<T,3,3> create_hom_3x3(T angle, T dx=0, T dy=0, T v0=0, T v1=0);
00992   
00994     template<class T>
00995     inline FixedMatrix<T,3,3> create_hom_3x3_trans(T dx, T dy){
00996       FixedMatrix<T,3,3> m = FixedMatrix<T,3,3>::id();
00997       m(2,0)=dx;
00998       m(2,1)=dy;
00999       return m;
01000     }
01001     
01002   
01004     template<class T>
01005     FixedMatrix<T,3,3> create_rot_3D(T axisX, T axisY, T axisZ, T angle);
01006     
01008     template<class T>
01009     FixedMatrix<T,3,3> create_rot_3D(T rx,T ry,T rz);
01010   
01012     template<class T>
01013     FixedMatrix<T,4,4> create_hom_4x4(T rx, T ry, T rz, T dx=0, T dy=0, T dz=0, T v0=0, T v1=0, T v2=0);
01014   
01016     template<class T>
01017     FixedMatrix<T,4,4> create_rot_4x4(T axisX, T axisY, T axisZ, T angle);
01018   
01019   
01021     template<class T>
01022     inline FixedMatrix<T,4,4> create_hom_4x4_trans(T dx, T dy, T dz){
01023       FixedMatrix<T,4,4> m = FixedMatrix<T,4,4>::id();
01024       m(3,0)=dx;
01025       m(3,1)=dy;
01026       m(3,2)=dy;
01027       return m;
01028     }
01029   
01031 
01035     template<class T,unsigned int COLS, unsigned int ROWS>
01036     FixedMatrix<T,1,3> extract_euler_angles(const FixedMatrix<T,COLS,ROWS> &m) throw (InvalidMatrixDimensionException){
01037       ICLASSERT_THROW(COLS>2 && ROWS>2,InvalidMatrixDimensionException("extract_euler_angles needs a matrix that has at least 3 rows and columns"));
01038       if( m(1,2) > -0.999999 && m(1,2) < 0.999999){ //avoid Gimbal lock
01039         return FixedMatrix<T,1,3>(asin(m(1,2)),atan2(m(0,2),m(2,2)),atan2(m(1,0),m(1,1)));
01040       }else{
01041         return FixedMatrix<T,1,3>(-M_PI/2,0,-atan2(m(0,1),m(0,0)));
01042       }
01043     }
01044   
01045     
01047     template<class T,unsigned int N, class Iterator> template<unsigned int COLS>
01048     inline FixedMatrixPart<T,N,Iterator>& FixedMatrixPart<T,N,Iterator>::operator=(const FixedMatrix<T,COLS,N/COLS> &m){
01049       FixedMatrixBase::optimized_copy<const T*,Iterator,N>(m.begin(),m.end(),begin);
01050       //std::copy(m.begin(),m.end(),begin);
01051       return *this;
01052     }
01053     template<class T,unsigned int N, class Iterator> template<class T2, unsigned int COLS>
01054     inline FixedMatrixPart<T,N,Iterator>& FixedMatrixPart<T,N,Iterator>::operator=(const FixedMatrix<T2,COLS,N/COLS> &m){
01055       std::transform(m.begin(),m.end(),begin,utils::clipped_cast<T2,T>);
01056       return *this;
01057     }
01060   #ifdef HAVE_IPP
01061   #define OPTIMIZED_MATRIX_MULTIPLICATION(LEFT_COLS,LEFT_ROWS,RIGHT_COLS,TYPE,IPPSUFFIX) \
01062     template<> template<>                                                                \
01063     inline void                                                                          \
01064     FixedMatrix<TYPE,RIGHT_COLS,LEFT_ROWS>::mult                                         \
01065        (                                                                                 \
01066           const FixedMatrix<TYPE,RIGHT_COLS,LEFT_COLS> &m,                               \
01067           FixedMatrix<TYPE,RIGHT_COLS,LEFT_ROWS> &dst                                    \
01068        ) const {                                                                         \
01069       static const unsigned int ST=sizeof(TYPE);                                         \
01070       ippmMul_mm_##IPPSUFFIX(data(),LEFT_COLS*ST,ST,LEFT_COLS,LEFT_ROWS,                 \
01071                              m.data(),RIGHT_COLS*ST,ST,RIGHT_COLS,LEFT_COLS,             \
01072                              dst.data(),RIGHT_COLS*ST,ST);                               \
01073     }
01074   
01075     OPTIMIZED_MATRIX_MULTIPLICATION(2,2,2,float,32f);
01076     OPTIMIZED_MATRIX_MULTIPLICATION(3,3,3,float,32f);  
01077     OPTIMIZED_MATRIX_MULTIPLICATION(4,4,4,float,32f);
01078   
01079     OPTIMIZED_MATRIX_MULTIPLICATION(2,2,2,double,64f);
01080     OPTIMIZED_MATRIX_MULTIPLICATION(3,3,3,double,64f);  
01081     OPTIMIZED_MATRIX_MULTIPLICATION(4,4,4,double,64f);
01082   #undef OPTIMIZED_MATRIX_MULTIPLICATION
01083    
01084   
01085   #endif
01086   
01087   #define USE_OPTIMIZED_INV_AND_DET_FOR_2X2_3X3_AND_4X4_MATRICES
01088   
01089   #ifdef USE_OPTIMIZED_INV_AND_DET_FOR_2X2_3X3_AND_4X4_MATRICES
01090   
01092     // this functions are implemented in iclFixedMatrix.cpp. All templates are
01093     // instantiated for float and double
01094   
01095     template<class T> 
01096     void icl_util_get_fixed_4x4_matrix_inv(const T *src, T*dst);
01097     template<class T> 
01098     void icl_util_get_fixed_3x3_matrix_inv(const T *src, T*dst);
01099     template<class T> 
01100     void icl_util_get_fixed_2x2_matrix_inv(const T *src, T*dst);
01101   
01102     template<class T> 
01103     T icl_util_get_fixed_4x4_matrix_det(const T *src);
01104     template<class T> 
01105     T icl_util_get_fixed_3x3_matrix_det(const T *src);
01106     template<class T> 
01107     T icl_util_get_fixed_2x2_matrix_det(const T *src);
01108   
01109   #define SPECIALISED_MATRIX_INV_AND_DET(D,T) \
01110     template<>                                                            \
01111     inline FixedMatrix<T,D,D> FixedMatrix<T,D,D>::inv() const             \
01112     throw (InvalidMatrixDimensionException,SingularMatrixException){      \
01113       FixedMatrix<T,D,D> r;                                               \
01114       icl_util_get_fixed_##D##x##D##_matrix_inv<T>(begin(),r.begin());    \
01115       return r;                                                           \
01116     }                                                                     \
01117     template<>                                                            \
01118     inline T FixedMatrix<T,D,D>::det() const                              \
01119     throw(InvalidMatrixDimensionException){                               \
01120       return icl_util_get_fixed_##D##x##D##_matrix_det<T>(begin());       \
01121     }
01122   
01123   
01124     SPECIALISED_MATRIX_INV_AND_DET(2,float);
01125     SPECIALISED_MATRIX_INV_AND_DET(3,float);
01126     SPECIALISED_MATRIX_INV_AND_DET(4,float);
01127     SPECIALISED_MATRIX_INV_AND_DET(2,double);
01128     SPECIALISED_MATRIX_INV_AND_DET(3,double);
01129     SPECIALISED_MATRIX_INV_AND_DET(4,double);
01130   
01131   
01132   #undef SPECIALISED_MATRIX_INV_AND_DET
01133     
01135   #endif
01136   
01137   
01138   } // namespace math
01139 }
01140 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines