|
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: 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