TooN: internal/objects.h Source File

TooN 2.0.0-beta8

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List

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