STK++ 1.0
STK_TExpAlgebra.h
Go to the documentation of this file.
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