GEL  2
GEL is a library for Geometry and Linear Algebra
/Users/jab/Documents/Teaching/02585/GEL2_and_demos/GEL/src/CGLA/ArithMatFloat.h
00001 #ifndef __CGLA_ARITHMATFLOAT_H__
00002 #define __CGLA_ARITHMATFLOAT_H__
00003 
00004 #include <vector>
00005 #include <iostream>
00006 #include <numeric>
00007 
00008 #include "CGLA.h"
00009 
00010 
00011 namespace CGLA 
00012 {
00013 
00024   template <class VVT, class HVT, class MT, unsigned int ROWS>
00025     class ArithMatFloat
00026     { 
00027     public:
00028 
00030       typedef HVT HVectorType;
00031 
00033       typedef VVT VVectorType;
00034 
00036       typedef typename HVT::ScalarType ScalarType;
00037                 
00038     protected:
00039 
00041       HVT data[ROWS];
00042 
00043     protected:
00044 
00046       ArithMatFloat() 
00047         {
00048 #ifndef NDEBUG
00049           std::fill_n(data, ROWS, HVT(CGLA_INIT_VALUE));
00050 #endif
00051         }
00052 
00054       explicit ArithMatFloat(ScalarType x)
00055         {
00056           std::fill_n(data, ROWS, HVT(x));
00057         }
00058 
00060       explicit ArithMatFloat(HVT _a)
00061         {
00062           std::fill_n(data, ROWS, _a);
00063         }
00064 
00066       ArithMatFloat(HVT _a, HVT _b)
00067         {
00068           assert(ROWS==2);
00069           data[0] = _a;
00070           data[1] = _b;
00071         }
00072 
00074       ArithMatFloat(HVT _a, HVT _b, HVT _c)
00075         {
00076           assert(ROWS==3);
00077           data[0] = _a;
00078           data[1] = _b;
00079           data[2] = _c;
00080         }
00081 
00083       ArithMatFloat(HVT _a, HVT _b, HVT _c, HVT _d)
00084         {
00085           assert(ROWS==4);
00086           data[0] = _a;
00087           data[1] = _b;
00088           data[2] = _c;
00089           data[3] = _d;
00090         }
00091                 
00092     public:
00093 
00095       static unsigned int get_v_dim() {return VVT::get_dim();}
00096 
00098       static unsigned int get_h_dim() {return HVT::get_dim();}
00099 
00100 
00104       const ScalarType* get() const 
00105         {
00106           return data[0].get();
00107         }
00108 
00112       ScalarType* get()
00113         {
00114           return data[0].get();
00115         }
00116 
00117       //----------------------------------------------------------------------
00118       // index operators
00119       //----------------------------------------------------------------------
00120 
00122       const HVT& operator [] ( unsigned int i ) const
00123         {
00124           assert(i<ROWS);
00125           return data[i];
00126         }
00127 
00129       HVT& operator [] ( unsigned int i ) 
00130         {
00131           assert(i<ROWS);
00132           return data[i];
00133         }
00134 
00135       //----------------------------------------------------------------------
00136 
00138       bool operator==(const MT& v) const 
00139         {
00140           return std::inner_product(data, &data[ROWS], &v[0], true,
00141                                     std::logical_and<bool>(), std::equal_to<HVT>());
00142         }
00143 
00145       bool operator!=(const MT& v) const 
00146         {
00147           return !(*this==v);
00148         }
00149 
00150       //----------------------------------------------------------------------
00151 
00153       const MT operator * (ScalarType k) const
00154         {
00155           MT v_new;
00156           std::transform(data, &data[ROWS], &v_new[0], std::bind2nd(std::multiplies<HVT>(), k));
00157           return v_new;
00158         }
00159 
00161       const MT operator / (ScalarType k) const
00162         {
00163           MT v_new;
00164           std::transform(data, &data[ROWS], &v_new[0], std::bind2nd(std::divides<HVT>(), k));
00165           return v_new;      
00166         }
00167 
00169       const MT& operator *=(ScalarType k) 
00170         {
00171           std::transform(data, &data[ROWS], data, std::bind2nd(std::multiplies<HVT>(), k));
00172           return static_cast<const MT&>(*this);
00173         }
00174 
00176       const MT& operator /=(ScalarType k) 
00177         { 
00178           std::transform(data, &data[ROWS], data, std::bind2nd(std::divides<HVT>(), k));
00179           return static_cast<const MT&>(*this);
00180         }
00181 
00182       //----------------------------------------------------------------------
00183 
00185       const MT operator + (const MT& m1) const
00186         {
00187           MT v_new;
00188           std::transform(data, &data[ROWS], &m1[0], &v_new[0], std::plus<HVT>());
00189           return v_new;
00190         }
00191 
00193       const MT operator - (const MT& m1) const
00194         {
00195           MT v_new;
00196           std::transform(data, &data[ROWS], &m1[0], &v_new[0], std::minus<HVT>());
00197           return v_new;
00198         }
00199 
00201       const MT& operator +=(const MT& v) 
00202         {
00203           std::transform(data, &data[ROWS], &v[0], data, std::plus<HVT>());
00204           return static_cast<const MT&>(*this);
00205         }
00206 
00208       const MT& operator -=(const MT& v) 
00209         {
00210           std::transform(data, &data[ROWS], &v[0], data, std::minus<HVT>());
00211           return static_cast<const MT&>(*this);
00212         }
00213 
00214       //----------------------------------------------------------------------
00215 
00217       const MT operator - () const
00218         {
00219           MT v_new;
00220           std::transform(data, &data[ROWS], &v_new[0], std::negate<HVT>());
00221           return v_new;
00222         }
00223     };
00224 
00226   template <class VVT, class HVT, class MT, unsigned int ROWS>
00227     inline const MT operator * (double k, const ArithMatFloat<VVT,HVT,MT,ROWS>& v) 
00228     {
00229       return v * k;
00230     }
00231 
00233   template <class VVT, class HVT, class MT, unsigned int ROWS>
00234     inline const MT operator * (float k, const ArithMatFloat<VVT,HVT,MT,ROWS>& v) 
00235     {
00236       return v * k;
00237     }
00238 
00240   template <class VVT, class HVT, class MT, unsigned int ROWS>
00241     inline const MT operator * (int k, const ArithMatFloat<VVT,HVT,MT,ROWS>& v) 
00242     {
00243       return v * k;
00244     }
00245 
00247   template <class VVT, class HVT, class MT, unsigned int ROWS>
00248     inline VVT operator*(const ArithMatFloat<VVT,HVT,MT,ROWS>& m,const HVT& v) 
00249     {
00250       VVT v2;
00251       for(unsigned int i=0;i<ROWS;i++) v2[i] = dot(m[i], v);
00252       return v2;
00253     }
00254 
00255 
00256 #ifndef WIN32
00257 
00269   template <class VVT, class HVT, 
00270     class HV1T, class VV2T,
00271     class MT1, class MT2, class MT,
00272     unsigned int ROWS1, unsigned int ROWS2>
00273     inline void mul(const ArithMatFloat<VVT,HV1T,MT1,ROWS1>& m1,
00274                     const ArithMatFloat<VV2T,HVT,MT2,ROWS2>& m2,
00275                     ArithMatFloat<VVT,HVT,MT,ROWS1>& m)
00276     {
00277       unsigned int cols = ArithMatFloat<VVT,HVT,MT,ROWS1>::get_h_dim();
00278       for(unsigned int i=0;i<ROWS1;i++)
00279         for(unsigned int j=0;j<cols;j++)
00280           {
00281             m[i][j] = 0;
00282             for(unsigned int k=0;k<ROWS2;k++)
00283               m[i][j] += m1[i][k] * m2[k][j]; 
00284           }
00285     }
00286 
00287 
00290   template <class VVT, class HVT, class M1T, class M2T, unsigned int ROWS, unsigned int COLS>
00291     inline void transpose(const ArithMatFloat<VVT,HVT,M1T,ROWS>& m,
00292                           ArithMatFloat<HVT,VVT,M2T,COLS>& m_new)
00293     {
00294       for(unsigned int i=0;i<M2T::get_v_dim();++i)
00295         for(unsigned int j=0;j<M2T::get_h_dim();++j)
00296           m_new[i][j] = m[j][i];
00297     }
00298 
00299 #else
00300 
00301   //----------------- win32 -------------------------------
00302   // Visual studio is not good at deducing the args. to these template functions.
00303   // This means that you can call the two functions below with 
00304   // matrices of wrong dimension.
00305 
00306   template <class M1, class M2, class M>
00307     inline void mul(const M1& m1, const M2& m2, M& m)
00308     {
00309       unsigned int cols = M::get_h_dim();
00310       unsigned int rows1 = M1::get_v_dim();
00311       unsigned int rows2 = M2::get_v_dim();
00312 
00313       for(unsigned int i=0;i<rows1;++i)
00314         for(unsigned int j=0;j<cols;++j)
00315           {
00316             m[i][j] = 0;
00317             for(unsigned int k=0;k<rows2;++k)
00318               m[i][j] += m1[i][k] * m2[k][j];
00319           }
00320     }
00321 
00322 
00325   template <class M1, class M2>
00326     inline void transpose(const M1& m1, M2& m2)
00327     {
00328       for(unsigned int i=0;i<M2::get_v_dim();++i)
00329         for(unsigned int j=0;j<M2::get_h_dim();++j)
00330           m2[i][j] = m1[j][i];
00331     }
00332 
00333 #endif
00334 
00337   template <class VVT, class HVT, class MT, unsigned int ROWS>
00338     void outer_product(const VVT& a, const HVT& b, 
00339                        ArithMatFloat<VVT,HVT,MT,ROWS>& m)
00340     {
00341       unsigned int R = VVT::get_dim();
00342       unsigned int C = HVT::get_dim();
00343       for(unsigned int i=0;i<R;++i)
00344         for(unsigned int j=0;j<C;++j)
00345           {
00346             m[i][j] = a[i] * b[j];
00347           }
00348     }
00349 
00353   template <class VVT, class HVT, class MT, int ROWS, class BinOp>
00354     void outer_product(const VVT& a, const HVT& b, 
00355                        ArithMatFloat<VVT,HVT,MT,ROWS>& m, BinOp op)
00356     {
00357       int R = VVT::get_dim();
00358       int C = HVT::get_dim();
00359       for(int i=0;i<R;++i)
00360         for(int j=0;j<C;++j)
00361           {
00362             m[i][j] = op(a[i], b[j]);
00363           }
00364     }
00365 
00381   template <class M1, class M2>
00382     void copy_matrix(const M1& inmat, M2& outmat)
00383     {
00384       const unsigned int R = s_min(inmat.get_v_dim(), outmat.get_v_dim());
00385       const unsigned int C = s_min(inmat.get_h_dim(), outmat.get_h_dim());
00386       for(unsigned int i=0;i<R;++i)
00387         for(unsigned int j=0;j<C;++j)
00388           outmat[i][j] = inmat[i][j];
00389     }
00390 
00392   template <class VVT, class HVT, class MT, unsigned int ROWS>
00393     inline std::ostream& 
00394     operator<<(std::ostream&os, const ArithMatFloat<VVT,HVT,MT,ROWS>& m)
00395     {
00396       os << "[\n";
00397       for(unsigned int i=0;i<ROWS;i++) os << "  " << m[i] << "\n";
00398       os << "]\n";
00399       return os;
00400     }
00401 
00403   template <class VVT, class HVT, class MT, unsigned int ROWS>
00404     inline std::istream& operator>>(std::istream&is, 
00405                                     const ArithMatFloat<VVT,HVT,MT,ROWS>& m)
00406     {
00407       for(unsigned int i=0;i<ROWS;i++) is>>m[i];
00408       return is;
00409     }
00410 }
00411 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations