TooN 2.1
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 
00094 ///@internal
00095 ///@brief Does One behave as a field with respect to Rhs?
00096 ///Answer: it does is Rhs forms a field.
00097 ///@ingroup gInternal
00098 template<class Rhs> struct Field<Internal::One, Rhs>
00099 {
00100     ///One can be converted in to anything, so the resulting type is
00101     ///a field if the other type is a field.
00102     static const int is = Field<Rhs,Rhs>::is;
00103 };
00104 
00105 ///@internal
00106 ///@brief Does One behave as a field with respect to Lhs?
00107 ///Answer: it does is Lhs forms a field.
00108 ///@ingroup gInternal
00109 template<class Lhs> struct Field<Lhs, Internal::One>
00110 {
00111     ///One can be converted in to anything, so the resulting type is
00112     ///a field if the other type is a field.
00113     static const int is = Field<Lhs,Lhs>::is;
00114 };
00115 
00116 ////////////////////
00117 // Zero
00118 ////////////////////
00119 
00120 
00121 
00122 template<> struct Operator<Internal::SizedZero>;
00123 template<> struct Operator<Internal::RCZero>;
00124 
00125 
00126 ///@internal
00127 ///@brief Object which behaves like a block of zeros. See TooN::Zeros.
00128 ///@ingroup gInternal
00129 template<> struct Operator<Internal::Zero> {
00130     ///@name Operator members
00131     ///@{
00132     template<int Size, class Precision, class Base>
00133     void eval(Vector<Size, Precision, Base>& v) const {
00134         for(int i=0; i < v.size(); i++) {
00135             v[i]= 0;
00136         }
00137     }
00138 
00139     template<int R, int C, class P, class B>
00140     void eval(Matrix<R,C,P,B>& m) const {
00141         for(int r=0; r<m.num_rows(); r++){
00142             for(int c=0; c<m.num_cols(); c++){
00143                 m(r,c)=0;
00144             }
00145         }
00146     }
00147     ///@}
00148 
00149     template<int R, int C, class P, class B>
00150     bool notequal(Matrix<R,C,P,B>& m) const {
00151         for(int r=0; r<m.num_rows(); r++)
00152             for(int c=0; c<m.num_cols(); c++)
00153                 if(m[r][c] != 0)
00154                     return 1;
00155         
00156         return 0;
00157     }
00158 
00159 
00160     template<int S, class P, class B>
00161     bool notequal(Vector<S,P,B>& v) const {
00162         for(int i=0; i<v.size(); i++)
00163             if(v[i] != 0)
00164                 return 1;
00165         return 0;
00166     }
00167 
00168     ///Generate a sized Zero object for constructing dynamic vectors.
00169     Operator<Internal::SizedZero> operator()(int s);
00170     ///Generate a sized Zero object for constructing dynamic matrices.
00171     Operator<Internal::RCZero> operator()(int r, int c);
00172     
00173 };
00174 
00175 ///@internal
00176 ///@brief Variant of the Zeros object which holds two sizes for constructing dynamic matrices.
00177 ///@ingroup gInternal
00178 template<> struct Operator<Internal::RCZero> : public Operator<Internal::Zero> {
00179 
00180     ///@name Operator members determining the size.
00181     ///@{
00182     Operator(int r, int c) : my_rows(r), my_cols(c) {}
00183 
00184     const int my_rows;
00185     const int my_cols;
00186     
00187     int num_rows() const {return my_rows;}
00188     int num_cols() const {return my_cols;}
00189     ///@}
00190 };
00191 
00192 ///@internal
00193 ///@brief Variant of the Zeros object which holds a size for constructing dynamic vectors.
00194 ///@ingroup gInternal
00195 template<> struct Operator<Internal::SizedZero> : public Operator<Internal::Zero> {
00196 
00197     ///@name Operator members determining the size for vectors and square matrices.
00198     ///@{
00199     Operator(int s) : my_size(s) {}
00200         
00201     const int my_size;
00202     
00203     int size() const {return my_size;}
00204     int num_rows() const {return my_size;}
00205     int num_cols() const {return my_size;}
00206     ///@}
00207 };
00208 
00209 inline Operator<Internal::SizedZero> Operator<Internal::Zero>::operator()(int s){
00210     return Operator<Internal::SizedZero>(s);
00211 }
00212 
00213 inline Operator<Internal::RCZero> Operator<Internal::Zero>::operator()(int r, int c){
00214     return Operator<Internal::RCZero>(r,c);
00215 }
00216 
00217 
00218 //////////////
00219 // Identity
00220 //////////////
00221 
00222 ///@internal
00223 ///@brief Operator to construct a new matrix with idendity added 
00224 ///@ingroup gInternal
00225 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::AddIdentity<R,C,P,B,Precision> >
00226 {
00227     const Precision s;   ///<Scale of the identity matrix
00228     const Matrix<R,C,P,B>& m; ///<matrix to which the identity should be added
00229     bool invert_m; ///<Whether the identity should be added to + or - m
00230     
00231     ///@name Construction
00232     ///@{
00233     Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool b)
00234         :s(s_),m(m_),invert_m(b){}
00235     ///@}
00236 
00237     ///@name Operator members
00238     ///@{
00239     template<int R1, int C1, class P1, class B1>
00240     void eval(Matrix<R1,C1,P1,B1>& mm) const{
00241         for(int r=0; r < m.num_rows(); r++)
00242             for(int c=0; c < m.num_cols(); c++)
00243                 if(invert_m)
00244                     mm[r][c] = -m[r][c];
00245                 else
00246                     mm[r][c] = m[r][c];
00247 
00248         for(int i=0; i < m.num_rows(); i++)
00249                 mm[i][i] += (P)s;
00250     }
00251     ///@}
00252 
00253     ///@name Sized operator members
00254     ///@{
00255     int num_rows() const
00256     {
00257         return m.num_rows();
00258     }
00259     int num_cols() const
00260     {
00261         return m.num_cols();
00262     }
00263     ///@}
00264 };
00265 
00266 ///@internal
00267 ///@brief Object which behaves like an Identity matrix. See TooN::Identity.
00268 ///@ingroup gInternal
00269 template<class Pr> struct Operator<Internal::Identity<Pr> > {
00270     
00271     ///@name Scalable operators members
00272     ///@{
00273 
00274     typedef Pr Precision;
00275     template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > scale_me(const Pmult& m) const
00276     {
00277         return Operator<Internal::Identity<Pout> >(val*m);
00278     }
00279     ///}
00280     
00281     ///<Scale of the identity matrix.
00282     const Precision val;
00283 
00284     ///@name Construction
00285     ///@{
00286     Operator(const Precision& v)
00287         :val(v)
00288     {}
00289 
00290     Operator()
00291     {}
00292     ///}
00293 
00294     ///@name Operator members
00295     ///@{
00296     template<int R, int C, class P, class B>
00297     void eval(Matrix<R,C,P,B>& m) const {
00298         SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
00299         
00300         for(int r=0; r<m.num_rows(); r++){
00301             for(int c=0; c<m.num_cols(); c++){
00302                 m(r,c)=0;
00303             }
00304         }
00305         
00306         for(int r=0; r < m.num_rows(); r++) {
00307             m(r,r) = (P)val;
00308         }
00309     }
00310     
00311     template<int Rows, int Cols, typename P, typename B>
00312     void plusequals(Matrix<Rows, Cols, P, B>& m) const
00313     {
00314         SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00315         for(int i=0; i < m.num_rows(); i++)
00316             m[i][i] += (P)val;
00317     }
00318 
00319     template <int Rows, int Cols, typename P1, typename B1> 
00320     Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& m) const
00321     {
00322         SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00323         return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 0);
00324     }
00325 
00326     template <int Rows, int Cols, typename P1, typename B1> 
00327     Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > rsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00328     {
00329         SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00330         return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(-val, m, 0);
00331     }
00332 
00333     template <int Rows, int Cols, typename P1, typename B1> 
00334     Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
00335     {
00336         SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
00337         return Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 1);
00338     }
00339     ///@}
00340     
00341     ///@name Sizeable operator members
00342     ///@{
00343     Operator<Internal::SizedIdentity<Precision> > operator()(int s){
00344         return Operator<Internal::SizedIdentity<Precision> >(s, val);
00345     }
00346     ///@}
00347 };
00348     
00349 ///@internal
00350 ///@brief A variant of Identity which holds a size, allowing dynamic matrices to be constructed
00351 ///@ingroup gInternal
00352 template<class Precision> struct Operator<Internal::SizedIdentity<Precision> > 
00353     : public  Operator<Internal::Identity<Precision> > {
00354 
00355     using Operator<Internal::Identity<Precision> >::val;
00356     
00357     ///@name Constructors
00358     ///@{
00359     Operator(int s, const Precision& v)
00360         :Operator<Internal::Identity<Precision> > (v), my_size(s)
00361     {}
00362     ///@}
00363 
00364     ///@name Sized operator members
00365     ///@{
00366     const int my_size;
00367     int num_rows() const {return my_size;}
00368     int num_cols() const {return my_size;}
00369     ///@}
00370 
00371     ///@name Scalable operator members
00372     ///@{
00373     template<class Pout, class Pmult> Operator<Internal::SizedIdentity<Pout> > scale_me(const Pmult& m) const
00374     {
00375         return Operator<Internal::SizedIdentity<Pout> >(my_size, val*m);
00376     }
00377     ///@}
00378 };
00379 ////////////////////////////////////////////////////////////////////////////////
00380 //
00381 // Addition of scalars to vectors and matrices
00382 //
00383 
00384     
00385 ///@internal
00386 ///@brief Operator to construct a new vector a a vector with a scalar added to every element
00387 ///@ingroup gInternal
00388 template<int S, class P, class B, class Precision> struct Operator<Internal::ScalarsVector<S,P,B,Precision> >
00389 {
00390     const Precision s;      ///<Scalar to add
00391     const Vector<S,P,B>& v; ///<Vector to be added to.
00392     const bool invert_v;    ///<Whether to use + or - \c v
00393 
00394     ///@name Constructors
00395     ///@{
00396     Operator(Precision s_, const Vector<S,P,B>& v_, bool inv)
00397         :s(s_),v(v_),invert_v(inv){}
00398     ///@}
00399 
00400     ///@name Operator members
00401     ///@{
00402     template<int S1, class P1, class B1>
00403     void eval(Vector<S1,P1,B1>& vv) const{
00404         for(int i=0; i < v.size(); i++)
00405             if(invert_v)
00406                 vv[i] = s - v[i];
00407             else
00408                 vv[i] = s + v[i];
00409     }
00410     ///@}
00411 
00412     ///@name Sized operator members
00413     ///@{
00414     int size() const
00415     {
00416         return v.size();
00417     }
00418     ///@}
00419 };
00420 
00421 ///@internal
00422 ///@brief Operator to construct a new matrix a a matrix with a scalar added to every element
00423 ///@ingroup gInternal
00424 template<int R, int C, class P, class B, class Precision> struct Operator<Internal::ScalarsMatrix<R,C,P,B,Precision> >
00425 {
00426     const Precision s;        ///<Scalar to add
00427     const Matrix<R,C,P,B>& m; ///<Vector to be added to.
00428     const bool invert_m;      ///<Whether to use + or - \c m
00429     ///@name Operator members
00430     ///@{
00431     Operator(Precision s_, const Matrix<R,C,P,B>& m_, bool inv)
00432         :s(s_),m(m_),invert_m(inv){}
00433     template<int R1, int C1, class P1, class B1>
00434     void eval(Matrix<R1,C1,P1,B1>& mm) const{
00435         for(int r=0; r < m.num_rows(); r++)
00436             for(int c=0; c < m.num_cols(); c++)
00437                 if(invert_m)
00438                     mm[r][c] = s - m[r][c];
00439                 else
00440                     mm[r][c] = s + m[r][c];
00441     }
00442     ///@}
00443 
00444     ///@name Sized operator members
00445     ///@{
00446     int num_rows() const
00447     {
00448         return m.num_rows();
00449     }
00450     int num_cols() const
00451     {
00452         return m.num_cols();
00453     }
00454     ///@}
00455 };
00456 
00457 ///@internal
00458 ///@brief Generic scalars object. Knows how to be added, knows how to deal with += and so on.
00459 ///See TooN::Ones
00460 ///@ingroup gInternal
00461 template<class P> struct Operator<Internal::Scalars<P> >
00462 {   
00463     ///@name Scalable operator members
00464     ///@{
00465     typedef P Precision;
00466     ///@}
00467 
00468     const Precision s; ///<Value of the scalar being represented.  
00469     
00470     ///@name Constructors
00471     ///@{
00472     Operator(Precision s_)
00473         :s(s_){}
00474 
00475     Operator()
00476     {}
00477     ///@}
00478 
00479     ////////////////////////////////////////
00480     //
00481     // All applications for vector
00482     //
00483     ///@name Operator members
00484     ///@{
00485 
00486     template <int Size, typename P1, typename B1> 
00487     void eval(Vector<Size, P1, B1>& v) const
00488     {
00489         for(int i=0; i < v.size(); i++)
00490             v[i] = (P1)s;
00491     }
00492 
00493     template <int Size, typename P1, typename B1> 
00494     void plusequals(Vector<Size, P1, B1>& v) const
00495     {
00496         for(int i=0; i < v.size(); i++)
00497             v[i] += (P1)s;
00498     }
00499 
00500     template <int Size, typename P1, typename B1>
00501     void minusequals(Vector<Size, P1, B1>& v) const
00502     {
00503         for(int i=0; i < v.size(); ++i)
00504             v[i] -= (P1)s;
00505     }
00506 
00507     template <int Size, typename P1, typename B1> 
00508     Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > add(const Vector<Size, P1, B1>& v) const
00509     {
00510         return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 0);
00511     }
00512 
00513     template <int Size, typename P1, typename B1> 
00514     Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > rsubtract(const Vector<Size, P1, B1>& v) const
00515     {
00516         return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(-s, v, 0);
00517     }
00518 
00519     template <int Size, typename P1, typename B1> 
00520     Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > lsubtract(const Vector<Size, P1, B1>& v) const
00521     {
00522         return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> >(s, v, 1);
00523     }
00524 
00525     ////////////////////////////////////////
00526     //
00527     // All applications for matrix
00528     //
00529 
00530     template <int Rows, int Cols, typename P1, typename B1> 
00531     void eval(Matrix<Rows,Cols, P1, B1>& m) const
00532     {
00533         for(int r=0; r < m.num_rows(); r++)
00534             for(int c=0; c < m.num_cols(); c++)
00535                 m[r][c] = s;
00536     }
00537 
00538     template <int Rows, int Cols, typename P1, typename B1> 
00539     void plusequals(Matrix<Rows,Cols, P1, B1>& m) const
00540     {
00541         for(int r=0; r < m.num_rows(); r++)
00542             for(int c=0; c < m.num_cols(); c++)
00543                 m[r][c] += (P1)s;
00544     }
00545 
00546     template <int Rows, int Cols, typename P1, typename B1> 
00547     void minusequals(Matrix<Rows,Cols, P1, B1>& m) const
00548     {
00549         for(int r=0; r < m.num_rows(); r++)
00550             for(int c=0; c < m.num_cols(); c++)
00551                 m[r][c] -= (P1)s;
00552     }
00553 
00554     template <int Rows, int Cols, typename P1, typename B1> 
00555     Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > add(const Matrix<Rows,Cols, P1, B1>& v) const
00556     {
00557         return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 0);
00558     }
00559 
00560 
00561     template <int Rows, int Cols, typename P1, typename B1> 
00562     Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename Internal::NegType<P>::Type> > rsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00563     {
00564         return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename Internal::NegType<P>::Type > >(-s, v, 0);
00565     }
00566 
00567     template <int Rows, int Cols, typename P1, typename B1> 
00568     Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > lsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
00569     {
00570         return Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(s, v, 1);
00571     }
00572     ///@}
00573     ////////////////////////////////////////
00574     //
00575     // Create sized versions for initialization
00576     //
00577 
00578     ///@name Sizeable operators members
00579     ///@{
00580 
00581     Operator<Internal::SizedScalars<Precision> > operator()(int size) const
00582     {
00583         return Operator<Internal::SizedScalars<Precision> > (s,size);
00584     }
00585 
00586     Operator<Internal::RCScalars<Precision> > operator()(int r, int c) const
00587     {
00588         return Operator<Internal::RCScalars<Precision> > (s,r,c);
00589     }
00590     ///@}
00591 
00592     ///@name Scalable operator members
00593     ///@{
00594     template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > scale_me(const Pmult& m) const
00595     {
00596         return Operator<Internal::Scalars<Pout> >(s*m);
00597     }
00598     ///@}
00599 };
00600 
00601 ///@internal
00602 ///@brief Variant of the Operator<Internal::Scalars> object which holds a size to construct dynamic vectors or square matrices.
00603 ///@ingroup gInternal 
00604 template<class P> struct Operator<Internal::SizedScalars<P> >: public Operator<Internal::Scalars<P> >
00605 {
00606     using Operator<Internal::Scalars<P> >::s;
00607     ///@name Sized operator members
00608     ///@{
00609     const int my_size;
00610     int size() const {
00611         return my_size;
00612     }
00613     int num_rows() const {
00614         return my_size;
00615     }
00616     int num_cols() const {
00617         return my_size;
00618     }
00619     ///@}
00620 
00621     ///@name Constructors
00622     ///@{
00623     Operator(P s, int sz)
00624         :Operator<Internal::Scalars<P> >(s),my_size(sz){}
00625     ///@}
00626         
00627     ///@name Scalable operator members
00628     ///@{
00629     template<class Pout, class Pmult> Operator<Internal::SizedScalars<Pout> > scale_me(const Pmult& m) const
00630     {
00631         return Operator<Internal::SizedScalars<Pout> >(s*m, my_size);
00632     }
00633     ///@}
00634 
00635 private:
00636     void operator()(int);
00637     void operator()(int,int);
00638 };
00639 
00640         
00641 ///@internal
00642 ///@brief Variant of Scalars (see TooN::Ones) which holds two sizes to construct dynamic matrices.
00643 ///@ingroup gInternal
00644 template<class P> struct Operator<Internal::RCScalars<P> >: public Operator<Internal::Scalars<P> >
00645 {
00646     using Operator<Internal::Scalars<P> >::s;
00647 
00648     ///@name Operator members
00649     ///@{
00650     const int my_rows, my_cols;
00651     int num_rows() const {
00652         return my_rows;
00653     }
00654     int num_cols() const {
00655         return my_cols;
00656     }
00657         
00658     Operator(P s, int r, int c)
00659         :Operator<Internal::Scalars<P> >(s),my_rows(r),my_cols(c)
00660     {}
00661         
00662     template<class Pout, class Pmult> Operator<Internal::RCScalars<Pout> > scale_me(const Pmult& m) const
00663     {
00664         return Operator<Internal::RCScalars<Pout> >(s*m, my_rows, my_cols);
00665     }
00666 
00667     ///@}
00668 private:
00669     void operator()(int);
00670     void operator()(int,int);
00671 };
00672 
00673 
00674 ////////////////////////////////////////////////////////////////////////////////
00675 //
00676 // How to scale scalable operators
00677 //
00678     
00679 template<template<class> class Op, class Pl, class Pr> 
00680 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00681 operator*(const Pl& l, const Operator<Op<Pr> >& r)
00682 {
00683     return r.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(l); 
00684 }
00685 
00686 template<template<class> class Op, class Pl, class Pr> 
00687 Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
00688 operator*(const Operator<Op<Pl> >& l, const Pr&  r)
00689 {
00690     return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type>(r); 
00691 }
00692 
00693 template<template<class> class Op, class Pl, class Pr> 
00694 Operator<Op<typename Internal::DivideType<Pl, Pr>::type > >
00695 operator/(const Operator<Op<Pl> >& l, const Pr&  r)
00696 {
00697     return l.template scale_me<typename Internal::MultiplyType<Pl, Pr>::type, Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r); 
00698 }
00699 
00700 
00701 template<class Op>
00702 Operator<Op> operator-(const Operator<Op>& o)
00703 {
00704     return o.template scale_me<typename Operator<Op>::Precision>(-1);
00705 }
00706 
00707 //Special case for negating One
00708 template<template<class>class Op>
00709 Operator<Op<DefaultPrecision> > operator-(const Operator<Op<Internal::One> >& o)
00710 {
00711     return o.template scale_me<DefaultPrecision>(-1);
00712 }
00713 
00714 /**This function is used to add a scalar to every element of a vector or
00715    matrix. For example:
00716    @code
00717    Vector<3> v;
00718    ...
00719    ...
00720    v += Ones * 3; //Add 3 to every element of v;
00721    @endcode
00722    Both + and += are supported on vectors,matrices and slices.
00723 
00724    For construction of dynamic vectors and matrices, a size needs to be given:
00725    @code
00726        Vector<3> v_static = Ones;    
00727        Vector<>  v_dynamic = Ones(3); //Construct a 3x1 vector full one 1s
00728        Matrix<3> m_static = Ones;     
00729        Matrix<>  m_dynamic = Ones(3,4); //Construct a 3x4 matrix
00730    @endcode
00731    @ingroup gLinAlg
00732 */
00733 static const Operator<Internal::Scalars<Internal::One> > Ones;
00734 
00735 
00736 /**This function is used to initialize vectors and matrices to zero.
00737    For construction of dynamic vectors and matrices, a size needs to be given.
00738    For example:
00739    @code
00740        Vector<3> v_static = Zeros;
00741        Vector<>  v_dynamic = Zeros(3); //Construct a 3x1 vector
00742        Matrix<3> m_static = Zeros;
00743        Matrix<>  m_dynamic = Zeros(3,4); //Construct a 3x4 matrix
00744    @endcode
00745    @ingroup gLinAlg
00746 */
00747 static Operator<Internal::Zero> Zeros;
00748 
00749 /**This function is used to add a scalar to the diagonal of a matrix,
00750    or to construct matrices.
00751    For example:
00752    @code
00753    Matrix<3> v;
00754    ...
00755    ...
00756    Matrix<3> u = v  + Identity * 4;
00757    @endcode
00758    Both + and += are supported. For assignment, if the matrix is non-square,
00759    then all elements off the leading diagonal are set to zero.
00760    For construction of dynamic matrices, a size needs to be given:
00761    @code
00762        Matrix<3> m_static = Identity;     
00763        Matrix<>  m_dynamic = Identity(3); //Construct a 3x3 matrix
00764    @endcode
00765    @ingroup gLinAlg
00766 */
00767 
00768 static Operator<Internal::Identity<Internal::One> > Identity;
00769 
00770 }
00771