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