TooN 2.0.0-beta8
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     ///@internal
00049     ///@brief This class represents 1 and only in all its forms.
00050     ///@ingroup gInternal
00051     struct One{
00052 
00053         One(){} ///<This constructor does nothing. This allows const One to be declared with no initializer.
00054         ///Generic cast to anything
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;}   ///<Multiplies One by something.
00061     template<class Lhs> Lhs operator*(const Lhs& v, One){return v;}   ///<Multiplies something by One
00062     template<class Rhs> Rhs operator+(One, const Rhs& v){return 1+v;} ///<Adds something to One
00063     template<class Lhs> Lhs operator+(const Lhs& v, One){return v+1;} ///<Adds One to something
00064     template<class Rhs> Rhs operator-(One, const Rhs& v){return 1-v;} ///<Subtracts something from One
00065     template<class Lhs> Lhs operator-(const Lhs& v, One){return v-1;} ///<Subtracts One from something.
00066 
00067     ///Returns negative One.
00068     inline int operator-(const One&)
00069     {
00070         return -1;
00071     }
00072     
00073     ///@internal
00074     ///@brief For an instance \e i of type C, what is the type of \e -i?
00075     ///Usually the answer is that is it the same type.
00076     ///@ingroup gInternal
00077     template<class C> struct NegType
00078     {
00079         typedef C Type; ///<The type of -C
00080     };
00081 
00082     /**@internal
00083        @brief The type of -One
00084        @ingroup gInternal
00085     */
00086     template<> struct NegType<One>
00087     {
00088         ///One really repersents 1. Therefore -One is not the same type
00089         ///as One.
00090         typedef int Type;
00091     };
00092 
00093     ///@internal
00094     ///@brief Does One behave as a field with respect to Rhs?
00095     ///@ingroup gInternal
00096     template<class Rhs> struct Field<One, Rhs>
00097     {
00098         ///One can be converted in to anything, so the resulting type is
00099         ///a field if the other type is a field.
00100         static const int is = IsField<Rhs>::value;
00101     };
00102 
00103     ///@internal
00104     ///@brief Does One behave as a field with respect to Lhs?
00105     ///@ingroup gInternal
00106     template<class Lhs> struct Field<Lhs, One>
00107     {
00108         ///One can be converted in to anything, so the resulting type is
00109         ///a field if the other type is a field.
00110         static const int is = IsField<Lhs>::value;
00111     };
00112 
00113 }
00114 
00115 ////////////////////
00116 // Zero
00117 ////////////////////
00118 
00119 
00120 
00121 template<> struct Operator<Internal::SizedZero>;
00122 template<> struct Operator<Internal::RCZero>;
00123 
00124 
00125 ///@internal
00126 ///@brief Object which behaves like a block of zeros. See TooN::Zeros.
00127 ///@ingroup gInternal
00128 template<> struct Operator<Internal::Zero> {
00129     ///@name Operator members
00130     ///@{
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     }
00146     ///@}
00147 
00148     ///Generate a sized Zero object for constructing dynamic vectors.
00149     Operator<Internal::SizedZero> operator()(int s);
00150     ///Generate a sized Zero object for constructing dynamic matrices.
00151     Operator<Internal::RCZero> operator()(int r, int c);
00152     
00153 };
00154 
00155 ///@internal
00156 ///@brief Variant of the Zeros object which holds two sizes for constructing dynamic matrices.
00157 ///@ingroup gInternal
00158 template<> struct Operator<Internal::RCZero> : public Operator<Internal::Zero> {
00159 
00160     ///@name Operator members determining the size.
00161     ///@{
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;}
00169     ///@}
00170 };
00171 
00172 ///@internal
00173 ///@brief Variant of the Zeros object which holds a size for constructing dynamic vectors.
00174 ///@ingroup gInternal
00175 template<> struct Operator<Internal::SizedZero> : public Operator<Internal::Zero> {
00176 
00177     ///@name Operator members determining the size for vectors and square matrices.
00178     ///@{
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;}
00186     ///@}
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 
00198 //////////////
00199 // Identity
00200 //////////////
00201 
00202 ///@internal
00203 ///@brief Operator to construct a new matrix with idendity added 
00204 ///@ingroup gInternal
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;   ///<Scale of the identity matrix
00208     const Matrix<R,C,P,B>& m; ///<matrix to which the identity should be added
00209     bool invert_m; ///<Whether the identity should be added to + or - m
00210     
00211     ///@name Construction
00212     ///@{
00213     Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool b)
00214         :s(s_),m(m_),invert_m(b){}
00215     ///@}
00216 
00217     ///@name Operator members
00218     ///@{
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     }
00231     ///@}
00232 
00233     ///@name Sized operator members
00234     ///@{
00235     int num_rows() const
00236     {
00237         return m.num_rows();
00238     }
00239     int num_cols() const
00240     {
00241         return m.num_cols();
00242     }
00243     ///@}
00244 };
00245 
00246 ///@internal
00247 ///@brief Object which behaves like an Identity matrix. See TooN::Identity.
00248 ///@ingroup gInternal
00249 template<class Pr> struct Operator<Internal::Identity<Pr> > {
00250     
00251     ///@name Scalable operators members
00252     ///@{
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     }
00259     ///}
00260     
00261     ///<Scale of the identity matrix.
00262     const Precision val;
00263 
00264     ///@name Construction
00265     ///@{
00266     Operator(const Precision& v)
00267         :val(v)
00268     {}
00269 
00270     Operator()
00271     {}
00272     ///}
00273 
00274     ///@name Operator members
00275     ///@{
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     }
00319     ///@}
00320     
00321     ///@name Sizeable operator members
00322     ///@{
00323     Operator<Internal::SizedIdentity<Precision> > operator()(int s){
00324         return Operator<Internal::SizedIdentity<Precision> >(s, val);
00325     }
00326     ///@}
00327 };
00328     
00329 ///@internal
00330 ///@brief A variant of Identity which holds a size, allowing dynamic matrices to be constructed
00331 ///@ingroup gInternal
00332 template<class Precision> struct Operator<Internal::SizedIdentity<Precision> > 
00333     : public  Operator<Internal::Identity<Precision> > {
00334 
00335     using Operator<Internal::Identity<Precision> >::val;
00336     
00337     ///@name Constructors
00338     ///@{
00339     Operator(int s, const Precision& v)
00340         :Operator<Internal::Identity<Precision> > (v), my_size(s)
00341     {}
00342     ///@}
00343 
00344     ///@name Sized operator members
00345     ///@{
00346     const int my_size;
00347     int num_rows() const {return my_size;}
00348     int num_cols() const {return my_size;}
00349     ///@}
00350 
00351     ///@name Scalable operator members
00352     ///@{
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     }
00357     ///@}
00358 };
00359 ////////////////////////////////////////////////////////////////////////////////
00360 //
00361 // Addition of scalars to vectors and matrices
00362 //
00363 
00364     
00365 ///@internal
00366 ///@brief Operator to construct a new vector a a vector with a scalar added to every element
00367 ///@ingroup gInternal
00368 template<int S, class P, class B, class Precision> struct Operator<Internal::ScalarsVector<S,P,B,Precision> >
00369 {
00370     const Precision s;      ///<Scalar to add
00371     const Vector<S,P,B>& v; ///<Vector to be added to.
00372     const bool invert_v;    ///<Whether to use + or - \c v
00373 
00374     ///@name Constructors
00375     ///@{
00376     Operator(Precision s_, const Vector<S,P,B>& v_, bool inv)
00377         :s(s_),v(v_),invert_v(inv){}
00378     ///@}
00379 
00380     ///@name Operator members
00381     ///@{
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     }
00390     ///@}
00391 
00392     ///@name Sized operator members
00393     ///@{
00394     int size() const
00395     {
00396         return v.size();
00397     }
00398     ///@}
00399 };
00400 
00401 ///@internal
00402 ///@brief Operator to construct a new matrix a a matrix with a scalar added to every element
00403 ///@ingroup gInternal
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;        ///<Scalar to add
00407     const Matrix<R,C,P,B>& m; ///<Vector to be added to.
00408     const bool invert_m;      ///<Whether to use + or - \c m
00409     ///@name Operator members
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     }
00422     ///@}
00423 
00424     ///@name Sized operator members
00425     ///@{
00426     int num_rows() const
00427     {
00428         return m.num_rows();
00429     }
00430     int num_cols() const
00431     {
00432         return m.num_cols();
00433     }
00434     ///@}
00435 };
00436 
00437 ///@internal
00438 ///@brief Generic scalars object. Knows how to be added, knows how to deal with += and so on.
00439 ///See TooN::Ones
00440 ///@ingroup gInternal
00441 template<class P> struct Operator<Internal::Scalars<P> >
00442 {   
00443     ///@name Scalable operator members
00444     ///@{
00445     typedef P Precision;
00446     ///@}
00447 
00448     const Precision s; ///<Value of the scalar being represented.  
00449     
00450     ///@name Constructors
00451     ///@{
00452     Operator(Precision s_)
00453         :s(s_){}
00454 
00455     Operator()
00456     {}
00457     ///@}
00458 
00459     ////////////////////////////////////////
00460     //
00461     // All applications for vector
00462     //
00463     ///@name Operator members
00464     ///@{
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 
00505     ////////////////////////////////////////
00506     //
00507     // All applications for matrix
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     }
00552     ///@}
00553     ////////////////////////////////////////
00554     //
00555     // Create sized versions for initialization
00556     //
00557 
00558     ///@name Sizeable operators members
00559     ///@{
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     }
00570     ///@}
00571 
00572     ///@name Scalable operator members
00573     ///@{
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     }
00578     ///@}
00579 };
00580 
00581 ///@internal
00582 ///@brief Variant of the Operator<Internal::Scalars> object which holds a size to construct dynamic vectors or square matrices.
00583 ///@ingroup gInternal 
00584 template<class P> struct Operator<Internal::SizedScalars<P> >: public Operator<Internal::Scalars<P> >
00585 {
00586     using Operator<Internal::Scalars<P> >::s;
00587     ///@name Sized operator members
00588     ///@{
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     }
00599     ///@}
00600 
00601     ///@name Constructors
00602     ///@{
00603     Operator(P s, int sz)
00604         :Operator<Internal::Scalars<P> >(s),my_size(sz){}
00605     ///@}
00606         
00607     ///@name Scalable operator members
00608     ///@{
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     }
00613     ///@}
00614 
00615 private:
00616     void operator()(int);
00617     void operator()(int,int);
00618 };
00619 
00620         
00621 ///@internal
00622 ///@brief Variant of Scalars (see TooN::Ones) which holds two sizes to construct dynamic matrices.
00623 ///@ingroup gInternal
00624 template<class P> struct Operator<Internal::RCScalars<P> >: public Operator<Internal::Scalars<P> >
00625 {
00626     using Operator<Internal::Scalars<P> >::s;
00627 
00628     ///@name Operator members
00629     ///@{
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 
00647     ///@}
00648 private:
00649     void operator()(int);
00650     void operator()(int,int);
00651 };
00652 
00653 
00654 ////////////////////////////////////////////////////////////////////////////////
00655 //
00656 // How to scale scalable operators
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 //Special case for negating One
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 
00694 /**This function is used to add a scalar to every element of a vector or
00695    matrix. For example:
00696    @code
00697    Vector<3> v;
00698    ...
00699    ...
00700    v += Ones * 3; //Add 3 to every element of v;
00701    @endcode
00702    Both + and += are supported on vectors,matrices and slices.
00703 
00704    For construction of dynamic vectors and matrices, a size needs to be given:
00705    @code
00706        Vector<3> v_static = Ones;    
00707        Vector<>  v_dynamic = Ones(3); //Construct a 3x1 vector full one 1s
00708        Matrix<3> m_static = Ones;     
00709        Matrix<>  m_dynamic = Ones(3,4); //Construct a 3x4 matrix
00710    @endcode
00711    @ingroup gLinAlg
00712 */
00713 static const Operator<Internal::Scalars<Internal::One> > Ones;
00714 
00715 
00716 /**This function is used to initialize vectors and matrices to zero.
00717    For construction of dynamic vectors and matrices, a size needs to be given.
00718    For example:
00719    @code
00720        Vector<3> v_static = Zeros;
00721        Vector<>  v_dynamic = Zeros(3); //Construct a 3x1 vector
00722        Matrix<3> m_static = Zeros;
00723        Matrix<>  m_dynamic = Zeros(3,4); //Construct a 3x4 matrix
00724    @endcode
00725    @ingroup gLinAlg
00726 */
00727 static Operator<Internal::Zero> Zeros;
00728 
00729 /**This function is used to add a scalar to the diagonal of a matrix,
00730    or to construct matrices.
00731    For example:
00732    @code
00733    Matrix<3> v;
00734    ...
00735    ...
00736    Matrix<3> u = v  + Identity * 4;
00737    @endcode
00738    Both + and += are supported. For assignment, if the matrix is non-square,
00739    then all elements off the leading diagonal are set to zero.
00740    For construction of dynamic matrices, a size needs to be given:
00741    @code
00742        Matrix<3> m_static = Identity;     
00743        Matrix<>  m_dynamic = Identity(3); //Construct a 3x3 matrix
00744    @endcode
00745    @ingroup gLinAlg
00746 */
00747 
00748 static Operator<Internal::Identity<Internal::One> > Identity;
00749 
00750 }
00751