TooN 2.0.0-beta8
|
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