|
STK++ 1.0
|
00001 /*--------------------------------------------------------------------*/ 00002 /* Copyright (C) 2004-2007 Serge Iovleff 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as 00006 published by the Free Software Foundation; either version 2 of the 00007 License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this program; if not, write to the 00016 Free Software Foundation, Inc., 00017 59 Temple Place, 00018 Suite 330, 00019 Boston, MA 02111-1307 00020 USA 00021 00022 Contact : Serge.Iovleff@stkpp.org 00023 */ 00024 00025 /* 00026 * Project: Algebra 00027 * Purpose: Allow to inline Algebraic expressions using template. 00028 * Author: Serge Iovleff, serge.iovleff@stkpp.org 00029 * 00030 **/ 00031 00036 #ifndef STK_TEXPALGEBRA_H 00037 #define STK_TEXPALGEBRA_H 00038 00039 #include "../../Arrays/include/STK_MatrixSquare.h" 00040 #include "../../Arrays/include/STK_MatrixLowerTriangular.h" 00041 #include "../../Arrays/include/STK_MatrixUpperTriangular.h" 00042 00043 #include "STK_TOperator.h" 00044 00045 00046 namespace STK 00047 { 00055 template<class Op, class ExpLeft, class ExpRight> 00056 class BinOpBase 00057 { 00058 protected: 00059 const ExpLeft& lhs_; 00060 const ExpRight& rhs_; 00061 00063 BinOpBase(const ExpLeft& X, const ExpRight& Y) : lhs_(X), rhs_(Y) 00064 { ;} 00065 00067 ~BinOpBase() { ;} 00068 00069 public: 00073 inline Real operator[](Integer i) const 00074 { return Op::apply(lhs_[i], rhs_[i]);} 00075 00079 inline Real operator()(Integer i, Integer j) const 00080 { return Op::apply(lhs_(i,j), rhs_(i,j));} 00081 }; 00082 00087 template<class Op, class ExpRight> 00088 class BinOpBase<Op, Real, ExpRight> 00089 { 00090 protected: 00091 Real const& lhs_; 00092 const ExpRight& rhs_; 00093 00095 BinOpBase(Real const& y, const ExpRight& X) : lhs_(y), rhs_(X) 00096 { ;} 00097 00099 ~BinOpBase(){ ;} 00100 00101 public: 00105 inline Real operator[](Integer i) const 00106 { return Op::apply(lhs_,rhs_[i]);} 00107 00111 inline Real operator()(Integer i, Integer j) const 00112 { return Op::apply(lhs_,rhs_(i,j));} 00113 }; 00114 00118 template<class Op, class ExpLeft> 00119 class BinOpBase<Op, ExpLeft, Real> 00120 { 00121 protected: 00122 const ExpLeft& lhs_; 00123 Real const& rhs_; 00124 00126 BinOpBase(const ExpLeft& X, Real const& y) : lhs_(X), rhs_(y) 00127 { ;} 00128 00130 ~BinOpBase(){ ;} 00131 00132 public: 00136 inline Real operator[](Integer i) const 00137 { return Op::apply(lhs_[i],rhs_);} 00138 00142 inline Real operator()(Integer i, Integer j) const 00143 { return Op::apply(lhs_(i,j),rhs_);} 00144 }; 00145 00146 00151 template<class ExpRight> 00152 class BinOpBase<Mult, Matrix, ExpRight> 00153 { 00154 protected: 00155 Matrix const& lhs_; 00156 const ExpRight& rhs_; 00157 00159 BinOpBase(const Matrix& y, const ExpRight& X) : lhs_(y), rhs_(X) 00160 { ;} 00161 00163 ~BinOpBase(){ ;} 00164 00165 public: 00169 inline Real operator[](Integer i) const 00170 { 00171 Real aux = 0.0; 00172 for (Integer j = lhs_.firstCol(); j <=lhs_.lastCol(); j++) 00173 aux += Mult::apply(lhs_(i,j),rhs_[j]); 00174 return aux; 00175 } 00176 }; 00177 00182 template<class ExpLeft> 00183 class BinOpBase<Mult, ExpLeft, Matrix> 00184 { 00185 protected: 00186 const ExpLeft& lhs_; 00187 Matrix const& rhs_; 00188 00190 BinOpBase(const ExpLeft& X, Matrix const& y) : lhs_(X), rhs_(y) 00191 { ;} 00192 00194 ~BinOpBase(){ ;} 00195 00196 public: 00200 inline Real operator[](Integer i) const 00201 { 00202 Real aux = 0.0; 00203 for (Integer j = rhs_.firstRow(); j<= rhs_.lastRow(); j++) 00204 aux += Mult::apply(lhs_[j],rhs_(j,i)); 00205 return aux; 00206 } 00207 }; 00208 00213 template<class ExpRight> 00214 class BinOpBase<Mult, MatrixSquare, ExpRight> 00215 { 00216 protected: 00217 MatrixSquare const& lhs_; 00218 const ExpRight& rhs_; 00219 00221 BinOpBase(MatrixSquare const& y, const ExpRight& X) : lhs_(y), rhs_(X) 00222 { ;} 00223 00225 ~BinOpBase(){ ;} 00226 00227 public: 00231 inline Real operator[](Integer i) const 00232 { 00233 Real aux = 0.0; 00234 for (Integer j = lhs_.firstCol(); j <=lhs_.lastCol(); j++) 00235 aux += Mult::apply(lhs_(i,j),rhs_[j]); 00236 return aux; 00237 } 00238 }; 00239 00244 template<class ExpLeft> 00245 class BinOpBase<Mult, ExpLeft, MatrixSquare> 00246 { 00247 protected: 00248 const ExpLeft& lhs_; 00249 MatrixSquare const& rhs_; 00250 00252 BinOpBase(const ExpLeft& X, MatrixSquare const& y) : lhs_(X), rhs_(y) 00253 { ;} 00254 00256 ~BinOpBase(){ ;} 00257 00258 public: 00262 inline Real operator[](Integer i) const 00263 { 00264 Real aux = 0.0; 00265 for (Integer j = rhs_.firstRow(); j<= rhs_.lastRow(); j++) 00266 aux += Mult::apply(lhs_[j],rhs_(j,i)); 00267 return aux; 00268 } 00269 }; 00270 00275 template<class ExpRight> 00276 class BinOpBase<Mult, MatrixUpperTriangular, ExpRight> 00277 { 00278 protected: 00279 const MatrixUpperTriangular& lhs_; 00280 const ExpRight& rhs_; 00281 00283 BinOpBase( const MatrixUpperTriangular& y, const ExpRight& X) 00284 : lhs_(y), rhs_(X) 00285 { ;} 00286 00288 ~BinOpBase(){ ;} 00289 00290 public: 00294 inline Real operator[](Integer i) const 00295 { 00296 Real aux = 0.0; 00297 for (Integer j = lhs_.compFirstHo(i); j <=lhs_.lastCol(); j++) 00298 aux += Mult::apply(lhs_(i,j),rhs_[j]); 00299 return aux; 00300 } 00301 }; 00302 00307 template<class ExpLeft> 00308 class BinOpBase<Mult, ExpLeft, MatrixUpperTriangular> 00309 { 00310 protected: 00311 const ExpLeft& lhs_; 00312 const MatrixUpperTriangular& rhs_; 00313 00315 BinOpBase( const ExpLeft& X, const MatrixUpperTriangular& y) 00316 : lhs_(X), rhs_(y) 00317 { ;} 00318 00320 ~BinOpBase(){ ;} 00321 00322 public: 00326 inline Real operator[](Integer i) const 00327 { 00328 Real aux = 0.0; 00329 for (Integer j = rhs_.firstRow(); j<= rhs_.compLastVe(i); j++) 00330 aux += Mult::apply(lhs_[j], rhs_(j,i)); 00331 return aux; 00332 } 00333 }; 00334 00339 template<class ExpRight> 00340 class BinOpBase<Mult, MatrixLowerTriangular, ExpRight> 00341 { 00342 protected: 00343 const MatrixLowerTriangular& lhs_; 00344 const ExpRight& rhs_; 00345 00347 BinOpBase( const MatrixLowerTriangular& y, const ExpRight& X) 00348 : lhs_(y), rhs_(X) 00349 { ;} 00350 00352 ~BinOpBase(){ ;} 00353 00354 public: 00358 inline Real operator[](Integer i) const 00359 { 00360 Real aux = 0.0; 00361 for (Integer j = lhs_.firstCol(); j <=lhs_.compLastHo(i); j++) 00362 aux += Mult::apply(lhs_(i,j),rhs_[j]); 00363 return aux; 00364 } 00365 }; 00366 00371 template<class ExpLeft> 00372 class BinOpBase<Mult, ExpLeft, MatrixLowerTriangular> 00373 { 00374 protected: 00375 const ExpLeft& lhs_; 00376 const MatrixLowerTriangular& rhs_; 00377 00379 BinOpBase( const ExpLeft& X, const MatrixLowerTriangular& y) 00380 : lhs_(X), rhs_(y) 00381 { ;} 00382 00384 ~BinOpBase(){ ;} 00385 00386 public: 00390 inline Real operator[](Integer i) const 00391 { 00392 Real aux = 0.0; 00393 for (Integer j = rhs_.compFirstVe(i); j<= rhs_.lastRow(); j++) 00394 aux += Mult::apply(lhs_[j], rhs_(j,i)); 00395 return aux; 00396 } 00397 }; 00398 00403 template<class Op, class ExpLeft, class ExpRight> 00404 class BinOp : public BinOpBase<Op, ExpLeft, ExpRight> 00405 { 00406 typedef BinOp<Op, ExpLeft, ExpRight> _This; 00407 00408 public: 00409 /* constructor */ 00410 BinOp( const ExpLeft& X, const ExpRight& Y) 00411 : BinOpBase<Op, ExpLeft, ExpRight>(X,Y) 00412 { ;} 00413 00415 ~BinOp(){ ;} 00416 }; 00417 00421 template<class Op, class Exp> 00422 class UnOp 00423 { 00424 typedef UnOp<Op, Exp> _This; 00425 00426 protected: 00427 const Exp& rhs_; 00428 00429 public: 00431 UnOp(const Exp& X) : rhs_(X) 00432 { ;} 00433 00435 ~UnOp(){} 00436 00438 Real operator[](Integer i) const 00439 { return Op::apply(rhs_[i]);} 00440 00442 Real operator()(Integer i) const 00443 { return Op::apply(rhs_(i));} 00444 00446 template<class Right> 00447 BinOp<Plus, _This, Right> operator+(const Right& rhs) 00448 { return BinOp<Plus, _This, Right>(*this, rhs); } 00449 00451 template<class Right> 00452 BinOp<Minus, _This, Right> operator-(const Right& rhs) 00453 { return BinOp<Minus, _This, Right>(*this, rhs);} 00454 00456 template<class Right> 00457 BinOp<Mult, _This, Right> operator*(const Right& rhs) 00458 { return BinOp<Mult, _This, Right>(*this, rhs);} 00459 00461 template<class Right> 00462 BinOp<Div, _This, Right> 00463 operator/(const Right& rhs) 00464 { return BinOp<Div, _This, Right>(*this, rhs);} 00465 }; 00466 00467 } // Namespace STK 00468 00469 #endif //STK_TEXPALGEBRA_H