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