GEL
2
GEL is a library for Geometry and Linear Algebra
|
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