internal/objects.h

00001 // -*- c++ -*-
00002 
00003 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk),
00004 // Ed Rosten (er258@cam.ac.uk), Gerhard Reitmayr (gr281@cam.ac.uk)
00005 //
00006 // This file is part of the TooN Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 namespace TooN {
00032 
00033 namespace Internal{
00034     // dummy structs that are used in 0-ary operators
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 // Zero
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 // Identity
00113 
00114 //Operator to construct a new matrix with idendity added 
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 // Addition of scalars to vectors and matrices
00226 //
00227 
00228     
00229 //Operator to construct a new vector a a vector with a scalar added to every element
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 //Operator to construct a new matrix a a matrix with a scalar added to every element
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 //Generic scalars object. Knows how to be added, knows how to deal with +=
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     // All applications for vector
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     // All applications for matrix
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     // Create sized versions for initialization
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 // How to scale scalable operators
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 }

Generated on Thu May 7 20:28:40 2009 for TooN by  doxygen 1.5.3