![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_UMATRIX_TLATE_H 00024 #define O2SCL_UMATRIX_TLATE_H 00025 00026 /** \file umatrix_tlate.h 00027 \brief File for definitions of matrices 00028 */ 00029 00030 #include <iostream> 00031 #include <cstdlib> 00032 #include <string> 00033 #include <fstream> 00034 #include <sstream> 00035 00036 #include <gsl/gsl_matrix.h> 00037 #include <gsl/gsl_ieee_utils.h> 00038 00039 #include <o2scl/err_hnd.h> 00040 #include <o2scl/uvector_tlate.h> 00041 00042 #ifndef DOXYGENP 00043 namespace o2scl { 00044 #endif 00045 00046 /** \brief A matrix view of double-precision numbers 00047 */ 00048 template<class data_t> class umatrix_const_view_tlate { 00049 00050 #ifndef DOXYGEN_INTERNAL 00051 00052 protected: 00053 00054 /// The data 00055 data_t *data; 00056 /// The number of rows 00057 size_t size1; 00058 /// The number of columns 00059 size_t size2; 00060 /// Zero if memory is owned elsewhere, 1 otherwise 00061 int owner; 00062 00063 #endif 00064 00065 public: 00066 00067 /// \name Copy constructors 00068 //@{ 00069 /// Shallow copy constructor - create a new view of the same matrix 00070 umatrix_const_view_tlate(const umatrix_const_view_tlate &v) { 00071 data=v.data; 00072 size1=v.size1; 00073 size2=v.size2; 00074 owner=0; 00075 } 00076 00077 /// Shallow copy constructor - create a new view of the same matrix 00078 umatrix_const_view_tlate& operator=(const umatrix_const_view_tlate &v) { 00079 data=v.data; 00080 size1=v.size1; 00081 size2=v.size2; 00082 owner=0; 00083 00084 return *this; 00085 } 00086 //@} 00087 00088 ~umatrix_const_view_tlate() {}; 00089 00090 /// \name Get and set methods 00091 //@{ 00092 /** \brief Array-like indexing 00093 */ 00094 const data_t *operator[](size_t i) const { 00095 #if O2SCL_NO_RANGE_CHECK 00096 #else 00097 if (i>=size1) { 00098 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00099 +" in umatrix_const_view_tlate::operator[] const. Size: "+ 00100 itos(size1)+ 00101 " (index should be less than size).").c_str(),gsl_eindex); 00102 return data; 00103 } 00104 #endif 00105 return data+i*size2; 00106 } 00107 00108 /** \brief Array-like indexing 00109 */ 00110 const data_t &operator()(size_t i, size_t j) const { 00111 #if O2SCL_NO_RANGE_CHECK 00112 #else 00113 if (i>=size1 || j>=size2) { 00114 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00115 ") out of bounds" 00116 +" in umatrix_const_view_tlate::operator() const. Sizes: ("+ 00117 itos(size1)+","+itos(size2)+ 00118 ") (index should be less than size).").c_str(),gsl_eindex); 00119 return *data; 00120 } 00121 #endif 00122 return *(data+i*size2+j); 00123 } 00124 00125 /** \brief Get (with optional range-checking) */ 00126 data_t get(size_t i, size_t j) const { 00127 #if O2SCL_NO_RANGE_CHECK 00128 #else 00129 if (i>=size1 || j>=size2) { 00130 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00131 ") out of bounds" 00132 +" in umatrix_const_view_tlate::get(). Sizes: ("+ 00133 itos(size1)+","+itos(size2)+ 00134 ") (index should be less than size).").c_str(),gsl_eindex); 00135 return *data; 00136 } 00137 #endif 00138 return (data+i*size2+j); 00139 } 00140 00141 /** \brief Get pointer (with optional range-checking) */ 00142 const data_t *get_const_ptr(size_t i, size_t j) const { 00143 #if O2SCL_NO_RANGE_CHECK 00144 #else 00145 if (i>=size1 || j>=size2) { 00146 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00147 ") out of bounds" 00148 +" in umatrix_const_view_tlate::get_const_ptr(). Sizes: ("+ 00149 itos(size1)+","+itos(size2)+ 00150 ") (index should be less than size).").c_str(),gsl_eindex); 00151 return (const data_t *)data; 00152 } 00153 #endif 00154 return (const data_t *)(data+i*size2+j); 00155 } 00156 00157 /** \brief Method to return number of rows 00158 00159 If no memory has been allocated, this will quietly 00160 return zero. 00161 */ 00162 size_t rows() const { 00163 return size1; 00164 } 00165 00166 /** \brief Method to return number of columns 00167 00168 If no memory has been allocated, this will quietly 00169 return zero. 00170 */ 00171 size_t cols() const { 00172 return size2; 00173 } 00174 //@} 00175 00176 /// \name Other methods 00177 //@{ 00178 /// Return true if this object owns the data it refers to 00179 bool is_owner() const { 00180 if (owner==1) return true; 00181 return false; 00182 } 00183 //@} 00184 00185 #ifndef DOXYGEN_INTERNAL 00186 00187 protected: 00188 00189 /** \brief Empty constructor provided for use by 00190 umatrix_tlate(const umatrix_tlate &v) 00191 */ 00192 umatrix_const_view_tlate() {}; 00193 00194 #endif 00195 00196 }; 00197 00198 /** \brief A matrix view of double-precision numbers 00199 */ 00200 template<class data_t> class umatrix_base_tlate : 00201 public umatrix_const_view_tlate<data_t> { 00202 00203 public: 00204 00205 /// \name Copy constructors 00206 //@{ 00207 /// Shallow copy constructor - create a new view of the same matrix 00208 umatrix_base_tlate(umatrix_base_tlate &v) { 00209 this->data=v.data; 00210 this->size1=v.size1; 00211 this->size2=v.size2; 00212 this->owner=0; 00213 } 00214 00215 /// Shallow copy constructor - create a new view of the same matrix 00216 umatrix_base_tlate& operator=(umatrix_base_tlate &v) { 00217 this->data=v.data; 00218 this->size1=v.size1; 00219 this->size2=v.size2; 00220 this->owner=0; 00221 00222 return *this; 00223 } 00224 //@} 00225 00226 ~umatrix_base_tlate() {}; 00227 00228 /// \name Get and set methods 00229 //@{ 00230 /** \brief Array-like indexing 00231 */ 00232 data_t *operator[](size_t i) { 00233 #if O2SCL_NO_RANGE_CHECK 00234 #else 00235 if (i>=this->size1) { 00236 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00237 +" in umatrix_base_tlate::operator[]. Size: "+ 00238 itos(this->size1)+ 00239 " (index should be less than size).").c_str(),gsl_eindex); 00240 return this->data; 00241 } 00242 #endif 00243 return this->data+i*this->size2; 00244 } 00245 00246 /** \brief Array-like indexing 00247 */ 00248 const data_t *operator[](size_t i) const { 00249 #if O2SCL_NO_RANGE_CHECK 00250 #else 00251 if (i>=this->size1) { 00252 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00253 +" in umatrix_base_tlate::operator[] const. Size: "+ 00254 itos(this->size1)+ 00255 " (index should be less than size).").c_str(),gsl_eindex); 00256 return this->data; 00257 } 00258 #endif 00259 return this->data+i*this->size2; 00260 } 00261 00262 /** \brief Array-like indexing 00263 */ 00264 data_t &operator()(size_t i, size_t j) { 00265 #if O2SCL_NO_RANGE_CHECK 00266 #else 00267 if (i>=this->size1 || j>=this->size2) { 00268 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00269 ") out of bounds" 00270 +" in umatrix_base_tlate::operator(). Sizes: ("+ 00271 itos(this->size1)+","+itos(this->size2)+ 00272 ") (index should be less than size).").c_str(),gsl_eindex); 00273 return *this->data; 00274 } 00275 #endif 00276 return *(this->data+i*this->size2+j); 00277 } 00278 00279 /** \brief Array-like indexing 00280 */ 00281 const data_t &operator()(size_t i, size_t j) const { 00282 #if O2SCL_NO_RANGE_CHECK 00283 #else 00284 if (i>=this->size1 || j>=this->size2) { 00285 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00286 ") out of bounds" 00287 +" in umatrix_base_tlate::operator() const. Sizes: ("+ 00288 itos(this->size1)+","+itos(this->size2)+ 00289 ") (index should be less than size).").c_str(),gsl_eindex); 00290 return *this->data; 00291 } 00292 #endif 00293 return *(this->data+i*this->size2+j); 00294 } 00295 00296 /** \brief Get pointer (with optional range-checking) */ 00297 data_t *get_ptr(size_t i, size_t j) { 00298 #if O2SCL_NO_RANGE_CHECK 00299 #else 00300 if (i>=this->size1 || j>=this->size2) { 00301 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00302 ") out of bounds" 00303 +" in umatrix_base_tlate::get_ptr(). Sizes: ("+ 00304 itos(this->size1)+","+itos(this->size2)+ 00305 ") (index should be less than size).").c_str(),gsl_eindex); 00306 return this->data; 00307 } 00308 #endif 00309 return this->data+i*this->size2+j; 00310 } 00311 00312 /** \brief Set (with optional range-checking) */ 00313 int set(size_t i, size_t j, data_t val) { 00314 #if O2SCL_NO_RANGE_CHECK 00315 #else 00316 if (i>=this->size1 || j>=this->size2) { 00317 O2SCL_ERR_RET((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00318 ") out of bounds" 00319 +" in umatrix_base_tlate::set(). Sizes: ("+ 00320 itos(this->size1)+","+itos(this->size2)+ 00321 ") (index should be less than size).").c_str(), 00322 gsl_eindex); 00323 } 00324 #endif 00325 *(this->data+i*this->size2+j)=val; 00326 return 0; 00327 } 00328 00329 /** \brief Set all of the value to be the value \c val */ 00330 int set_all(data_t val) { 00331 for(size_t i=0;i<this->size1;i++) { 00332 for(size_t j=0;j<this->size2;j++) { 00333 *(this->data+i*this->size2+j)=val; 00334 } 00335 } 00336 return 0; 00337 } 00338 //@} 00339 00340 /// \name Arithmetic 00341 //@{ 00342 /** \brief operator+= */ 00343 umatrix_base_tlate<data_t> &operator+= 00344 (const umatrix_base_tlate<data_t> &x) { 00345 size_t lsize=x.size1; 00346 if (lsize>this->size1) lsize=this->size1; 00347 size_t lsize2=x.size2; 00348 if (lsize2>this->size2) lsize2=this->size2; 00349 for(size_t i=0;i<lsize;i++) { 00350 for(size_t j=0;j<lsize2;j++) { 00351 (*this)[i][j]+=x[i][j]; 00352 } 00353 } 00354 00355 return *this; 00356 } 00357 00358 /** \brief operator-= */ 00359 umatrix_base_tlate<data_t> &operator-= 00360 (const umatrix_base_tlate<data_t> &x) { 00361 size_t lsize=x.size1; 00362 if (lsize>this->size1) lsize=this->size1; 00363 size_t lsize2=x.size2; 00364 if (lsize2>this->size2) lsize2=this->size2; 00365 for(size_t i=0;i<lsize;i++) { 00366 for(size_t j=0;j<lsize2;j++) { 00367 (*this)[i][j]+=x[i][j]; 00368 } 00369 } 00370 00371 return *this; 00372 } 00373 00374 /** \brief operator+= */ 00375 umatrix_base_tlate<data_t> &operator+=(const data_t &y) { 00376 for(size_t i=0;i<this->size1;i++) { 00377 for(size_t j=0;j<this->size2;j++) { 00378 (*this)[i][j]+=y; 00379 } 00380 } 00381 00382 return *this; 00383 } 00384 00385 /** \brief operator-= */ 00386 umatrix_base_tlate<data_t> &operator-=(const data_t &y) { 00387 for(size_t i=0;i<this->size1;i++) { 00388 for(size_t j=0;j<this->size2;j++) { 00389 (*this)[i][j]-=y; 00390 } 00391 } 00392 00393 return *this; 00394 } 00395 00396 /** \brief operator*= */ 00397 umatrix_base_tlate<data_t> &operator*=(const data_t &y) { 00398 for(size_t i=0;i<this->size1;i++) { 00399 for(size_t j=0;j<this->size2;j++) { 00400 (*this)[i][j]*=y; 00401 } 00402 } 00403 00404 return *this; 00405 } 00406 //@} 00407 00408 #ifndef DOXYGEN_INTERNAL 00409 00410 protected: 00411 00412 /** \brief Empty constructor 00413 */ 00414 umatrix_base_tlate() {}; 00415 00416 #endif 00417 00418 }; 00419 00420 /** \brief A matrix view of double-precision numbers 00421 */ 00422 template<class data_t> class umatrix_view_tlate : 00423 public umatrix_base_tlate<data_t> { 00424 00425 public: 00426 00427 /// \name Copy constructors 00428 //@{ 00429 /// Shallow copy constructor - create a new view of the same matrix 00430 umatrix_view_tlate(const umatrix_view_tlate &v) { 00431 this->data=v.data; 00432 this->size1=v.size1; 00433 this->size2=v.size2; 00434 this->owner=0; 00435 } 00436 00437 /// Shallow copy constructor - create a new view of the same matrix 00438 umatrix_view_tlate& operator=(const umatrix_view_tlate &v) { 00439 this->data=v.data; 00440 this->size1=v.size1; 00441 this->size2=v.size2; 00442 this->owner=0; 00443 00444 return *this; 00445 } 00446 00447 /// Shallow copy constructor - create a new view of the same matrix 00448 umatrix_view_tlate(umatrix_base_tlate<data_t> &v) { 00449 this->data=v.data; 00450 this->size1=v.size1; 00451 this->size2=v.size2; 00452 this->owner=0; 00453 } 00454 00455 /// Shallow copy constructor - create a new view of the same matrix 00456 umatrix_view_tlate& operator=(umatrix_base_tlate<data_t> &v) { 00457 this->data=v.data; 00458 this->size1=v.size1; 00459 this->size2=v.size2; 00460 this->owner=0; 00461 00462 return *this; 00463 } 00464 //@} 00465 00466 ~umatrix_view_tlate() {}; 00467 00468 /// \name Get and set methods 00469 //@{ 00470 /** \brief Array-like indexing 00471 */ 00472 data_t *operator[](size_t i) const { 00473 #if O2SCL_NO_RANGE_CHECK 00474 #else 00475 if (i>=this->size1) { 00476 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00477 +" in umatrix_view_tlate::operator[]. Size: "+ 00478 itos(this->size1)+ 00479 " (index should be less than size).").c_str(),gsl_eindex); 00480 return this->data; 00481 } 00482 #endif 00483 return this->data+i*this->size2; 00484 } 00485 00486 /** \brief Array-like indexing 00487 */ 00488 data_t &operator()(size_t i, size_t j) const { 00489 #if O2SCL_NO_RANGE_CHECK 00490 #else 00491 if (i>=this->size1 || j>=this->size2) { 00492 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00493 ") out of bounds" 00494 +" in umatrix_view_tlate::operator(). Sizes: ("+ 00495 itos(this->size1)+","+itos(this->size2)+ 00496 ") (index should be less than size).").c_str(),gsl_eindex); 00497 return *this->data; 00498 } 00499 #endif 00500 return *(this->data+i*this->size2+j); 00501 } 00502 00503 /** \brief Get pointer (with optional range-checking) */ 00504 data_t *get_ptr(size_t i, size_t j) const { 00505 #if O2SCL_NO_RANGE_CHECK 00506 #else 00507 if (i>=this->size1 || j>=this->size2) { 00508 O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00509 ") out of bounds" 00510 +" in umatrix_view_tlate::get_ptr(). Sizes: ("+ 00511 itos(this->size1)+","+itos(this->size2)+ 00512 ") (index should be less than size).").c_str(),gsl_eindex); 00513 return this->data; 00514 } 00515 #endif 00516 return this->data+i*this->size2+j; 00517 } 00518 00519 /** \brief Set (with optional range-checking) */ 00520 int set(size_t i, size_t j, data_t val) const { 00521 #if O2SCL_NO_RANGE_CHECK 00522 #else 00523 if (i>=this->size1 || j>=this->size2) { 00524 O2SCL_ERR_RET((((std::string)"Indices (")+itos(i)+","+itos(j)+ 00525 ") out of bounds" 00526 +" in umatrix_view_tlate::set(). Sizes: ("+ 00527 itos(this->size1)+","+itos(this->size2)+ 00528 ") (index should be less than size).").c_str(), 00529 gsl_eindex); 00530 } 00531 #endif 00532 *(this->data+i*this->size2+j)=val; 00533 return 0; 00534 } 00535 00536 /** \brief Set all of the value to be the value \c val */ 00537 int set_all(double val) const { 00538 for(size_t i=0;i<this->size1;i++) { 00539 for(size_t j=0;j<this->size2;j++) { 00540 *(this->data+i*this->size2+j)=val; 00541 } 00542 } 00543 return 0; 00544 } 00545 //@} 00546 00547 #ifndef DOXYGEN_INTERNAL 00548 00549 protected: 00550 00551 /** \brief Empty constructor 00552 */ 00553 umatrix_view_tlate() {}; 00554 00555 #endif 00556 00557 }; 00558 00559 /** \brief A matrix of double-precision numbers 00560 */ 00561 template<class data_t> class umatrix_tlate : 00562 public umatrix_base_tlate<data_t> { 00563 public: 00564 00565 /// \name Standard constructor 00566 //@{ 00567 /** \brief Create an umatrix of size \c n with owner as 'true' 00568 */ 00569 umatrix_tlate(size_t r=0, size_t c=0) { 00570 00571 this->data=0; 00572 this->size1=0; 00573 this->size2=0; 00574 00575 // This must be set to 1 even if n=0 so that future 00576 // calls to operator= work properly 00577 this->owner=1; 00578 00579 if (r>0 && c>0) { 00580 this->data=(data_t *)malloc(r*c*sizeof(data_t)); 00581 if (this->data) { 00582 this->size1=r; 00583 this->size2=c; 00584 } else { 00585 O2SCL_ERR("No memory for data in umatrix_tlate constructor", 00586 gsl_enomem); 00587 } 00588 } 00589 } 00590 //@} 00591 00592 /// \name Copy constructors 00593 //@{ 00594 /// Deep copy constructor, allocate new space and make a copy 00595 umatrix_tlate(const umatrix_tlate &v) : umatrix_base_tlate<data_t>() { 00596 size_t n=v.size1; 00597 size_t n2=v.size2; 00598 if (n>0 && n2>0) { 00599 this->data=(data_t *)malloc(n*n2*sizeof(data_t)); 00600 if (this->data) { 00601 this->size1=n; 00602 this->size2=n2; 00603 this->owner=1; 00604 for(size_t i=0;i<n;i++) { 00605 for(size_t j=0;j<n2;j++) { 00606 *(this->data+i*this->size2+j)=v[i][j]; 00607 } 00608 } 00609 } else { 00610 O2SCL_ERR("No memory for data in umatrix_tlate constructor", 00611 gsl_enomem); 00612 } 00613 } else { 00614 this->size1=0; 00615 this->size2=0; 00616 } 00617 } 00618 00619 /// Deep copy constructor, allocate new space and make a copy 00620 umatrix_tlate 00621 (const umatrix_view_tlate<data_t> &v) : 00622 umatrix_base_tlate<data_t>() { 00623 size_t r=v.rows(); 00624 size_t c=v.cols(); 00625 if (r>0 && c>0) { 00626 this->data=(data_t *)malloc(r*c*sizeof(data_t)); 00627 if (this->data) { 00628 this->size1=v.size1; 00629 this->size2=v.size2; 00630 this->owner=1; 00631 for(size_t i=0;i<r;i++) { 00632 for(size_t j=0;i<c;j++) { 00633 *(this->data+i*this->size2+j)=v[i][j]; 00634 } 00635 } 00636 } else { 00637 O2SCL_ERR("No memory for data in umatrix_tlate constructor", 00638 gsl_enomem); 00639 } 00640 } else { 00641 this->size1=0; 00642 this->size2=0; 00643 } 00644 } 00645 00646 /** \brief Deep copy constructor, if owner is true, allocate space and 00647 make a new copy, otherwise, just copy into the view 00648 */ 00649 umatrix_tlate& operator=(const umatrix_tlate &v) { 00650 00651 // Check for self-assignment 00652 if (this==&v) return *this; 00653 00654 size_t sze=v.size1; 00655 size_t sze2=v.size2; 00656 if (this->owner) { 00657 allocate(sze,sze2); 00658 } else { 00659 if (this->size1!=sze || this->size2!=sze2) { 00660 O2SCL_ERR("Sizes don't match in umatrix_tlate::operator=()", 00661 gsl_ebadlen); 00662 return *this; 00663 } 00664 } 00665 for(size_t i=0;i<sze;i++) { 00666 for(size_t j=0;j<sze2;j++) { 00667 *(this->data+i*this->size2+j)=v[i][j]; 00668 } 00669 } 00670 return *this; 00671 } 00672 00673 /** \brief Deep copy constructor, if owner is true, allocate space and 00674 make a new copy, otherwise, just copy into the view 00675 */ 00676 umatrix_tlate& operator= 00677 (const umatrix_view_tlate<data_t> &v) { 00678 00679 // Check for self-assignment 00680 if (this==&v) return *this; 00681 00682 size_t sze=v.rows(); 00683 size_t sze2=v.cols(); 00684 if (this->owner) { 00685 allocate(sze,sze2); 00686 } else { 00687 if (this->size1!=sze || this->size2!=sze2) { 00688 O2SCL_ERR("Sizes don't match in umatrix_tlate::operator=()", 00689 gsl_ebadlen); 00690 return *this; 00691 } 00692 } 00693 for(size_t i=0;i<sze;i++) { 00694 for(size_t j=0;j<sze2;j++) { 00695 *(this->data+i*this->size2+j)=v[i][j]; 00696 } 00697 } 00698 return *this; 00699 } 00700 00701 /** \brief Deep copy from an array of uvectors 00702 */ 00703 umatrix_tlate(size_t n, uvector_view_tlate<data_t> uva[]) { 00704 if (n>0) { 00705 size_t n2=uva[0]; 00706 if (n2>0) { 00707 allocate(n,n2); 00708 for(size_t i=0;i<n;i++) { 00709 for(size_t j=0;j<n2;j++) { 00710 (*this)[i][j]=uva[i][j]; 00711 } 00712 } 00713 } 00714 } 00715 } 00716 00717 /** \brief Deep copy from a C-style 2-d array 00718 */ 00719 umatrix_tlate(size_t n, size_t n2, data_t **csa) { 00720 if (n>0 && n2>0) { 00721 allocate(n,n2); 00722 for(size_t i=0;i<n;i++) { 00723 for(size_t j=0;j<n2;j++) { 00724 (*this)[i][j]=csa[i][j]; 00725 } 00726 } 00727 } 00728 } 00729 00730 //@} 00731 00732 ~umatrix_tlate() { 00733 if (this->size1>0) { 00734 if (this->owner==1) { 00735 std::free(this->data); 00736 this->size1=0; 00737 this->size2=0; 00738 } 00739 } 00740 } 00741 00742 /// \name Memory allocation 00743 //@{ 00744 /** \brief Allocate memory after freeing any memory presently in use 00745 */ 00746 int allocate(size_t nrows, size_t ncols) { 00747 if (this->size1>0 || this->size2>0) free(); 00748 00749 if (nrows>0 && ncols>0) { 00750 this->data=(data_t *)malloc(nrows*ncols*sizeof(data_t)); 00751 if (this->data) { 00752 this->size1=nrows; 00753 this->size2=ncols; 00754 this->owner=1; 00755 } else { 00756 O2SCL_ERR_RET("No memory for data in umatrix_tlate::allocate()", 00757 gsl_enomem); 00758 } 00759 } else { 00760 O2SCL_ERR_RET("Zero size in umatrix::allocate()",gsl_einval); 00761 } 00762 return 0; 00763 } 00764 00765 /** \brief Free the memory 00766 00767 This function will safely do nothing if used without first 00768 allocating memory or if called multiple times in succession. 00769 */ 00770 int free() { 00771 if (this->size1>0) { 00772 if (this->owner==1) { 00773 std::free(this->data); 00774 } 00775 this->size1=0; 00776 this->size2=0; 00777 } 00778 return 0; 00779 } 00780 //@} 00781 00782 /// \name Other methods 00783 //@{ 00784 /** \brief Compute the transpose (even if matrix is not square) 00785 */ 00786 umatrix_tlate<data_t> transpose() { 00787 umatrix_tlate<data_t> result(this->size2,this->size1); 00788 for(size_t i=0;i<this->size1;i++) { 00789 for(size_t j=0;j<this->size2;j++) { 00790 result[j][i]=(*this)[i][j]; 00791 } 00792 } 00793 } 00794 //@} 00795 00796 }; 00797 00798 /** \brief Create a vector from a row of a matrix 00799 */ 00800 template<class data_t> class umatrix_row_tlate : 00801 public uvector_view_tlate<data_t> { 00802 public: 00803 /** \brief Create a vector from row \c i of matrix \c m */ 00804 umatrix_row_tlate(umatrix_base_tlate<data_t> &m, 00805 size_t i) { 00806 this->sz=0; 00807 this->data=0; 00808 this->owner=0; 00809 if (i<m.rows()) { 00810 this->sz=m.cols(); 00811 this->data=m[0]+m.cols()*i; 00812 } 00813 } 00814 }; 00815 00816 /** \brief Create a const vector from a row of a matrix 00817 */ 00818 template<class data_t> class umatrix_const_row_tlate : 00819 public uvector_const_view_tlate<data_t> { 00820 public: 00821 /** \brief Create a vector from row \c i of matrix \c m */ 00822 umatrix_const_row_tlate 00823 (const umatrix_base_tlate<data_t> &m, 00824 size_t i) { 00825 if (i<m.size1) { 00826 this->sz=m.cols(); 00827 this->data=m[0]+m.cols()*i; 00828 this->owner=0; 00829 } 00830 } 00831 }; 00832 00833 /// umatrix typedef 00834 typedef umatrix_tlate<double> umatrix; 00835 /// umatrix_view typedef 00836 typedef umatrix_view_tlate<double> umatrix_view; 00837 /// umatrix_base typedef 00838 typedef umatrix_base_tlate<double> umatrix_base; 00839 /// umatrix_const_view typedef 00840 typedef umatrix_const_view_tlate<double> umatrix_const_view; 00841 /// umatrix_row typedef 00842 typedef umatrix_row_tlate<double> umatrix_row; 00843 /// umatrix_const_row typedef 00844 typedef umatrix_const_row_tlate<double> umatrix_const_row; 00845 00846 /// umatrix_int typedef 00847 typedef umatrix_tlate<int> umatrix_int; 00848 /// umatrix_int_view typedef 00849 typedef umatrix_view_tlate<int> umatrix_int_view; 00850 /// umatrix_int_const_view typedef 00851 typedef umatrix_const_view_tlate<int> umatrix_int_const_view; 00852 /// umatrix_int_base typedef 00853 typedef umatrix_base_tlate<int> umatrix_int_base; 00854 /// umatrix_int_row typedef 00855 typedef umatrix_row_tlate<int> umatrix_int_row; 00856 /// umatrix_int_const_row typedef 00857 typedef umatrix_const_row_tlate<int> umatrix_int_const_row; 00858 00859 /** \brief A operator for simple matrix output 00860 00861 This outputs all of the matrix elements. Each row is output with 00862 an endline character at the end of each row. Positive values are 00863 preceeded by an extra space. A 2x2 example: 00864 \verbatim 00865 -3.751935e-05 -6.785864e-04 00866 -6.785864e-04 1.631984e-02 00867 \endverbatim 00868 00869 The function \c gsl_ieee_double_to_rep() is used to determine 00870 the sign of a number, so that "-0.0" as distinct from "+0.0" 00871 is handled correctly. 00872 00873 \future This assumes that scientific mode is on and showpos 00874 is off. It'd be nice to fix this. 00875 00876 */ 00877 template<class data_t> std::ostream &operator<< 00878 (std::ostream &os, const umatrix_const_view_tlate<data_t> &v) { 00879 size_t i; 00880 gsl_ieee_double_rep r; 00881 for(i=0;i<v.rows()-1;i++) { 00882 for(size_t j=0;j<v.cols();j++) { 00883 gsl_ieee_double_to_rep(&(v[i][j]), &r); 00884 if (r.sign==1) os << v[i][j] << ' '; 00885 else os << ' ' << v[i][j] << ' '; 00886 } 00887 os << '\n'; 00888 } 00889 i=v.rows()-1; 00890 if (i>0) { 00891 for(size_t j=0;j<v.cols();j++) { 00892 gsl_ieee_double_to_rep(&(v[i][j]), &r); 00893 if (r.sign==1) os << v[i][j] << ' '; 00894 else os << ' ' << v[i][j] << ' '; 00895 } 00896 } 00897 return os; 00898 } 00899 00900 /** \brief A simple class to provide an \c allocate() function 00901 for \ref umatrix 00902 */ 00903 class umatrix_alloc { 00904 public: 00905 /// Allocate \c v for \c i elements 00906 void allocate(umatrix &o, int i, int j) { o.allocate(i,j); } 00907 /// Free memory 00908 void free(umatrix &o) { o.free(); } 00909 }; 00910 00911 /** \brief A matrix where the memory allocation is performed in 00912 the constructor 00913 */ 00914 #ifdef DOXYGENP 00915 template<size_t N, size_t M> class ufmatrix : 00916 public umatrix_tlate<data_t> 00917 #else 00918 template<size_t N, size_t M> class ufmatrix : 00919 public umatrix_tlate<double> 00920 #endif 00921 { 00922 public: 00923 ufmatrix() : umatrix_tlate<double>(N,M) { 00924 } 00925 }; 00926 00927 00928 #ifndef DOXYGENP 00929 } 00930 #endif 00931 00932 #endif 00933 00934 00935
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).