TooN 2.1
|
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