STK++ 1.0
STK_Matrix.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:  stkpp::Arrays
00027  * Purpose:  Define the Matrix classes.
00028  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00029  *
00030  **/
00031 
00036 #ifndef STK_MATRIX_H
00037 #define STK_MATRIX_H
00038 
00039 #include "STK_Vector.h"
00040 #include "STK_Point.h"
00041 
00042 #include "STK_Array2D.h"
00043 #include "../../Sdk/include/STK_ContainerTraits.h"
00044 
00045 namespace STK
00046 {
00047 
00053 typedef Array2D<Real> Matrix;
00054 
00067 template<>
00068 class Array2D<Real> : public ITArray2D< Real, Array2D<Real> >
00069 {
00071   typedef ITArray2D<Real, Array2D<Real> > _ITArray2DType;
00072 
00073   public:
00078     Array2D( Range const& I = Range(), Range const& J = Range())
00079            : _ITArray2DType(I, J)
00080     {
00081       // initialize vertically the container
00082       this->initializeCols(J);
00083     }
00084 
00091     Array2D( Range const& I, Range const& J, Real const& v)
00092            : _ITArray2DType(I, J)
00093     {
00094       // initialize vertically the container
00095       this->initializeCols(J);
00096       // initialize with v
00097       for (Integer j=J.first(); j<=J.last(); j++)
00098       {
00099         Real* p(this->data(j));
00100         for (Integer i=I.first(); i<=I.last(); i++) p[i]= v;
00101       }
00102     }
00103 
00108     Array2D( const Array2D &T, bool ref=false)
00109            : _ITArray2DType(T, ref)
00110     { 
00111       if (!ref)
00112       {
00113         // initialize the Cols and Rows
00114         this->initializeCols(T.rangeHo());
00115         for (Integer j=T.firstCol(); j<=T.lastCol(); j++)
00116         {
00117           // ptr on the rows
00118           Real* p = this->data(j);
00119           Real* pt= T.data(j);
00120           for (Integer i=T.firstRow(); i<=T.lastRow(); i++) p[i]=pt[i];
00121         }
00122       }
00123     }
00124 
00130     Array2D( const Array2D& T, Range const& I, Range const& J)
00131            : _ITArray2DType(T, I, J)
00132     { ;}
00133 
00139     Array2D( Real** q, Range const& I, Range const& J)
00140            : _ITArray2DType(q, I, J)
00141     { ;}
00142 
00144     virtual ~Array2D()
00145     { ;}
00146 
00148     inline Real& elt(Integer i, Integer j)
00149     { return this->data(j)[i];}
00150 
00152     inline Real const& elt(Integer i, Integer j) const
00153     { return this->data(j)[i];}
00154 
00156     inline Array2D sub(Range const& I, Range const& J) const
00157     { return Array2D(*this, I, J);} 
00158 
00160     inline Vector col( Integer j) const
00161     { return Vector(this->data(j), this->rangeVe(), j);}
00162 
00164     inline Vector col(Range const& I, Integer j) const
00165     { return Vector(this->data(j), I, j);}
00166 
00171     inline Point row( Integer const& i) const
00172     { return Point(*this, this->rangeHo(), i);}
00173 
00175     inline Point row(Integer i, Range const& J) const
00176     { return Point(*this, J, i);}
00177 
00183     inline Range compRangeVe( Integer const& icol) const
00184     { return this->rangeVe();}
00185 
00190     void swapRows( Integer const& pos1, Integer pos2)
00191     {
00192 #ifdef STK_BOUNDS_CHECK
00193       // check conditions
00194       if (this->firstRow() > pos1)
00195       { throw out_of_range("Array2D::swapRows(pos1, pos2) "
00196                                 "this->firstRow() > pos1");
00197       }
00198       if (this->lastRow() < pos1)
00199       { throw out_of_range("Array2D::swapRows(pos1, pos2) "
00200                                 "this->lastRow() < pos1");
00201       }
00202       if (this->firstRow() > pos2)
00203       { throw out_of_range("Array2D::swapRows(pos1, pos2) "
00204                                 "this->firstRow() > pos2");
00205       }
00206       if (this->lastRow() < pos2)
00207       { throw out_of_range("Array2D::swapRows(pos1, pos2) "
00208                                 "this->lastRow() < pos2");
00209       }
00210 #endif
00211       // swap
00212       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00213       {
00214         Real aux(this->asLeaf().elt(pos1, j));
00215         this->asLeaf().elt(pos1, j) = this->asLeaf().elt(pos2, j);
00216         this->asLeaf().elt(pos2, j) = aux;
00217       }
00218     }
00219 
00226     inline Array2D& operator=(const Array2D &T)
00227     {
00228 //      // clear any allocated memory
00229 //      this->clear();
00230 //      // set AllocatorBase part
00231 //      this->setRef(true);
00232 //      this->setPtrData(T.ptrData(), T.rangeData());
00233 //      // ITContainer2D part
00234 //      this->setRange(T.rangeVe_, T.rangeHo_);
00235 //      // Array2D part
00236 //      rangeCols_ = T.rangeCols();
00237 //      this->setCapacityHo( T.capacityHo());
00238       // Resize if necessary.
00239       if ( (this->sizeVe() != T.sizeVe())
00240          ||(this->sizeHo() != T.sizeHo())
00241          )
00242         this->resize(T.rangeVe(), T.rangeHo());
00243       // Copy without overlapping
00244       if (T.firstRow()>=this->firstRow())
00245       {
00246         if (T.firstCol()>=this->firstCol())
00247         {
00248           for ( Integer jt=T.firstCol(), j=this->firstCol()
00249               ; jt<=T.lastCol()
00250               ; j++, jt++
00251               )
00252           {
00253             Real *p =this->data(j), *pt =T.data(jt);
00254             for ( Integer it=T.firstRow(), i=this->firstRow()
00255                 ; it<=T.lastRow()
00256                 ; i++, it++
00257                 )
00258               p[i] = pt[it];
00259           }
00260           return *this;
00261         }
00262         // T.firstCol()<this->firstCol()
00263         for ( Integer jt=T.lastCol(), j=this->lastCol()
00264             ; jt>=T.firstCol()
00265             ; j--, jt--
00266             )
00267         {
00268           Real *p =this->data(j), *pt =T.data(jt);
00269           for ( Integer it=T.firstRow(), i=this->firstRow()
00270               ; it<=T.lastRow()
00271               ; i++, it++
00272               )
00273             p[i] = pt[it];
00274         }
00275         return *this;
00276       }
00277       // T.firstRow()<this->firstRow()
00278       if (T.firstCol()>=this->firstCol())
00279       {
00280         for ( Integer jt=T.firstCol(), j=this->firstCol()
00281             ; jt<=T.lastCol()
00282             ; j++, jt++
00283             )
00284         {
00285           Real *p =this->data(j), *pt =T.data(jt);
00286           for ( Integer it=T.lastRow(), i=this->lastRow()
00287               ; it>=T.firstRow()
00288               ; i--, it--
00289               )
00290             p[i] = pt[it] ;
00291         }
00292         return *this;
00293       }
00294       // T.firstCol()<this->firstCol()
00295       for ( Integer jt=T.lastCol(), j=this->lastCol()
00296           ; jt>=T.firstCol()
00297           ; j--, jt--
00298           )
00299       {
00300         Real *p =this->data(j), *pt =T.data(jt);
00301         for ( Integer it=T.lastRow(), i=this->lastRow()
00302             ; it>=T.firstRow()
00303             ; i--, it--
00304             )
00305           p[i] = pt[it];
00306       }
00307       return *this;
00308     }
00309 
00313     inline Array2D& operator=(Real const& v)
00314     {
00315       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00316       { Real *p =this->data(j);
00317         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00318           p[i] = v;
00319       }
00320       return *this;
00321     }
00322 
00326     inline Array2D& operator+=(Real const& v)
00327     {
00328       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00329       { Real *p =this->data(j);
00330         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00331           p[i] += v;
00332       }
00333       return *this;
00334     }
00335 
00339     inline Array2D& operator-=(Real const& v)
00340     {
00341       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00342       { Real *p =this->data(j);
00343         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00344           p[i] += v;
00345       }
00346       return *this;
00347     }
00348 
00352     inline Array2D& operator*=(Real const& v)
00353     {
00354       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00355       { Real *p =this->data(j);
00356         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00357           p[i] += v;
00358       }
00359       return *this;
00360     }
00361 
00365     inline Array2D& operator/=(Real const& v)
00366     {
00367       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00368       { Real *p =this->data(j);
00369         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00370           p[i] /= v;
00371       }
00372       return *this;
00373     }
00374 
00378     template< class Exp>
00379     inline Array2D& operator=(const Exp& rhs)
00380     {
00381       for (Integer j=this->firstCol(); j<=this->lastCol(); ++j)
00382         for (Integer i=this->firstRow(); i<=this->lastRow(); ++i)
00383         {
00384           this->elt(i,j) = rhs(i,j);
00385         }
00386       return *this;
00387     }
00388 
00392     template< class Exp>
00393     inline Array2D& operator+=(const Exp& rhs)
00394     {
00395       for (Integer j=this->firstCol(); j<=this->lastCol(); ++j)
00396         for (Integer i=this->firstRow(); i<=this->lastRow(); ++i)
00397         {
00398           this->elt(i,j) += rhs(i,j);
00399         }
00400       return *this;
00401     }
00402 
00406     template< class Exp>
00407     inline Array2D& operator-=(const Exp& rhs)
00408     {
00409         for (Integer j=this->firstCol(); j<=this->lastCol(); ++j)
00410           for (Integer i=this->firstRow(); i<=this->lastRow(); ++i)
00411           {
00412             this->elt(i,j) -= rhs(i,j);
00413           }
00414       return *this;
00415     }
00416 
00420     template< class Exp>
00421     inline Array2D& operator/=(const Exp& rhs)
00422     {
00423         for (Integer j=this->firstCol(); j<=this->lastCol(); ++j)
00424           for (Integer i=this->firstRow(); i<=this->lastRow(); ++i)
00425           {
00426             this->elt(i,j) /= rhs(i,j);
00427           }
00428       return *this;
00429     }
00430 
00434     template< class Exp>
00435     inline Array2D& operator*=(const Exp& rhs)
00436     {
00437         for (Integer j=this->firstCol(); j<=this->lastCol(); ++j)
00438           for (Integer i=this->firstRow(); i<=this->lastRow(); ++i)
00439           {
00440             this->elt(i,j) *= rhs(i,j);
00441           }
00442       return *this;
00443     }
00444 };
00445 
00446 } // namespace STK
00447 
00448 #endif
00449 // STK_MATRIX_H