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
00051 struct One{
00052
00053 One(){}
00054
00055 template<class C> operator C() const
00056 {
00057 return 1;
00058 }
00059 };
00060 template<class Rhs> Rhs operator*(One, const Rhs& v){return v;}
00061 template<class Lhs> Lhs operator*(const Lhs& v, One){return v;}
00062 template<class Rhs> Rhs operator+(One, const Rhs& v){return 1+v;}
00063 template<class Lhs> Lhs operator+(const Lhs& v, One){return v+1;}
00064 template<class Rhs> Rhs operator-(One, const Rhs& v){return 1-v;}
00065 template<class Lhs> Lhs operator-(const Lhs& v, One){return v-1;}
00066
00068 inline int operator-(const One&)
00069 {
00070 return -1;
00071 }
00072
00077 template<class C> struct NegType
00078 {
00079 typedef C Type;
00080 };
00081
00086 template<> struct NegType<One>
00087 {
00090 typedef int Type;
00091 };
00092
00096 template<class Rhs> struct Field<One, Rhs>
00097 {
00100 static const int is = IsField<Rhs>::value;
00101 };
00102
00106 template<class Lhs> struct Field<Lhs, One>
00107 {
00110 static const int is = IsField<Lhs>::value;
00111 };
00112
00113 }
00114
00116
00118
00119
00120
00121 template<> struct Operator<Internal::SizedZero>;
00122 template<> struct Operator<Internal::RCZero>;
00123
00124
00128 template<> struct Operator<Internal::Zero> {
00131 template<int Size, class Precision, class Base>
00132 void eval(Vector<Size, Precision, Base>& v) const {
00133 for(int i=0; i < v.size(); i++) {
00134 v[i]= 0;
00135 }
00136 }
00137
00138 template<int R, int C, class P, class B>
00139 void eval(Matrix<R,C,P,B>& m) const {
00140 for(int r=0; r<m.num_rows(); r++){
00141 for(int c=0; c<m.num_cols(); c++){
00142 m(r,c)=0;
00143 }
00144 }
00145 }
00147
00149 Operator<Internal::SizedZero> operator()(int s);
00151 Operator<Internal::RCZero> operator()(int r, int c);
00152
00153 };
00154
00158 template<> struct Operator<Internal::RCZero> : public Operator<Internal::Zero> {
00159
00162 Operator(int r, int c) : my_rows(r), my_cols(c) {}
00163
00164 const int my_rows;
00165 const int my_cols;
00166
00167 int num_rows() const {return my_rows;}
00168 int num_cols() const {return my_cols;}
00170 };
00171
00175 template<> struct Operator<Internal::SizedZero> : public Operator<Internal::Zero> {
00176
00179 Operator(int s) : my_size(s) {}
00180
00181 const int my_size;
00182
00183 int size() const {return my_size;}
00184 int num_rows() const {return my_size;}
00185 int num_cols() const {return my_size;}
00187 };
00188
00189 inline Operator<Internal::SizedZero> Operator<Internal::Zero>::operator()(int s){
00190 return Operator<Internal::SizedZero>(s);
00191 }
00192
00193 inline Operator<Internal::RCZero> Operator<Internal::Zero>::operator()(int r, int c){
00194 return Operator<Internal::RCZero>(r,c);
00195 }
00196
00197
00199
00201
00205 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::AddIdentity<R,C,P,B,Precision> >
00206 {
00207 const Precision s;
00208 const Matrix<R,C,P,B>& m;
00209 bool invert_m;
00210
00213 Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool b)
00214 :s(s_),m(m_),invert_m(b){}
00216
00219 template<int R1, int C1, class P1, class B1>
00220 void eval(Matrix<R1,C1,P1,B1>& mm) const{
00221 for(int r=0; r < m.num_rows(); r++)
00222 for(int c=0; c < m.num_cols(); c++)
00223 if(invert_m)
00224 mm[r][c] = -m[r][c];
00225 else
00226 mm[r][c] = m[r][c];
00227
00228 for(int i=0; i < m.num_rows(); i++)
00229 mm[i][i] += (P)s;
00230 }
00232
00235 int num_rows() const
00236 {
00237 return m.num_rows();
00238 }
00239 int num_cols() const
00240 {
00241 return m.num_cols();
00242 }
00244 };
00245
00249 template<class Pr> struct Operator<Internal::Identity<Pr> > {
00250
00253
00254 typedef Pr Precision;
00255 template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > scale_me(const Pmult& m) const
00256 {
00257 return Operator<Internal::Identity<Pout> >(val*m);
00258 }
00260
00262 const Precision val;
00263
00266 Operator(const Precision& v)
00267 :val(v)
00268 {}
00269
00270 Operator()
00271 {}
00273
00276 template<int R, int C, class P, class B>
00277 void eval(Matrix<R,C,P,B>& m) const {
00278 SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
00279
00280 for(int r=0; r<m.num_rows(); r++){
00281 for(int c=0; c<m.num_cols(); c++){
00282 m(r,c)=0;
00283 }
00284 }
00285
00286 for(int r=0; r < m.num_rows(); r++) {
00287 m(r,r) = (P)val;
00288 }
00289 }
00290
00291 template<int Rows, int Cols, typename P, typename B>
00292 void plusequals(Matrix<Rows, Cols, P, B>& m) const
00293 {
00294 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00295 for(int i=0; i < m.num_rows(); i++)
00296 m[i][i] += (P)val;
00297 }
00298
00299 template <int Rows, int Cols, typename P1, typename B1>
00300 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& m) const
00301 {
00302 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00303 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 0);
00304 }
00305
00306 template <int Rows, int Cols, typename P1, typename B1>
00307 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > rsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00308 {
00309 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00310 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(-val, m, 0);
00311 }
00312
00313 template <int Rows, int Cols, typename P1, typename B1>
00314 Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00315 {
00316 SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00317 return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 1);
00318 }
00320
00323 Operator<Internal::SizedIdentity<Precision> > operator()(int s){
00324 return Operator<Internal::SizedIdentity<Precision> >(s, val);
00325 }
00327 };
00328
00332 template<class Precision> struct Operator<Internal::SizedIdentity<Precision> >
00333 : public Operator<Internal::Identity<Precision> > {
00334
00335 using Operator<Internal::Identity<Precision> >::val;
00336
00339 Operator(int s, const Precision& v)
00340 :Operator<Internal::Identity<Precision> > (v), my_size(s)
00341 {}
00343
00346 const int my_size;
00347 int num_rows() const {return my_size;}
00348 int num_cols() const {return my_size;}
00350
00353 template<class Pout, class Pmult> Operator<Internal::SizedIdentity<Pout> > scale_me(const Pmult& m) const
00354 {
00355 return Operator<Internal::SizedIdentity<Pout> >(my_size, val*m);
00356 }
00358 };
00360
00361
00362
00363
00364
00368 template<int S, class P, class B, class Precision> struct Operator<Internal::ScalarsVector<S,P,B,Precision> >
00369 {
00370 const Precision s;
00371 const Vector<S,P,B>& v;
00372 const bool invert_v;
00373
00376 Operator(Precision s_, const Vector<S,P,B>& v_, bool inv)
00377 :s(s_),v(v_),invert_v(inv){}
00379
00382 template<int S1, class P1, class B1>
00383 void eval(Vector<S1,P1,B1>& vv) const{
00384 for(int i=0; i < v.size(); i++)
00385 if(invert_v)
00386 vv[i] = s - v[i];
00387 else
00388 vv[i] = s + v[i];
00389 }
00391
00394 int size() const
00395 {
00396 return v.size();
00397 }
00399 };
00400
00404 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::ScalarsMatrix<R,C,P,B,Precision> >
00405 {
00406 const Precision s;
00407 const Matrix<R,C,P,B>& m;
00408 const bool invert_m;
00409
00410
00411 Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool inv)
00412 :s(s_),m(m_),invert_m(inv){}
00413 template<int R1, int C1, class P1, class B1>
00414 void eval(Matrix<R1,C1,P1,B1>& mm) const{
00415 for(int r=0; r < m.num_rows(); r++)
00416 for(int c=0; c < m.num_cols(); c++)
00417 if(invert_m)
00418 mm[r][c] = s - m[r][c];
00419 else
00420 mm[r][c] = s + m[r][c];
00421 }
00423
00426 int num_rows() const
00427 {
00428 return m.num_rows();
00429 }
00430 int num_cols() const
00431 {
00432 return m.num_cols();
00433 }
00435 };
00436
00441 template<class P> struct Operator<Internal::Scalars<P> >
00442 {
00445 typedef P Precision;
00447
00448 const Precision s;
00449
00452 Operator(Precision s_)
00453 :s(s_){}
00454
00455 Operator()
00456 {}
00458
00460
00461
00462
00465
00466 template <int Size, typename P1, typename B1>
00467 void eval(Vector<Size, P1, B1>& v) const
00468 {
00469 for(int i=0; i < v.size(); i++)
00470 v[i] = (P1)s;
00471 }
00472
00473 template <int Size, typename P1, typename B1>
00474 void plusequals(Vector<Size, P1, B1>& v) const
00475 {
00476 for(int i=0; i < v.size(); i++)
00477 v[i] += (P1)s;
00478 }
00479
00480 template <int Size, typename P1, typename B1>
00481 void minusequals(Vector<Size, P1, B1>& v) const
00482 {
00483 for(int i=0; i < v.size(); ++i)
00484 v[i] -= (P1)s;
00485 }
00486
00487 template <int Size, typename P1, typename B1>
00488 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > add(const Vector<Size, P1, B1>& v) const
00489 {
00490 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 0);
00491 }
00492
00493 template <int Size, typename P1, typename B1>
00494 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > rsubtract(const Vector<Size, P1, B1>& v) const
00495 {
00496 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(-s, v, 0);
00497 }
00498
00499 template <int Size, typename P1, typename B1>
00500 Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > lsubtract(const Vector<Size, P1, B1>& v) const
00501 {
00502 return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 1);
00503 }
00504
00506
00507
00508
00509
00510 template <int Rows, int Cols, typename P1, typename B1>
00511 void eval(Matrix<Rows,Cols, P1, B1>& m) const
00512 {
00513 for(int r=0; r < m.num_rows(); r++)
00514 for(int c=0; c < m.num_cols(); c++)
00515 m[r][c] = s;
00516 }
00517
00518 template <int Rows, int Cols, typename P1, typename B1>
00519 void plusequals(Matrix<Rows,Cols, P1, B1>& m) const
00520 {
00521 for(int r=0; r < m.num_rows(); r++)
00522 for(int c=0; c < m.num_cols(); c++)
00523 m[r][c] += (P1)s;
00524 }
00525
00526 template <int Rows, int Cols, typename P1, typename B1>
00527 void minusequals(Matrix<Rows,Cols, P1, B1>& m) const
00528 {
00529 for(int r=0; r < m.num_rows(); r++)
00530 for(int c=0; c < m.num_cols(); c++)
00531 m[r][c] -= (P1)s;
00532 }
00533
00534 template <int Rows, int Cols, typename P1, typename B1>
00535 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& v) const
00536 {
00537 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 0);
00538 }
00539
00540
00541 template <int Rows, int Cols, typename P1, typename B1>
00542 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename Internal::NegType<P>::Type> > rsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00543 {
00544 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename Internal::NegType<P>::Type > >(-s, v, 0);
00545 }
00546
00547 template <int Rows, int Cols, typename P1, typename B1>
00548 Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00549 {
00550 return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 1);
00551 }
00554
00555
00556
00557
00560
00561 Operator<Internal::SizedScalars<Precision> > operator()(int size) const
00562 {
00563 return Operator<Internal::SizedScalars<Precision> > (s,size);
00564 }
00565
00566 Operator<Internal::RCScalars<Precision> > operator()(int r, int c) const
00567 {
00568 return Operator<Internal::RCScalars<Precision> > (s,r,c);
00569 }
00571
00574 template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > scale_me(const Pmult& m) const
00575 {
00576 return Operator<Internal::Scalars<Pout> >(s*m);
00577 }
00579 };
00580
00584 template<class P> struct Operator<Internal::SizedScalars<P> >: public Operator<Internal::Scalars<P> >
00585 {
00586 using Operator<Internal::Scalars<P> >::s;
00589 const int my_size;
00590 int size() const {
00591 return my_size;
00592 }
00593 int num_rows() const {
00594 return my_size;
00595 }
00596 int num_cols() const {
00597 return my_size;
00598 }
00600
00603 Operator(P s, int sz)
00604 :Operator<Internal::Scalars<P> >(s),my_size(sz){}
00606
00609 template<class Pout, class Pmult> Operator<Internal::SizedScalars<Pout> > scale_me(const Pmult& m) const
00610 {
00611 return Operator<Internal::SizedScalars<Pout> >(s*m, my_size);
00612 }
00614
00615 private:
00616 void operator()(int);
00617 void operator()(int,int);
00618 };
00619
00620
00624 template<class P> struct Operator<Internal::RCScalars<P> >: public Operator<Internal::Scalars<P> >
00625 {
00626 using Operator<Internal::Scalars<P> >::s;
00627
00630 const int my_rows, my_cols;
00631 int num_rows() const {
00632 return my_rows;
00633 }
00634 int num_cols() const {
00635 return my_cols;
00636 }
00637
00638 Operator(P s, int r, int c)
00639 :Operator<Internal::Scalars<P> >(s),my_rows(r),my_cols(c)
00640 {}
00641
00642 template<class Pout, class Pmult> Operator<Internal::RCScalars<Pout> > scale_me(const Pmult& m) const
00643 {
00644 return Operator<Internal::RCScalars<Pout> >(s*m, my_rows, my_cols);
00645 }
00646
00648 private:
00649 void operator()(int);
00650 void operator()(int,int);
00651 };
00652
00653
00655
00656
00657
00658
00659 template<template<class> class Op, class Pl, class Pr>
00660 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00661 operator*(const Pl& l, const Operator<Op<Pr> >& r)
00662 {
00663 return r.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(l);
00664 }
00665
00666 template<template<class> class Op, class Pl, class Pr>
00667 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00668 operator*(const Operator<Op<Pl> >& l, const Pr& r)
00669 {
00670 return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type>(r);
00671 }
00672
00673 template<template<class> class Op, class Pl, class Pr>
00674 Operator<Op<typename Internal::DivideType<Pl, Pr>::type > >
00675 operator/(const Operator<Op<Pl> >& l, const Pr& r)
00676 {
00677 return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r);
00678 }
00679
00680
00681 template<class Op>
00682 Operator<Op> operator-(const Operator<Op>& o)
00683 {
00684 return o.template scale_me<typename Operator<Op>::Precision>(-1);
00685 }
00686
00687
00688 template<template<class>class Op>
00689 Operator<Op<DefaultPrecision> > operator-(const Operator<Op<Internal::One> >& o)
00690 {
00691 return o.template scale_me<DefaultPrecision>(-1);
00692 }
00693
00713 static const Operator<Internal::Scalars<Internal::One> > Ones;
00714
00715
00727 static Operator<Internal::Zero> Zeros;
00728
00748 static Operator<Internal::Identity<Internal::One> > Identity;
00749
00750 }
00751