rtcMat.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009
00003  * Robert Bosch LLC
00004  * Research and Technology Center North America
00005  * Palo Alto, California
00006  *
00007  * All rights reserved.
00008  *
00009  *------------------------------------------------------------------------------
00010  * project ....: Autonomous Technologies
00011  * file .......: rtcMat.h
00012  * authors ....: Benjamin Pitzer
00013  * organization: Robert Bosch LLC
00014  * creation ...: 08/16/2006
00015  * modified ...: $Date: 2009-03-19 11:10:08 -0700 (Thu, 19 Mar 2009) $
00016  * changed by .: $Author: wg75pal $
00017  * revision ...: $Revision: 101 $
00018  */
00019 #ifndef RTC_MAT_H
00020 #define RTC_MAT_H
00021 
00022 //== INCLUDES ==================================================================
00023 #include "rtc/rtcOutputHandler.h"
00024 #include "rtc/rtcInputHandler.h"
00025 #include "rtc/rtcMath.h"
00026 #include "rtc/rtcVec.h"
00027 #include "rtc/rtcSMat.h"
00028 
00029 //== NAMESPACES ================================================================
00030 namespace rtc {
00031 
00032 // Forward declarations
00033 template <class T, int M> class Vec; // M-d vector
00034 template <class T, int M, int N> class Mat; // MxN Matrix
00035 template <class T, int M> class SMat; // MxM Matrix
00036 
00040 template <class T, int M, int N>
00041 class Mat {
00042 public:
00043   // Data
00044   T x[M*N]; 
00045 
00046   // Constructors
00047   Mat();
00048   Mat(const T* d);
00049   Mat(const T a);
00050   Mat(const Mat<T,M,N>& m);
00051 
00052   // Cast Operation
00053   template <class U> Mat(const Mat<U,M,N>& m);
00054 
00055   // Mutators
00056   void set(const T* d);
00057   void set(const T a);
00058   void set(const Mat<T,M,N>& m);
00059   Mat<T,M,N>& operator = (const T* d);
00060   Mat<T,M,N>& operator = (const T a);
00061   Mat<T,M,N>& operator = (const Mat<T,M,N>& m);
00062   void setRow(const int i, const Vec<T,N>& v);
00063   void setCol(const int j, const Vec<T,M>& v);
00064   template <int P, int Q> void setSubMat(const int r, const int c, const Mat<T,P,Q>& m);
00065 
00066   // Casting Mutators
00067   template <class U> void set(const Mat<U,M,N>& m);
00068   template <class U> Mat<T,M,N>& operator = (const Mat<U,M,N>& m);
00069 
00070   // Accessors
00071   T operator () (const int r, const int c) const;
00072   T& operator () (const int r, const int c);
00073   Vec<T,N> getRow(int r) const;
00074   Vec<T,M> getCol(int c) const;
00075   template <int P, int Q> Mat<T,P,Q> getSubMat(const int i, const int j);
00076 
00077   // Addition and subtraction: <matrix> +/- <matrix>
00078   Mat<T,M,N>& add(const Mat<T,M,N>& m);
00079   Mat<T,M,N>& subtract(const Mat<T,M,N>& m);
00080   Mat<T,M,N> operator + (const Mat<T,M,N>& m) const;
00081   void operator += (const Mat<T,M,N>& m);
00082   Mat<T,M,N> operator - (const Mat<T,M,N>& m) const;
00083   void operator -= (const Mat<T,M,N>& m);
00084   Mat<T,M,N> operator - () const;
00085 
00086   // Addition and subtraction: <matrix> +/- <scalar>
00087   Mat<T,M,N>& add(const T a);
00088   Mat<T,M,N>& subtract(const T a);
00089   Mat<T,M,N> operator + (const T a) const;
00090   void operator += (const T a);
00091   Mat<T,M,N> operator - (const T a) const;
00092   void operator -= (const T a);
00093 
00094   // Multiplication and division: <matrix> *// <scalar>
00095   Mat<T,M,N> operator * (const T a) const;
00096   void operator *= (const T a);
00097   Mat<T,M,N> operator / (const T a) const;
00098   void operator /= (const T a);
00099 
00100   // Multiplication: <matrix> * <vector>
00101   Vec<T,M> operator * (const Vec<T,N>& v) const;
00102   template <int P> Mat<T,M,P> operator * (const Mat<T,N,P>& m) const;
00103   void operator *= (const Mat<T,N,N>& m);
00104 
00105   // Equality and inequality tests
00106   Mat<bool,M,N> operator == (const Mat<T,M,N>& m) const;
00107   Mat<bool,M,N> operator != (const Mat<T,M,N>& m) const;
00108   Mat<bool,M,N> operator >= (const Mat<T,M,N>& m) const;
00109   Mat<bool,M,N> operator <= (const Mat<T,M,N>& m) const;
00110   Mat<bool,M,N> operator > (const Mat<T,M,N>& m) const;
00111   Mat<bool,M,N> operator < (const Mat<T,M,N>& m) const;
00112   int compareTo(const Mat<T,M,N>& m) const;
00113   bool equalTo(const Mat<T,M,N>& m, const T tol = T(0)) const;
00114 
00115   // Other matrix operations
00116   Mat<T,N,M> transposed() const;
00117 
00118   // Random matrix
00119   static Mat<T,M,N> uniformRand(const T a = T(0), const T b = T(1));
00120   static Mat<T,M,N> normalRand(const T mean = T(0), const T stdev = T(1));
00121   static Mat<T,M,N> multivariateGauss(const Vec<T,M>& mean, const SMat<T,M>& cov);
00122 
00123   // General elementwise operations
00124   void perform(T (*mathFun)(T));
00125   //void perform(T (*mathFun)(T,T), const T arg2);
00126   //void perform(T (*mathFun)(T,T), const Vec<T,M>& v);
00127   //Vec<T,M> performed(T (*mathFun)(T));
00128   //Vec<T,M> performed(T (*mathFun)(T,T), const T arg2);
00129   //Vec<T,M> performed(T (*mathFun)(T,T), const Vec<T,M>& v);
00130 
00131   // Reductions: Max/Min, Sum/Product
00132   //T max() const;
00133   //T min() const;
00134   Vec<T,N> sum() const;
00135   //T prod() const;
00136 
00137   // Bilinear Interpolation
00138   T interpolate(const float i, const float j) const;
00139 
00140   // statistical operations
00141   Vec<T,N> meanOfRows() const;
00142   SMat<T,N> covarianceMatrixOfRows() const;
00143 
00144   // Serialization
00145   bool write(OutputHandler& oh) const;
00146   bool read(InputHandler& ih);
00147 };
00148 
00149 // Global operators to for cases where Mat<T,M,N>
00150 // is the second argument in a binary operator
00151 template <class T, int M, int N> Mat<T,M,N> operator * (const T a, const Mat<T,M,N> &m);
00152 template <class T, int M, int N> Vec<T,N> operator * (const Vec<T,M>& v, const Mat<T,M,N> &m);
00153 
00154 // ASCII stream IO
00155 template <class T, int M, int N> std::ostream& operator<<(std::ostream& os, const Mat<T,M,N>& vec);
00156 template <class T, int M, int N> std::istream& operator>>(std::istream& is, Mat<T,M,N>& vec);
00157 
00158 
00159 //==============================================================================
00160 // Mat<T,M,N>
00161 //==============================================================================
00162 
00163 // Constructors
00164 
00167 template <class T, int M, int N>
00168 inline Mat<T,M,N>::Mat() {}
00169 
00173 template <class T, int M, int N>
00174 inline Mat<T,M,N>::Mat(const T* d) {
00175   set(d);
00176 }
00177 
00181 template <class T, int M, int N>
00182 inline Mat<T,M,N>::Mat(const T a) {
00183   set(a);
00184 }
00185 
00189 template <class T, int M, int N>
00190 inline Mat<T,M,N>::Mat(const Mat<T,M,N>& m) {
00191   set(m);
00192 }
00193 
00194 // Casting Operation
00195 
00199 template <class T, int M, int N> template <class U>
00200 inline Mat<T,M,N>::Mat(const Mat<U,M,N>& m) {
00201   set<U>(m);
00202 }
00203 
00204 // Mutators
00205 
00209 template <class T, int M, int N>
00210 inline void Mat<T,M,N>::set(const T* d) {
00211   for (int k=0;k<M*N;k++) x[k] = d[k];
00212 }
00213 
00217 template <class T, int M, int N>
00218 inline void Mat<T,M,N>::set(const T a) {
00219   if (a == T(0)) memset(x,0,M*N*sizeof(T));
00220   else for (int i=0;i<M*N;++i) x[i] = a;
00221 }
00222 
00226 template <class T, int M, int N>
00227 inline void Mat<T,M,N>::set(const Mat<T,M,N>& m) {
00228   memcpy((void*)x,(void*)m.x,M*N*sizeof(T));
00229 }
00230 
00234 template <class T, int M, int N>
00235 inline Mat<T,M,N>& Mat<T,M,N>::operator = (const T* d) {
00236   set(d);
00237   return *this;
00238 }
00239 
00243 template <class T, int M, int N>
00244 inline Mat<T,M,N>& Mat<T,M,N>::operator = (const T a) {
00245   set(a);
00246   return *this;
00247 }
00248 
00252 template <class T, int M, int N>
00253 inline Mat<T,M,N>& Mat<T,M,N>::operator = (const Mat<T,M,N>& m) {
00254   set(m);
00255   return *this;
00256 }
00257 
00263 template <class T, int M, int N>
00264 inline void Mat<T,M,N>::setRow(const int i, const Vec<T,N>& v) {
00265 #if MATMATH_CHECK_BOUNDS
00266   if (i < 0 || i > M) {
00267     std::stringstream ss;
00268     ss << "Mat<" << M << "," << N << ">::setRow(" << i;
00269     ss << ", v): index out of range\n";
00270     ss << std::flush;
00271     throw Exception(ss.str());
00272   }
00273 #endif
00274   for (int j=0,k=i*N;j<N;j++,k++) x[k] = v.x[j];
00275 }
00276 
00282 template <class T, int M, int N>
00283 inline void Mat<T,M,N>::setCol(const int j, const Vec<T,M>& v) {
00284 #if MATMATH_CHECK_BOUNDS
00285   if (j < 0 || j > N) {
00286     std::stringstream ss;
00287     ss << "Mat<" << M << "," << N << ">::setCol(" << j;
00288     ss << ", v) out of range\n";
00289     ss << std::flush;
00290     throw Exception(ss.str());
00291   }
00292 #endif
00293   for (int i=0,k=j;i<M;i++,k+=N) x[k] = v.x[i];
00294 }
00295 
00302 template <class T, int M, int N> template <int P, int Q>
00303 inline void Mat<T,M,N>::setSubMat(const int i, const int j,
00304           const Mat<T,P,Q>& m) {
00305 #if MATMATH_CHECK_BOUNDS
00306   if (i < 0 || i+P > M || j < 0 || j+Q > N) {
00307     std::stringstream ss;
00308     ss << "Mat<" << M << "," << N << ">::setSubMat(" << i;
00309     ss << ", " << j << ", m): index out of range\n";
00310     ss << std::flush;
00311     throw Exception(ss.str());
00312   }
00313 #endif
00314   for (int id=i,is=0;id<M && is<P;id++,is++)
00315     for (int jd=j,js=0;jd<N && js<Q;jd++,js++)
00316 x[id*N+jd] = m.x[is*Q+js];
00317 }
00318 
00319 // Casting Mutators
00320 
00324 template <class T, int M, int N> template <class U>
00325 inline void Mat<T,M,N>::set(const Mat<U,M,N>& m) {
00326   for (int k=0;k<M*N;k++) x[k] = T(m.x[k]);
00327 }
00328 
00332 template <class T, int M, int N> template <class U>
00333 inline Mat<T,M,N>& Mat<T,M,N>::operator = (const Mat<U,M,N>& m) {
00334   set<U>(m);
00335 }
00336 
00337 // Accessors
00338 
00345 template <class T, int M, int N>
00346 inline T Mat<T,M,N>::operator () (const int i, const int j) const {
00347 #if MATMATH_CHECK_BOUNDS
00348   if (i<0 || i>M || j<0 || j>N) {
00349     std::stringstream ss;
00350     ss << "Mat<" << M << "," << N << ">::operator (" << i;
00351     ss << ", " << j << "): index out of range\n";
00352     ss << std::flush;
00353     throw Exception(ss.str());
00354   }
00355 #endif
00356   return x[i*N + j];
00357 }
00358 
00365 template <class T, int M, int N>
00366 inline T& Mat<T,M,N>::operator () (const int i, const int j) {
00367 #if MATMATH_CHECK_BOUNDS
00368   if (i<0 || i>M || j<0 || j>N) {
00369     std::stringstream ss;
00370     ss << "&Mat<" << M << "," << N << ">::operator (" << i;
00371     ss << ", " << j << "): index out of range\n";
00372     ss << std::flush;
00373     rtc::Exception e(ss.str());
00374     throw e;
00375   }
00376 #endif
00377   return x[i*N + j];
00378 }
00379 
00384 template <class T, int M, int N>
00385 inline Vec<T,N> Mat<T,M,N>::getRow(int i) const {
00386 #if MATMATH_CHECK_BOUNDS
00387   if (i < 0 || i >= M) {
00388     std::stringstream ss;
00389     ss << "Mat<" << M << "," << N << ">::getRow(" << i;
00390     ss << "): index out of range\n";
00391     ss << std::cerr << std::flush;
00392     throw Exception(ss.str());
00393   }
00394 #endif
00395   Vec<T,N> v;
00396   for (int j=0,k=i*N;j<N;j++,k++) v.x[j] = x[k];
00397   return v;
00398 }
00399 
00404 template <class T, int M, int N>
00405 inline Vec<T,M> Mat<T,M,N>::getCol(int j) const {
00406 #if MATMATH_CHECK_BOUNDS
00407   if (j < 0 || j >= N) {
00408     std::stringstream ss;
00409     ss << "Mat<" << M << "," << N << ">::getCol(" << j;
00410     ss << "): index out of range\n";
00411     ss << std::flush;
00412     throw Exception(ss.str());
00413   }
00414 #endif
00415   Vec<T,M> v;
00416   for (int i=0,k=j;i<M;i++,k+=N) v.x[i] = x[k];
00417   return v;
00418 }
00419 
00425 template <class T, int M, int N> template <int P, int Q>
00426 inline Mat<T,P,Q> Mat<T,M,N>::getSubMat(const int i, const int j) {
00427 #if MATMATH_CHECK_BOUNDS
00428   if (i < 0 || i+P > M || j < 0 || j+Q > N) {
00429     std::stringstream ss;
00430     ss << "Mat<" << M << "," << N << ">::getSubMat(" << i;
00431     ss << ", " << j << "): index out of range\n";
00432     ss << std::flush;
00433     throw Exception(ss.str());
00434   }
00435 #endif
00436   Mat<T,P,Q> m(T(0));
00437   for (int id=i,is=0;id<M && is<P;id++,is++)
00438     for (int jd=j,js=0;jd<N && js<Q;jd++,js++)
00439 m.x[is*Q+js] = x[id*N+jd];
00440   return m;
00441 }
00442 
00443 // Addition and subtraction: <matrix> +/- <matrix>
00444 
00447 template <class T, int M, int N>
00448 inline Mat<T,M,N>& Mat<T,M,N>::add(const Mat<T,M,N>& m) {
00449   for (int k=0;k<M*N;k++) x[k] = x[k] + m.x[k];
00450   return *this;
00451 }
00452 
00455 template <class T, int M, int N>
00456 inline Mat<T,M,N>& Mat<T,M,N>::subtract(const Mat<T,M,N>& m) {
00457   for (int k=0;k<M*N;k++) x[k] = x[k] - m.x[k];
00458   return *this;
00459 }
00460 
00461 // Addition and subtraction operators: <matrix> +/- <matrix>
00462 
00465 template <class T, int M, int N>
00466 inline Mat<T,M,N> Mat<T,M,N>::operator + (const Mat<T,M,N>& m) const {
00467   Mat<T,M,N> mp;
00468   for (int k=0;k<M*N;k++) mp.x[k] = x[k] + m.x[k];
00469   return mp;
00470 }
00471 
00474 template <class T, int M, int N>
00475 inline void Mat<T,M,N>::operator += (const Mat<T,M,N>& m) {
00476   for (int k=0;k<M*N;k++) x[k] += m.x[k];
00477 }
00478 
00481 template <class T, int M, int N>
00482 inline Mat<T,M,N> Mat<T,M,N>::operator - (const Mat<T,M,N>& m) const {
00483   Mat<T,M,N> mp;
00484   for (int k=0;k<M*N;k++) mp.x[k] = x[k] - m.x[k];
00485   return mp;
00486 }
00487 
00490 template <class T, int M, int N>
00491 inline void Mat<T,M,N>::operator -= (const Mat<T,M,N>& m) {
00492   for (int k=0;k<M*N;k++) x[k] -= m.x[k];
00493 }
00494 
00497 template <class T, int M, int N>
00498 inline Mat<T,M,N> Mat<T,M,N>::operator - () const {
00499   Mat<T,M,N> mp;
00500   for (int k=0;k<M*N;k++) mp.x[k] = -x[k];
00501   return mp;
00502 }
00503 
00504 // Addition and subtraction: <matrix> +/- <scalar>
00505 
00508 template <class T, int M, int N>
00509 inline Mat<T,M,N>& Mat<T,M,N>::add(const T a) {
00510   for (int k=0;k<M*N;k++) x[k] = x[k] + a;
00511   return *this;
00512 }
00513 
00516 template <class T, int M, int N>
00517 inline Mat<T,M,N>& Mat<T,M,N>::subtract(const T a) {
00518   for (int k=0;k<M*N;k++) x[k] = x[k] - a;
00519   return *this;
00520 }
00521 
00522 // Addition and subtraction operators: <matrix> +/- <scalar
00523 
00526  template <class T, int M, int N>
00527  inline Mat<T,M,N> Mat<T,M,N>::operator + (const T a) const {
00528    Mat<T,M,N> mp;
00529    for (int k=0;k<M*N;k++) mp.x[k] = x[k] + a;
00530    return mp;
00531  }
00532 
00535  template <class T, int M, int N>
00536  inline void Mat<T,M,N>::operator += (const T a) {
00537    for (int k=0;k<M*N;k++) x[k] += a;
00538  }
00539 
00542  template <class T, int M, int N>
00543  inline Mat<T,M,N> Mat<T,M,N>::operator - (const T a) const {
00544    Mat<T,M,N> mp;
00545    for (int k=0;k<M*N;k++) mp.x[k] = x[k] - a;
00546    return mp;
00547  }
00548 
00551  template <class T, int M, int N>
00552  inline void Mat<T,M,N>::operator -= (const T a) {
00553    for (int k=0;k<M*N;k++) x[k] -= a;
00554  }
00555 
00556 // Multiplication and division: <matrix> *// <scalar>
00557 
00560 template <class T, int M, int N>
00561 inline Mat<T,M,N> Mat<T,M,N>::operator * (const T a) const {
00562   Mat<T,M,N> m;
00563   for (int k=0;k<M*N;k++) m.x[k] = x[k]*a;
00564   return m;
00565 }
00566 
00569 template <class T, int M, int N>
00570 inline void Mat<T,M,N>::operator *= (const T a) {
00571   for (int k=0;k<M*N;k++) x[k] *= a;
00572 }
00573 
00576 template <class T, int M, int N>
00577 inline Mat<T,M,N> Mat<T,M,N>::operator / (const T a) const {
00578   Mat<T,M,N> m;
00579   for (int k=0;k<M*N;k++) m.x[k] = x[k]/a;
00580   return m;
00581 }
00582 
00585 template <class T, int M, int N>
00586 inline void Mat<T,M,N>::operator /= (const T a) {
00587   for (int k=0;k<M*N;k++) x[k] /= a;
00588 }
00589 
00592 template <class T, int M, int N>
00593 Mat<T,M,N> operator * (const T a, const Mat<T,M,N> &m) {
00594   Mat<T,M,N> mp;
00595   for (int k=0;k<M*N;k++) mp.x[k] = m.x[k]*a;
00596   return mp;
00597 }
00598 
00599 // Multiplication: <matrix> * <vector>
00600 
00603 template <class T, int M, int N>
00604 inline Vec<T,M> Mat<T,M,N>::operator * (const Vec<T,N>& v) const {
00605   Vec<T,M> vp(T(0));
00606   for (int i=0,k=0;i<M;i++)
00607     for (int j=0;j<N;j++,k++)
00608       vp.x[i] += x[k]*v.x[j];
00609   return vp;
00610 }
00611 
00614 template <class T, int M, int N>
00615 Vec<T,N> operator * (const Vec<T,M>& v, const Mat<T,M,N> &m) {
00616   Vec<T,N> vp(T(0));
00617   for (int i=0,k=0;i<M;i++)
00618     for (int j=0;j<N;j++,k++)
00619       vp.x[j] += m.x[k]*v.x[i];
00620   return vp;
00621 }
00622 
00623 // Multiplication: <matrix> * <matrix>
00624 
00627 template <class T, int M, int N> template <int P>
00628 inline Mat<T,M,P> Mat<T,M,N>::operator * (const Mat<T,N,P>& m) const {
00629   Mat<T,M,P> mp(T(0));
00630   for (int i=0;i<M;i++)
00631     for (int j=0;j<P;j++)
00632       for (int k=0;k<N;k++)
00633         mp.x[i*P+j] += x[i*N+k]*m.x[k*P+j];
00634   return mp;
00635 }
00636 
00637 
00640 template <class T, int M, int N>
00641 inline void Mat<T,M,N>::operator *= (const Mat<T,N,N>& m) {
00642   (*this) = (*this)*m;
00643 }
00644 
00645 // Equality and inequality tests.
00646 
00650 template <class T, int M, int N>
00651 inline Mat<bool,M,N> Mat<T,M,N>::operator == (const Mat<T,M,N>& m) const {
00652   Mat<bool,M,N> b(false);
00653   for (int i=0;i<M*N;i++) if (x[i] == m.x[i]) b.x[i] = true;
00654   return b;
00655 }
00656 
00660 template <class T, int M, int N>
00661 inline Mat<bool,M,N> Mat<T,M,N>::operator != (const Mat<T,M,N>& m) const {
00662   Mat<bool,M,N> b(false);
00663   for (int i=0;i<M*N;i++) if (x[i] != m.x[i]) b.x[i] = true;
00664   return b;
00665 }
00666 
00670 template <class T, int M, int N>
00671 inline Mat<bool,M,N> Mat<T,M,N>::operator >= (const Mat<T,M,N>& m) const {
00672   Mat<bool,M,N> b(false);
00673   for (int i=0;i<M*N;i++) if (x[i] >= m.x[i]) b.x[i] = true;
00674   return b;
00675 }
00676 
00680 template <class T, int M, int N>
00681 inline Mat<bool,M,N> Mat<T,M,N>::operator <= (const Mat<T,M,N>& m) const {
00682   Mat<bool,M,N> b(false);
00683   for (int i=0;i<M*N;i++) if (x[i] <= m.x[i]) b.x[i] = true;
00684   return b;
00685 }
00686 
00690 template <class T, int M, int N>
00691 inline Mat<bool,M,N> Mat<T,M,N>::operator > (const Mat<T,M,N>& m) const {
00692   Mat<bool,M,N> b(false);
00693   for (int i=0;i<M*N;i++) if (x[i] > m.x[i]) b.x[i] = true;
00694   return b;
00695 }
00696 
00700 template <class T, int M, int N>
00701 inline Mat<bool,M,N> Mat<T,M,N>::operator < (const Mat<T,M,N>& m) const {
00702   Mat<bool,M,N> b(false);
00703   for (int i=0;i<M*N;i++) if (x[i] < m.x[i]) b.x[i] = true;
00704   return b;
00705 }
00706 
00711 template <class T, int M, int N>
00712 inline int Mat<T,M,N>::compareTo(const Mat<T,M,N>& m) const {
00713   int g=0, l=0;
00714   for (int i=0;i<M*N;i++) {
00715     if (x[i] < m.x[i]) l++;
00716     if (x[i] > m.x[i]) g++;
00717   }
00718   if (l==(M*N)) return -1;
00719   else if (g==(M*N)) return 1;
00720   else return 0;
00721 }
00722 
00726 template <class T, int M, int N>
00727 inline bool Mat<T,M,N>::equalTo(const Mat<T,M,N>& m, const T tol) const {
00728   bool t = true;
00729   for (int i=0;i<M*N;i++) if (fabs(x[i] - m.x[i]) > tol) t = false;
00730   return t;
00731 }
00732 
00733 // Transpose
00734 
00737 template <class T, int M, int N>
00738 inline Mat<T,N,M> Mat<T,M,N>::transposed() const {
00739   Mat<T,N,M> mp;
00740   for (int i=0;i<M;i++)
00741     for (int j=0;j<N;j++)
00742       mp.x[j*M+i] = x[i*N+j];
00743   return mp;
00744 }
00745 
00746 // Random matrices
00747 
00753 template <class T, int M, int N>
00754 inline Mat<T,M,N> Mat<T,M,N>::uniformRand(const T a, const T b) {
00755   Mat<T,M,N> m;
00756   for (int i=0;i<M*N;i++) m.x[i] = rtc_uniform_rand<T>(a,b);
00757   return m;
00758 }
00759 
00765 template <class T, int M, int N>
00766 inline Mat<T,M,N> Mat<T,M,N>::normalRand(const T mean, const T stdev) {
00767   Mat<T,M,N> m;
00768   for (int i=0;i<M*N;i++) m.x[i] = rtc_normal_rand<T>(mean,stdev);
00769   return m;
00770 }
00771 
00777 template <class T, int M, int N>
00778 inline Mat<T,M,N> Mat<T,M,N>::multivariateGauss(const Vec<T,M>& mean, const SMat<T,M>& cov) {
00779   Mat<T,M,N> m;
00780   SMat<T,M> S(cov);
00781   int n=S.choleskyDecomp();
00782   S.transpose();
00783   Mat<T,M,N> X = normalRand();
00784   for(int j=0;j<N;++j) m.setCol(j,mean);
00785   m = m + S*X;
00786   return m;
00787 }
00788 
00789 // General elementwise operations
00790 
00794 template <class T, int M, int N>
00795 inline void Mat<T,M,N>::perform(T (*mathFun)(T)) {
00796   for (int i=0;i<M*N;i++) x[i] = (*mathFun)(x[i]);
00797 }
00798 
00802 template <class T, int M, int N>
00803 inline Vec<T,N> Mat<T,M,N>::sum() const {
00804   Vec<T,N> s(T(0));
00805   for (int j=0;j<N;j++)
00806     for (int i=0;i<M;i++) s.x[j] += x[i*N+j];
00807   return s;
00808 }
00809 
00814 template <class T, int M, int N>
00815 inline T Mat<T,M,N>::interpolate(const float i, const float j) const {
00816   const int truncR = rtc_clamp(static_cast<int>(i),0,M-1);
00817   const int truncR1 = rtc_clamp(truncR+1,0,M-1);
00818   const float fractR = i - static_cast<float>(truncR);
00819   const int truncC = rtc_clamp(static_cast<int>(j),0,N-1);
00820   const int truncC1 = rtc_clamp(truncC+1,0,N-1);
00821   const float fractC = j - static_cast<float>(truncC);
00822 
00823   // do the interpolation
00824   const T syx = x[truncR*N+truncC];
00825   const T syx1 = x[truncR*N+truncC1];
00826   const T sy1x = x[truncR1*N+truncC];
00827   const T sy1x1 = x[truncR1*N+truncC1];
00828   // normal interpolation within range
00829   const T tmp1 = syx  + (syx1-syx)*T(fractC);
00830   const T tmp2 = sy1x + (sy1x1-sy1x)*T(fractC);
00831   return (tmp1 + (tmp2-tmp1)*T(fractR));
00832 }
00833 
00839 template <class T, int M, int N>
00840 inline Vec<T,N> Mat<T,M,N>::meanOfRows() const {
00841   Vec<T,N> m(T(0));
00842   for (int j=0;j<N;j++)
00843     for (int i=0;i<M;i++) m.x[j] += x[i*N+j];
00844   m/=static_cast<T>(M);
00845   return m;
00846 }
00847 
00848 /*
00849   * This is a new, faster version, written by Gu Xin:
00850   */
00851 template <class T, int M, int N>
00852 inline SMat<T,N> Mat<T,M,N>::covarianceMatrixOfRows() const {
00853   SMat<T,N> dest(T(0));
00854 
00855   //Implementation for the sum of Matrix[X];
00856   if (M<2) {  //just one row
00857    throw Exception("matrix has to have more than one row");
00858   }
00859 
00860   // mean vector
00861   Vec<T,N> mu(T(0));
00862 
00863   /*
00864   * the loop gets out the result of the Matrix[X];
00865   * Matrix[X]=sum(Matrix[X(i)]);-- i from 0 to n-1--
00866   */
00867   for(int i=0;i<M;i++){
00868    Vec<T,N> tmpV = getRow(i);
00869    mu.add(tmpV);
00870    SMat<T,N> tmp = tmpV.outer(tmpV);
00871    dest.add(tmp);          //add the Matrix[X(i)] to Matrix[sumMatrix];
00872   }
00873   //End of the Implementation for the sum of Matrix[X];
00874 
00875   //Implementation for the Matrix[meanOf];
00876   mu/=static_cast<T>(M);
00877 
00878   SMat<T,N> tmp = mu.outer(mu);
00879   tmp *= static_cast<T>(M);
00880 
00881   //get the result of the difference from Matrix[X] and Matrix[meanOf];
00882   dest.subtract(tmp);
00883   dest/=static_cast<T>(M-1);
00884   return dest;
00885 }
00886 
00887 
00888 // Serialization routines
00889 
00892 template <class T, int M, int N>
00893 inline bool Mat<T,M,N>::write(OutputHandler& oh) const {
00894   return oh.stream().write((char *)(x),M*N*sizeof(T)).good();
00895 }
00896 
00899 template <class T, int M, int N>
00900 inline bool Mat<T,M,N>::read(InputHandler& ih) {
00901   return ih.stream().read((char *)(x),M*N*sizeof(T)).good();
00902 }
00903 
00906 template <class T, int M, int N>
00907 std::ostream& operator<<(std::ostream& os, const Mat<T,M,N>& mat) {
00908 
00909   int minFieldWidth = os.precision()+2;
00910 
00911   //case with 1 row
00912   if (M == 1){
00913     os << "[" ;
00914     for (int i=0; i<N; ++i)
00915       os << std::setw(minFieldWidth) << mat.x[i] << " ";
00916 
00917     os << "]" << std::endl;
00918   }
00919   //case with 2+ rows
00920   else{
00921     //write first row
00922     os << "[" ;
00923     for (int j=0; j<N-1; ++j){
00924       os << std::setw(minFieldWidth) << mat.x[j] << " ";
00925     }
00926     os << std::setw(minFieldWidth) << mat.x[N-1] << ";" << std::endl;
00927     //write middle rows
00928     for (int i=1;i<M-1;++i){
00929       for (int j=0;j<N;++j){
00930         os << " " << std::setw(minFieldWidth) << mat.x[i*N+j];
00931         }
00932       os << ";" << std::endl;
00933       }
00934     //write last row
00935     for (int j=0; j<N; ++j){
00936       os << " " << std::setw(minFieldWidth) << mat.x[N*(M-1)+j];
00937     }
00938     os << "]" << std::endl;
00939   }
00940 
00941   return os;
00942 }
00943 
00946 template <class T, int M, int N>
00947 std::istream& operator>>(std::istream& is, Mat<T,M,N>& mat){
00948   using namespace std;
00949   vector<T> data;
00950   string matString;
00951   stringstream matStringStream;
00952   string rowString;
00953   stringstream rowStringStream;
00954 
00955   getline(is, matString, ']');
00956   int sPos = matString.find('[');
00957   if (sPos == (int)string::npos)
00958     throw Exception("format error: expecting formated matrix to start with '['");
00959 
00960   //erase the starting '['
00961   //note the ending ']' was removed by the getline function as the delim
00962   matString.erase(0,sPos+1);
00963   matStringStream.str(matString);
00964 
00965   //determine num of rows and cols
00966   int rowCount = 0, colCount = 0;
00967   int cols = -1;
00968   float tmpVal;
00969   while(getline(matStringStream, rowString, ';')){
00970     rowStringStream << rowString;
00971 
00972     colCount = 0;
00973     while(rowStringStream.good()){
00974       rowStringStream >> tmpVal;
00975       data.push_back(tmpVal);
00976       ++colCount;
00977     }
00978     rowStringStream.clear();
00979 
00980     //check that we have same num of entries in each row
00981     if (cols == -1)
00982       cols = colCount;
00983     else{
00984       if (colCount != cols){
00985         throw Exception("format error: different number of elements in rows.");
00986       }
00987     }
00988 
00989     ++rowCount;
00990   }
00991 
00992   //check that dimensions agree
00993   if (rowCount != M || colCount != N){
00994     std::stringstream ss;
00995     ss << "format error: formated text is " << rowCount << "x" << colCount;
00996     ss << " while destination matrix is " << M << "x" << N << endl;
00997     throw Exception(ss.str());
00998   }
00999 
01000   //copy extracted data
01001   for (int i=0;i<M*N;i++){
01002     mat.x[i] = data[i];
01003   }
01004 
01005   return is;
01006 }
01007 
01011 template <class T, int M, int N>
01012 bool rtc_write(OutputHandler& oh, const Mat<T,M,N>& data)
01013 {
01014   return data.write(oh);
01015 };
01016 
01020 template <class T, int M, int N>
01021 bool rtc_read(InputHandler& ih, Mat<T,M,N>& data)
01022 {
01023   return data.read(ih);
01024 };
01025 
01026 //==============================================================================
01027 } // NAMESPACE rtc
01028 //==============================================================================
01029 #endif // RTC_MAT_H defined
01030 //==============================================================================


rtc
Author(s): Benjamin Pitzer
autogenerated on Mon Oct 6 2014 10:07:34