00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 namespace TooN {
00032
00033 namespace Internal{
00034
00035 struct Zero;
00036 struct SizedZero;
00037 struct RCZero;
00038 template<class P> struct Identity;
00039 template<class P> struct SizedIdentity;
00040
00041 template<int S, class P, class B, class Ps> class ScalarsVector;
00042 template<int R, int C, class P, class B, class Ps> class ScalarsMatrix;
00043 template<int R, int C, class P, class B, class Ps> class AddIdentity;
00044 template<class P> class Scalars;
00045 template<class P> class SizedScalars;
00046 template<class P> class RCScalars;
00047 }
00048
00050
00052
00053
00054
00055 template<> struct Operator<Internal::SizedZero>;
00056 template<> struct Operator<Internal::RCZero>;
00057
00058 template<> struct Operator<Internal::Zero> {
00059 template<int Size, class Precision, class Base>
00060 void eval(Vector<Size, Precision, Base>& v) const {
00061 for(int i=0; i < v.size(); i++) {
00062 v[i]= 0;
00063 }
00064 }
00065
00066 template<int R, int C, class P, class B>
00067 void eval(Matrix<R,C,P,B>& m) const {
00068 for(int r=0; r<m.num_rows(); r++){
00069 for(int c=0; c<m.num_cols(); c++){
00070 m(r,c)=0;
00071 }
00072 }
00073 }
00074
00075 Operator<Internal::SizedZero> operator()(int s);
00076 Operator<Internal::RCZero> operator()(int r, int c);
00077
00078 };
00079
00080 template<> struct Operator<Internal::RCZero> : public Operator<Internal::Zero> {
00081 Operator(int r, int c) : my_rows(r), my_cols(c) {}
00082
00083 const int my_rows;
00084 const int my_cols;
00085
00086 int num_rows() const {return my_rows;}
00087 int num_cols() const {return my_cols;}
00088 };
00089
00090 template<> struct Operator<Internal::SizedZero> : public Operator<Internal::Zero> {
00091
00092 Operator(int s) : my_size(s) {}
00093
00094 const int my_size;
00095
00096 int size() const {return my_size;}
00097 int num_rows() const {return my_size;}
00098 int num_cols() const {return my_size;}
00099 };
00100
00101 inline Operator<Internal::SizedZero> Operator<Internal::Zero>::operator()(int s){
00102 return Operator<Internal::SizedZero>(s);
00103 }
00104
00105 inline Operator<Internal::RCZero> Operator<Internal::Zero>::operator()(int r, int c){
00106 return Operator<Internal::RCZero>(r,c);
00107 }
00108
00109
00111
00113
00114
00115 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::AddIdentity<R,C,P,B,Precision> >
00116 {
00117 const Precision s;
00118 const Matrix<R,C,P,B>& m;
00119 bool invert_m;
00120
00121 Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool b)
00122 :s(s_),m(m_),invert_m(b){}
00123 template<int R1, int C1, class P1, class B1>
00124 void eval(Matrix<R1,C1,P1,B1>& mm) const{
00125 for(int r=0; r < m.num_rows(); r++)
00126 for(int c=0; c < m.num_cols(); c++)
00127 if(invert_m)
00128 mm[r][c] = -m[r][c];
00129 else
00130 mm[r][c] = m[r][c];
00131
00132 for(int i=0; i < m.num_rows(); i++)
00133 mm[i][i] += s;
00134 }
00135
00136 int num_rows() const
00137 {
00138 return m.num_rows();
00139 }
00140 int num_cols() const
00141 {
00142 return m.num_cols();
00143 }
00144 };
00145
00146
00147 template<class Pr> struct Operator<Internal::Identity<Pr> > {
00148
00149 typedef Pr Precision;
00150 const Precision val;
00151 Operator(const Precision& v=1)
00152 :val(v)
00153 {}
00154
00155 template<int R, int C, class P, class B>
00156 void eval(Matrix<R,C,P,B>& m) const {
00157 SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
00158
00159 for(int r=0; r<m.num_rows(); r++){
00160 for(int c=0; c<m.num_cols(); c++){
00161 m(r,c)=0;
00162 }
00163 }
00164
00165 for(int r=0; r < m.num_rows(); r++) {
00166 m(r,r) = val;
00167 }
00168 }
00169
00170 template <int Rows, int Cols, typename P1, typename B1>
00171 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& m) const
00172 {
00173 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00174 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 0);
00175 }
00176
00177 template <int Rows, int Cols, typename P1, typename B1>
00178 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > rsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00179 {
00180 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00181 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(-val, m, 0);
00182 }
00183
00184 template <int Rows, int Cols, typename P1, typename B1>
00185 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00186 {
00187 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00188 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 1);
00189 }
00190
00191
00192 Operator<Internal::SizedIdentity<Precision> > operator()(int s){
00193 return Operator<Internal::SizedIdentity<Precision> >(s);
00194 }
00195
00196 template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > scale_me(const Pmult& m) const
00197 {
00198 return Operator<Internal::Identity<Pout> >(val*m);
00199 }
00200
00201
00202 };
00203
00204
00205 template<class Precision> struct Operator<Internal::SizedIdentity<Precision> >
00206 : public Operator<Internal::Identity<Precision> > {
00207
00208 using Operator<Internal::Identity<Precision> >::val;
00209 const int my_size;
00210
00211 Operator(int s, const Precision& v=1)
00212 :Operator<Internal::Identity<Precision> > (v), my_size(s)
00213 {}
00214
00215 int num_rows() const {return my_size;}
00216 int num_cols() const {return my_size;}
00217
00218 template<class Pout, class Pmult> Operator<Internal::SizedIdentity<Pout> > scale_me(const Pmult& m) const
00219 {
00220 return Operator<Internal::SizedIdentity<Pout> >(my_size, val*m);
00221 }
00222 };
00224
00225
00226
00227
00228
00229
00230 template<int S, class P, class B, class Precision> struct Operator<Internal::ScalarsVector<S,P,B,Precision> >
00231 {
00232 const Precision s;
00233 const Vector<S,P,B>& v;
00234 const bool invert_v;
00235 Operator(Precision s_, const Vector<S,P,B>& v_, bool inv)
00236 :s(s_),v(v_),invert_v(inv){}
00237
00238 template<int S1, class P1, class B1>
00239 void eval(Vector<S1,P1,B1>& vv) const{
00240 for(int i=0; i < v.size(); i++)
00241 if(invert_v)
00242 vv[i] = s - v[i];
00243 else
00244 vv[i] = s + v[i];
00245 }
00246
00247 int size() const
00248 {
00249 return v.size();
00250 }
00251 };
00252
00253
00254 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::ScalarsMatrix<R,C,P,B,Precision> >
00255 {
00256 const Precision s;
00257 const Matrix<R,C,P,B>& m;
00258 const bool invert_m;
00259 Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool inv)
00260 :s(s_),m(m_),invert_m(inv){}
00261 template<int R1, int C1, class P1, class B1>
00262 void eval(Matrix<R1,C1,P1,B1>& mm) const{
00263 for(int r=0; r < m.num_rows(); r++)
00264 for(int c=0; c < m.num_cols(); c++)
00265 if(invert_m)
00266 mm[r][c] = s - m[r][c];
00267 else
00268 mm[r][c] = s + m[r][c];
00269 }
00270
00271 int num_rows() const
00272 {
00273 return m.num_rows();
00274 }
00275 int num_cols() const
00276 {
00277 return m.num_cols();
00278 }
00279 };
00280
00281
00282 template<class P> struct Operator<Internal::Scalars<P> >
00283 {
00284 typedef P Precision;
00285 const Precision s;
00286 Operator(Precision s_)
00287 :s(s_){}
00288
00290
00291
00292
00293
00294 template <int Size, typename P1, typename B1>
00295 void eval(Vector<Size, P1, B1>& v) const
00296 {
00297 for(int i=0; i < v.size(); i++)
00298 v[i] = s;
00299 }
00300
00301 template <int Size, typename P1, typename B1>
00302 void plusequals(Vector<Size, P1, B1>& v) const
00303 {
00304 for(int i=0; i < v.size(); i++)
00305 v[i] += s;
00306 }
00307
00308 template <int Size, typename P1, typename B1>
00309 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > add(const Vector<Size, P1, B1>& v) const
00310 {
00311 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 0);
00312 }
00313
00314 template <int Size, typename P1, typename B1>
00315 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > rsubtract(const Vector<Size, P1, B1>& v) const
00316 {
00317 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(-s, v, 0);
00318 }
00319
00320 template <int Size, typename P1, typename B1>
00321 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > lsubtract(const Vector<Size, P1, B1>& v) const
00322 {
00323 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 1);
00324 }
00325
00327
00328
00329
00330
00331 template <int Rows, int Cols, typename P1, typename B1>
00332 void eval(Matrix<Rows,Cols, P1, B1>& m) const
00333 {
00334 for(int r=0; r < m.num_rows(); r++)
00335 for(int c=0; c < m.num_cols(); c++)
00336 m[r][c] = s;
00337 }
00338
00339 template <int Rows, int Cols, typename P1, typename B1>
00340 void plusequals(Matrix<Rows,Cols, P1, B1>& m) const
00341 {
00342 for(int r=0; r < m.num_rows(); r++)
00343 for(int c=0; c < m.num_cols(); c++)
00344 m[r][c] += s;
00345 }
00346
00347 template <int Rows, int Cols, typename P1, typename B1>
00348 void minusequals(Matrix<Rows,Cols, P1, B1>& m) const
00349 {
00350 for(int r=0; r < m.num_rows(); r++)
00351 for(int c=0; c < m.num_cols(); c++)
00352 m[r][c] -= s;
00353 }
00354
00355 template <int Rows, int Cols, typename P1, typename B1>
00356 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& v) const
00357 {
00358 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 0);
00359 }
00360
00361
00362 template <int Rows, int Cols, typename P1, typename B1>
00363 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > rsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00364 {
00365 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(-s, v, 0);
00366 }
00367
00368 template <int Rows, int Cols, typename P1, typename B1>
00369 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00370 {
00371 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 1);
00372 }
00374
00375
00376
00377
00378 Operator<Internal::SizedScalars<Precision> > operator()(int size) const
00379 {
00380 return Operator<Internal::SizedScalars<Precision> > (s,size);
00381 }
00382
00383 Operator<Internal::RCScalars<Precision> > operator()(int r, int c) const
00384 {
00385 return Operator<Internal::RCScalars<Precision> > (s,r,c);
00386 }
00387
00388 template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > scale_me(const Pmult& m) const
00389 {
00390 return Operator<Internal::Scalars<Pout> >(s*m);
00391 }
00392 };
00393
00394 template<class P> struct Operator<Internal::SizedScalars<P> >: public Operator<Internal::Scalars<P> >
00395 {
00396 using Operator<Internal::Scalars<P> >::s;
00397 const int my_size;
00398 int size() const {
00399 return my_size;
00400 }
00401
00402 Operator(P s, int sz)
00403 :Operator<Internal::Scalars<P> >(s),my_size(sz){}
00404
00405 template<class Pout, class Pmult> Operator<Internal::SizedScalars<Pout> > scale_me(const Pmult& m) const
00406 {
00407 return Operator<Internal::SizedScalars<Pout> >(s*m, my_size);
00408 }
00409
00410 private:
00411 void operator()(int);
00412 void operator()(int,int);
00413 };
00414
00415
00416
00417 template<class P> struct Operator<Internal::RCScalars<P> >: public Operator<Internal::Scalars<P> >
00418 {
00419 using Operator<Internal::Scalars<P> >::s;
00420 const int my_rows, my_cols;
00421 int num_rows() const {
00422 return my_rows;
00423 }
00424 int num_cols() const {
00425 return my_cols;
00426 }
00427
00428 Operator(P s, int r, int c)
00429 :Operator<Internal::Scalars<P> >(s),my_rows(r),my_cols(c)
00430 {}
00431
00432 template<class Pout, class Pmult> Operator<Internal::RCScalars<Pout> > scale_me(const Pmult& m) const
00433 {
00434 return Operator<Internal::RCScalars<Pout> >(s*m, my_rows, my_cols);
00435 }
00436
00437 private:
00438 void operator()(int);
00439 void operator()(int,int);
00440 };
00441
00442
00444
00445
00446
00447
00448 template<template<class> class Op, class Pl, class Pr>
00449 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00450 operator*(const Pl& l, const Operator<Op<Pr> >& r)
00451 {
00452 return r.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(l);
00453 }
00454
00455 template<template<class> class Op, class Pl, class Pr>
00456 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00457 operator*(const Operator<Op<Pl> >& l, const Pr& r)
00458 {
00459 return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(r);
00460 }
00461
00462 template<template<class> class Op, class Pl, class Pr>
00463 Operator<Op<typename Internal::DivideType<Pl, Pr>::type > >
00464 operator/(const Operator<Op<Pl> >& l, const Pr& r)
00465 {
00466 return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r);
00467 }
00468
00469
00470 template<class Op, class P>
00471 Operator<Op> operator-(const Operator<Op>& o)
00472 {
00473 return o.scalar(-1);
00474 }
00475
00476
00488 static Operator<Internal::Zero> Zeros;
00489 static Operator<Internal::Identity<DefaultPrecision> > Identity;
00490 static const Operator<Internal::Scalars<DefaultPrecision> > Ones(1);
00491
00492 }