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