STK++ 1.0
STK_RecursiveArray2D.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 RecursiveArray2D classes.
00028  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00029  *
00030  **/
00031 
00036 #ifndef STK_RECURSIVEARRAY2D_H
00037 #define STK_RECURSIVEARRAY2D_H
00038 
00039 #include "STK_ITArray2D.h"
00040 
00041 namespace STK
00042 {
00043 
00065 template<class TYPE, class Container2D >
00066 class RecursiveArray2D : public ITArray2D< TYPE, Container2D >
00067 {
00068   public:
00070     typedef Array1D<TYPE> TContainerVe;
00071 
00073     typedef ArrayHo<TYPE> TContainerHo;
00074 
00076     typedef ITArray2D<TYPE, Container2D > _ITArray2DType;
00077 
00082     RecursiveArray2D( Range const& I = Range(), Range const& J = Range())
00083            : _ITArray2DType(I, J)
00084     {
00085       // initialize vertically the container
00086       this->initializeCols(J);
00087     }
00088 
00095     RecursiveArray2D( Range const& I, Range const& J, TYPE const& v)
00096            : _ITArray2DType(I, J)
00097     {
00098       // initialize vertically the container
00099       this->initializeCols(J);
00100       // initialize with v
00101       for (Integer j=J.first(); j<=J.last(); j++)
00102       {
00103         TYPE* p(this->data(j));
00104         for (Integer i=I.first(); i<=I.last(); i++) p[i]= v;
00105       }
00106     }
00107 
00112     RecursiveArray2D( const RecursiveArray2D &T, bool ref=false)
00113            : _ITArray2DType(T, ref)
00114     {
00115       if (!ref)
00116       {
00117         // initialize the Cols and Rows
00118         this->initializeCols(T.rangeHo());
00119         for (Integer j=T.firstCol(); j<=T.lastCol(); j++)
00120         {
00121           // ptr on the rows
00122           TYPE* p = this->data(j);
00123           TYPE* pt= T.data(j);
00124           for (Integer i=T.firstRow(); i<=T.lastRow(); i++) p[i]=pt[i];
00125         }
00126       }
00127     }
00128 
00134     RecursiveArray2D( const RecursiveArray2D& T, Range const& I, Range const& J)
00135            : _ITArray2DType(T, I, J)
00136     { ;}
00137 
00143     RecursiveArray2D( TYPE** q, Range const& I, Range const& J)
00144            : _ITArray2DType(q, I, J)
00145     { ;}
00146 
00148     virtual ~Array2D()
00149     { ;}
00150 
00155     inline RecursiveArray2D sub(Range const& I, Range const& J) const
00156     { return RecursiveArray2D(*this, I, J);}
00157 
00162     inline Range compRangeVe( Integer const& icol) const
00163     { return this->rangeVe();}
00164 
00171     inline RecursiveArray2D& operator=(const RecursiveArray2D &T)
00172     {
00173       // Resize if necessary.
00174       if ( (this->sizeVe() != T.sizeVe())
00175          ||(this->sizeHo() != T.sizeHo())
00176          )
00177         this->resize(T.rangeVe(), T.rangeHo());
00178       // Copy without overlapping
00179       if (T.firstRow()>=this->firstRow())
00180       {
00181         if (T.firstCol()>=this->firstCol())
00182         {
00183           for ( Integer jt=T.firstCol(), j=this->firstCol()
00184               ; jt<=T.lastCol()
00185               ; j++, jt++
00186               )
00187           {
00188             TYPE *p =this->data(j), *pt =T.data(jt);
00189             for ( Integer it=T.firstRow(), i=this->firstRow()
00190                 ; it<=T.lastRow()
00191                 ; i++, it++
00192                 )
00193               p[i] = pt[it];
00194           }
00195           return *this;
00196         }
00197         // T.firstCol()<this->firstCol()
00198         for ( Integer jt=T.lastCol(), j=this->lastCol()
00199             ; jt>=T.firstCol()
00200             ; j--, jt--
00201             )
00202         {
00203           TYPE *p =this->data(j), *pt =T.data(jt);
00204           for ( Integer it=T.firstRow(), i=this->firstRow()
00205               ; it<=T.lastRow()
00206               ; i++, it++
00207               )
00208             p[i] = pt[it];
00209         }
00210         return *this;
00211       }
00212       // T.firstRow()<this->firstRow()
00213       if (T.firstCol()>=this->firstCol())
00214       {
00215         for ( Integer jt=T.firstCol(), j=this->firstCol()
00216             ; jt<=T.lastCol()
00217             ; j++, jt++
00218             )
00219         {
00220           TYPE *p =this->data(j), *pt =T.data(jt);
00221           for ( Integer it=T.lastRow(), i=this->lastRow()
00222               ; it>=T.firstRow()
00223               ; i--, it--
00224               )
00225             p[i] = pt[it] ;
00226         }
00227         return *this;
00228       }
00229       // T.firstCol()<this->firstCol()
00230       for ( Integer jt=T.lastCol(), j=this->lastCol()
00231           ; jt>=T.firstCol()
00232           ; j--, jt--
00233           )
00234       {
00235         TYPE *p =this->data(j), *pt =T.data(jt);
00236         for ( Integer it=T.lastRow(), i=this->lastRow()
00237             ; it>=T.firstRow()
00238             ; i--, it--
00239             )
00240           p[i] = pt[it];
00241       }
00242       return *this;
00243     }
00244 
00248     inline RecursiveArray2D& operator=(TYPE const& v)
00249     {
00250       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00251       { TYPE *p =this->data(j);
00252         for (Integer i=this->firstRow(); i<=this->lastRow(); i++)
00253           p[i] = v;
00254       }
00255       return *this;
00256     }
00257 
00262     void swapRows( Integer const& pos1, Integer pos2)
00263     {
00264 #ifdef STK_BOUNDS_CHECK
00265       // check conditions
00266       if (this->firstRow() > pos1)
00267       { throw out_of_range("ITArray2D::swapRows(pos1, pos2) "
00268                            "this->firstRow() > pos1");
00269       }
00270       if (this->lastRow() < pos1)
00271       { throw out_of_range("ITArray2D::swapRows(pos1, pos2) "
00272                            "this->lastRow() < pos1");
00273       }
00274       if (this->firstRow() > pos2)
00275       { throw out_of_range("ITArray2D::swapRows(pos1, pos2) "
00276                            "this->firstRow() > pos2");
00277       }
00278       if (this->lastRow() < pos2)
00279       { throw out_of_range("ITArray2D::swapRows(pos1, pos2) "
00280                            "this->lastRow() < pos2");
00281       }
00282 #endif
00283       // swap
00284       for (Integer j=this->firstCol(); j<=this->lastCol(); j++)
00285       {
00286         TYPE aux(this->asLeaf().elt(pos1, j));
00287         this->asLeaf().elt(pos1, j) = this->asLeaf().elt(pos2, j);
00288         this->asLeaf().elt(pos2, j) = aux;
00289       }
00290     }
00291 };
00292 
00293 } // namespace STK
00294 
00295 #endif
00296 // STK_RECURSIVEARRAY2D_H