00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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_UVECTOR_CX_TLATE_H 00024 #define O2SCL_UVECTOR_CX_TLATE_H 00025 00026 /** \file uvector_cx_tlate.h 00027 \brief File for definitions of complex unit-stride vectors 00028 */ 00029 00030 #include <iostream> 00031 #include <cstdlib> 00032 #include <string> 00033 #include <fstream> 00034 #include <sstream> 00035 #include <vector> 00036 #include <o2scl/err_hnd.h> 00037 #include <gsl/gsl_vector.h> 00038 00039 #ifndef DOXYGENP 00040 namespace o2scl { 00041 #endif 00042 00043 /** 00044 \brief A vector view of complex numbers with unit stride 00045 00046 \experiment 00047 00048 \todo Write lookup() method, and possible an erase() method. 00049 */ 00050 template<class data_t, class complex_t> class uvector_cx_view_tlate { 00051 00052 #ifndef DOXYGEN_INTERNAL 00053 00054 protected: 00055 00056 /// The data 00057 data_t *data; 00058 /// The vector sz 00059 size_t sz; 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 /// Copy constructor - create a new view of the same vector 00070 uvector_cx_view_tlate(const uvector_cx_view_tlate &v) { 00071 data=v.data; 00072 sz=v.sz; 00073 owner=0; 00074 } 00075 00076 /// Copy constructor - create a new view of the same vector 00077 uvector_cx_view_tlate& operator=(const uvector_cx_view_tlate &v) { 00078 data=v.data; 00079 sz=v.sz; 00080 owner=0; 00081 00082 return *this; 00083 } 00084 //@} 00085 00086 ~uvector_cx_view_tlate() {}; 00087 00088 /// \name Get and set methods 00089 //@{ 00090 /** 00091 \brief Array-like indexing 00092 */ 00093 complex_t &operator[](size_t i) { 00094 #if O2SCL_NO_RANGE_CHECK 00095 #else 00096 if (i>=sz) { 00097 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00098 +" in uvector_cx_view_tlate::operator[]. Size: "+ 00099 itos(sz)+ 00100 " (index should be less than size).").c_str(),gsl_index); 00101 return *(complex_t *)(data); 00102 } 00103 #endif 00104 return *(complex_t *)(&data[i*2]); 00105 } 00106 00107 /** 00108 \brief Array-like indexing 00109 */ 00110 const complex_t &operator[](size_t i) const { 00111 #if O2SCL_NO_RANGE_CHECK 00112 #else 00113 if (i>=sz) { 00114 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00115 +" in uvector_cx_view_tlate::operator[] const. Size: "+ 00116 itos(sz)+ 00117 " (index should be less than size).").c_str(),gsl_index); 00118 return *(const complex_t *)(data); 00119 } 00120 #endif 00121 return *(const complex_t *)(&data[i*2]); 00122 } 00123 00124 /** 00125 \brief Array-like indexing 00126 */ 00127 complex_t &operator()(size_t i) { 00128 #if O2SCL_NO_RANGE_CHECK 00129 #else 00130 if (i>=sz) { 00131 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00132 +" in uvector_cx_view_tlate::operator(). Size: "+ 00133 itos(sz)+ 00134 " (index should be less than size).").c_str(),gsl_index); 00135 return *(complex_t *)(data); 00136 } 00137 #endif 00138 return *(complex_t *)(&data[i*2]); 00139 } 00140 00141 /** 00142 \brief Array-like indexing 00143 */ 00144 const complex_t &operator()(size_t i) const { 00145 #if O2SCL_NO_RANGE_CHECK 00146 #else 00147 if (i>=sz) { 00148 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00149 +" in uvector_cx_view_tlate::operator() const. Size: "+ 00150 itos(sz)+ 00151 " (index should be less than size).").c_str(),gsl_index); 00152 return *(const complex_t *)(data); 00153 } 00154 #endif 00155 return *(const complex_t *)(&data[i*2]); 00156 } 00157 00158 /** \brief Get (with optional range-checking) */ 00159 complex_t get(size_t i) const { 00160 #if O2SCL_NO_RANGE_CHECK 00161 #else 00162 if (i>=sz) { 00163 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00164 +" in uvector_cx_view_tlate::get(). Size: "+ 00165 itos(sz)+ 00166 " (index should be less than size).").c_str(),gsl_index); 00167 return *(complex_t *)(data); 00168 } 00169 #endif 00170 return *(complex_t *)(&data[i*2]); 00171 } 00172 00173 /** \brief Get pointer (with optional range-checking) */ 00174 complex_t *get_ptr(size_t i) { 00175 #if O2SCL_NO_RANGE_CHECK 00176 #else 00177 if (i>=sz) { 00178 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00179 +" in uvector_cx_view_tlate::get_ptr(). Size: "+ 00180 itos(sz)+ 00181 " (index should be less than size).").c_str(),gsl_index); 00182 return (complex_t *)(data); 00183 } 00184 #endif 00185 return (complex_t *)(&data[i*2]); 00186 } 00187 00188 /** \brief Get pointer (with optional range-checking) */ 00189 const complex_t *get_const_ptr(size_t i) const { 00190 #if O2SCL_NO_RANGE_CHECK 00191 #else 00192 if (i>=sz) { 00193 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00194 +" in uvector_cx_view_tlate::get_const_ptr(). Size: "+ 00195 itos(sz)+ 00196 " (index should be less than size).").c_str(),gsl_index); 00197 return (const complex_t *)(data); 00198 } 00199 #endif 00200 return (const complex_t *)(&data[i*2]); 00201 } 00202 00203 /** \brief Set (with optional range-checking) */ 00204 int set(size_t i, const complex_t &val) { 00205 #if O2SCL_NO_RANGE_CHECK 00206 #else 00207 if (i>=sz) { 00208 set_err_ret((((std::string)"Array index ")+itos(i)+" out of bounds" 00209 +" in uvector_cx_view_tlate::set(). Size: "+ 00210 itos(sz)+ 00211 " (index should be less than size).").c_str(),gsl_index); 00212 } 00213 #endif 00214 data[2*i]=val.dat[0]; 00215 data[2*i+1]=val.dat[1]; 00216 return 0; 00217 } 00218 00219 /** \brief Set all of the value to be the value \c val */ 00220 int set_all(const complex_t &val) { 00221 double re=val.dat[0]; 00222 double im=val.dat[1]; 00223 for(size_t i=0;i<sz;i++) { 00224 data[2*i]=re; 00225 data[2*i+1]=im; 00226 } 00227 return 0; 00228 } 00229 00230 /** 00231 \brief Method to return vector size 00232 00233 If no memory has been allocated, this will quietly 00234 return zero. 00235 */ 00236 size_t size() const { 00237 return sz; 00238 } 00239 //@} 00240 00241 /// \name Other methods 00242 //@{ 00243 00244 /** \brief Swap vectors */ 00245 int swap(uvector_cx_view_tlate<data_t,complex_t> &x) { 00246 size_t t1; 00247 double *t3; 00248 int t5; 00249 00250 t1=sz; 00251 t3=data; 00252 t5=owner; 00253 00254 sz=x.sz; 00255 data=x.data; 00256 owner=x.owner; 00257 00258 x.sz=t1; 00259 x.data=t3; 00260 x.owner=t5; 00261 00262 return 0; 00263 } 00264 00265 /// Return true if this object owns the data it refers to 00266 bool is_owner() const { 00267 if (owner==1) return true; 00268 return false; 00269 } 00270 00271 /// \name Arithmetic 00272 //@{ 00273 /** \brief operator+= */ 00274 uvector_cx_view_tlate<data_t,complex_t> &operator+= 00275 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00276 size_t lsz=x.sz; 00277 if (lsz>sz) lsz=sz; 00278 for(size_t i=0;i<lsz;i++) (*this)[i]+=x[i]; 00279 00280 return *this; 00281 } 00282 00283 /** \brief operator-= */ 00284 uvector_cx_view_tlate<data_t,complex_t> &operator-= 00285 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00286 size_t lsz=x.sz; 00287 if (lsz>sz) lsz=sz; 00288 for(size_t i=0;i<lsz;i++) (*this)[i]-=x[i]; 00289 00290 return *this; 00291 } 00292 00293 /** \brief operator+= */ 00294 uvector_cx_view_tlate<data_t,complex_t> &operator+=(const data_t &y) { 00295 for(size_t i=0;i<sz;i++) (*this)[i]+=y; 00296 00297 return *this; 00298 } 00299 00300 /** \brief operator-= */ 00301 uvector_cx_view_tlate<data_t,complex_t> &operator-=(const data_t &y) { 00302 for(size_t i=0;i<sz;i++) (*this)[i]-=y; 00303 00304 return *this; 00305 } 00306 00307 /** \brief operator*= */ 00308 uvector_cx_view_tlate<data_t,complex_t> &operator*=(const data_t &y) { 00309 for(size_t i=0;i<sz;i++) (*this)[i]*=y; 00310 00311 return *this; 00312 } 00313 00314 /** \brief Norm */ 00315 data_t norm() const { 00316 data_t result=0; 00317 for(size_t i=0;i<sz;i++) { 00318 result+=(*this)[i]*(*this)[i]; 00319 } 00320 return sqrt(result); 00321 } 00322 //@} 00323 00324 #ifndef DOXYGEN_INTERNAL 00325 00326 protected: 00327 00328 /** \brief Empty constructor provided for use by 00329 uvector_cx_tlate(const uvector_cx_tlate &v) 00330 */ 00331 uvector_cx_view_tlate() {}; 00332 00333 #endif 00334 00335 }; 00336 00337 /** 00338 \brief A vector of double-precision numbers with unit stride 00339 00340 There are several global binary operators associated with 00341 objects of type \ref uvector_cx_tlate. The are documented in the 00342 "Functions" section of \ref uvector_cx_tlate.h. 00343 */ 00344 template<class data_t, class complex_t> class uvector_cx_tlate : 00345 public uvector_cx_view_tlate<data_t,complex_t> { 00346 public: 00347 00348 /// \name Standard constructor 00349 //@{ 00350 /** \brief Create an uvector_cx of size \c n with owner as 'true' */ 00351 uvector_cx_tlate(size_t n=0) { 00352 // This must be set to 1 even if n=0 so that future 00353 // calls to operator= work properly 00354 this->owner=1; 00355 if (n>0) { 00356 this->data=(data_t *)malloc(2*n*sizeof(data_t)); 00357 if (this->data) { 00358 this->sz=n; 00359 } else { 00360 set_err("No memory for data in uvector_cx_tlate constructor", 00361 gsl_enomem); 00362 } 00363 } else { 00364 this->sz=0; 00365 } 00366 } 00367 //@} 00368 00369 /// \name Copy constructors 00370 //@{ 00371 /// Deep copy constructor - allocate new space and make a copy 00372 uvector_cx_tlate(const uvector_cx_tlate &v) : 00373 uvector_cx_view_tlate<data_t,complex_t>() { 00374 size_t n=v.sz; 00375 if (n>0) { 00376 this->data=(data_t *)malloc(2*n*sizeof(data_t)); 00377 if (this->data) { 00378 this->sz=n; 00379 this->owner=1; 00380 for(size_t i=0;i<n;i++) { 00381 this->data[2*i]=v[i].dat[0]; 00382 this->data[2*i+1]=v[i].dat[1]; 00383 } 00384 } else { 00385 set_err("No memory for data in uvector_cx_tlate constructor", 00386 gsl_enomem); 00387 } 00388 } else { 00389 this->sz=0; 00390 } 00391 } 00392 00393 /// Deep copy constructor - allocate new space and make a copy 00394 uvector_cx_tlate(const uvector_cx_view_tlate<data_t,complex_t> &v) : 00395 uvector_cx_view_tlate<data_t,complex_t>() { 00396 size_t n=v.sz; 00397 if (n>0) { 00398 this->data=(data_t *)malloc(2*n*sizeof(data_t)); 00399 if (this->data) { 00400 this->sz=n; 00401 this->owner=1; 00402 for(size_t i=0;i<n;i++) { 00403 this->data[2*i]=v[i].dat[0]; 00404 this->data[2*i+1]=v[i].dat[1]; 00405 } 00406 } else { 00407 set_err("No memory for data in uvector_cx_tlate constructor", 00408 gsl_enomem); 00409 } 00410 } else { 00411 this->sz=0; 00412 } 00413 } 00414 00415 /** \brief Deep copy constructor - if owner is true, allocate space and 00416 make a new copy, otherwise, just copy into the view 00417 */ 00418 uvector_cx_tlate& operator=(const uvector_cx_tlate &v) { 00419 size_t sz2=v.sz; 00420 if (this->owner) { 00421 allocate(sz2); 00422 } else { 00423 if (this->sz!=sz2) { 00424 set_err("Sizes don't match in uvector_cx_tlate::operator=()", 00425 gsl_ebadlen); 00426 return *this; 00427 } 00428 } 00429 for(size_t i=0;i<sz2;i++) { 00430 this->data[2*i]=v[i].dat[0]; 00431 this->data[2*i+1]=v[i].dat[1]; 00432 } 00433 return *this; 00434 } 00435 00436 /** \brief Deep copy constructor - if owner is true, allocate space and 00437 make a new copy, otherwise, just copy into the view 00438 */ 00439 uvector_cx_tlate& operator= 00440 (const uvector_cx_view_tlate<data_t,complex_t> &v) { 00441 size_t sz2=v.size(); 00442 if (this->owner) { 00443 allocate(sz2); 00444 } else { 00445 if (this->sz!=sz2) { 00446 set_err("Sizes don't match in uvector_cx_tlate::operator=()", 00447 gsl_ebadlen); 00448 return *this; 00449 } 00450 } 00451 for(size_t i=0;i<sz2;i++) { 00452 this->data[2*i]=v[i].dat[0]; 00453 this->data[2*i+1]=v[i].dat[1]; 00454 } 00455 return *this; 00456 } 00457 //@} 00458 00459 ~uvector_cx_tlate() { 00460 if (this->sz>0) { 00461 if (this->owner==1) { 00462 std::free(this->data); 00463 } 00464 this->sz=0; 00465 } 00466 } 00467 00468 /// \name Memory allocation 00469 //@{ 00470 /** 00471 \brief Allocate memory for size \c n after freeing any memory 00472 presently in use 00473 */ 00474 int allocate(size_t nsize) { 00475 if (this->sz>0) free(); 00476 00477 if (nsize>0) { 00478 this->data=(data_t *)malloc(2*nsize*sizeof(data_t)); 00479 if (this->data) { 00480 this->sz=nsize; 00481 this->owner=1; 00482 } else { 00483 set_err_ret("No memory for data in uvector_cx_tlate::allocate()", 00484 gsl_enomem); 00485 } 00486 } else { 00487 set_err_ret("Zero size in uvector_cx::allocate()",gsl_einval); 00488 } 00489 return 0; 00490 } 00491 00492 /** 00493 \brief Free the memory 00494 00495 This function will safely do nothing if used without first 00496 allocating memory or if called multiple times in succession. 00497 */ 00498 int free() { 00499 if (this->sz>0) { 00500 if (this->owner==1) { 00501 std::free(this->data); 00502 } 00503 this->sz=0; 00504 } 00505 return 0; 00506 } 00507 //@} 00508 00509 }; 00510 00511 /** \brief Create a vector from an array 00512 */ 00513 template<class data_t, class complex_t> class uvector_cx_array_tlate : 00514 public uvector_cx_view_tlate<data_t,complex_t> { 00515 public: 00516 /** \brief Create a vector from \c dat with size \c n */ 00517 uvector_cx_array_tlate(size_t n, data_t *dat) { 00518 if (n>0) { 00519 this->data=dat; 00520 this->sz=n; 00521 this->owner=0; 00522 } 00523 } 00524 }; 00525 00526 /** \brief Create a vector from a subvector of another 00527 */ 00528 template<class data_t, class complex_t> class uvector_cx_subvector_tlate : 00529 public uvector_cx_view_tlate<data_t,complex_t> { 00530 public: 00531 /** \brief Create a vector from \c orig */ 00532 uvector_cx_subvector_tlate(uvector_cx_view_tlate<data_t,complex_t> &orig, 00533 size_t offset, size_t n) { 00534 if (offset+n-1<orig.size) { 00535 this->data=orig.data+offset; 00536 this->sz=n; 00537 this->owner=0; 00538 } else { 00539 this->sz=0; 00540 set_err("Subvector failed in uvector_cx_sub_view().",1); 00541 } 00542 } 00543 }; 00544 00545 /** \brief Create a vector from an array 00546 */ 00547 template<class data_t, class complex_t> class uvector_cx_const_array_tlate : 00548 public uvector_cx_view_tlate<data_t,complex_t> { 00549 public: 00550 /** \brief Create a vector from \c dat with size \c n */ 00551 uvector_cx_const_array_tlate(size_t n, const data_t *dat) { 00552 if (n>0) { 00553 // We have to do an explicit cast here, but we prevent the 00554 // user from changing the data. 00555 this->data=(data_t *)dat; 00556 this->sz=n; 00557 this->owner=0; 00558 } 00559 } 00560 00561 ~uvector_cx_const_array_tlate() {}; 00562 00563 #ifndef DOXYGEN_INTERNAL 00564 00565 protected: 00566 00567 /** \name These are inaccessible to ensure the vector is \c const. 00568 */ 00569 //@{ 00570 data_t &operator[](size_t i) { return this->data[0]; } 00571 data_t &operator()(size_t i) { return this->data[0]; } 00572 data_t *get_ptr(size_t i) { return NULL; } 00573 int set(size_t i, data_t val) { return 0; } 00574 int swap(uvector_cx_view_tlate<data_t,complex_t> &x) { 00575 return 0; 00576 } 00577 int set_all(double val) { return 0; } 00578 uvector_cx_view_tlate<data_t,complex_t> &operator+= 00579 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00580 return *this; 00581 } 00582 uvector_cx_view_tlate<data_t,complex_t> &operator-= 00583 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00584 return *this; 00585 } 00586 uvector_cx_view_tlate<data_t,complex_t> &operator*=(const data_t &y) { 00587 return *this; 00588 } 00589 //@} 00590 00591 #endif 00592 00593 }; 00594 00595 /** \brief Create a vector from a subvector of another 00596 */ 00597 template<class data_t, class complex_t> 00598 class uvector_cx_const_subvector_tlate : 00599 public uvector_cx_view_tlate<data_t,complex_t> { 00600 public: 00601 /** \brief Create a vector from \c orig 00602 */ 00603 uvector_cx_const_subvector_tlate 00604 (const uvector_cx_view_tlate<data_t,complex_t> &orig, 00605 size_t offset, size_t n) { 00606 if (offset+n-1<orig.sz) { 00607 this->data=orig.data+offset; 00608 this->sz=n; 00609 this->owner=0; 00610 } else { 00611 this->sz=0; 00612 set_err("Subvector failed in uvector_cx_subvector().",1); 00613 } 00614 } 00615 00616 #ifndef DOXYGENP 00617 00618 protected: 00619 00620 /** \name Ensure \c const by hiding non-const members 00621 */ 00622 //@{ 00623 data_t &operator[](size_t i) { return this->data[0]; } 00624 data_t &operator()(size_t i) { return this->data[0]; } 00625 data_t *get_ptr(size_t i) { return NULL; } 00626 int set(size_t i, data_t val) { return 0; } 00627 int swap(uvector_cx_view_tlate<data_t,complex_t> &x) { 00628 return 0; 00629 } 00630 int set_all(double val) { return 0; } 00631 uvector_cx_view_tlate<data_t,complex_t> &operator+= 00632 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00633 return *this; 00634 } 00635 uvector_cx_view_tlate<data_t,complex_t> &operator-= 00636 (const uvector_cx_view_tlate<data_t,complex_t> &x) { 00637 return *this; 00638 } 00639 uvector_cx_view_tlate<data_t,complex_t> &operator*=(const data_t &y) { 00640 return *this; 00641 } 00642 //@} 00643 00644 #endif 00645 00646 }; 00647 00648 /// uvector_cx typedef 00649 typedef uvector_cx_tlate<double,gsl_complex> uvector_cx; 00650 /// uvector_cx_view typedef 00651 typedef uvector_cx_view_tlate<double,gsl_complex> uvector_cx_view; 00652 /// uvector_cx_array typedef 00653 typedef uvector_cx_array_tlate<double,gsl_complex> uvector_cx_array; 00654 /// uvector_cx_subvector typedef 00655 typedef uvector_cx_subvector_tlate<double,gsl_complex> uvector_cx_subvector; 00656 /// uvector_cx_const_array typedef 00657 typedef uvector_cx_const_array_tlate<double,gsl_complex> 00658 uvector_cx_const_array; 00659 /// uvector_cx_const_subvector typedef 00660 typedef uvector_cx_const_subvector_tlate<double,gsl_complex> 00661 uvector_cx_const_subvector; 00662 00663 /** 00664 \brief A operator for naive vector output 00665 00666 This outputs all of the vector elements. All of these are 00667 separated by one space character, though no trailing space or \c 00668 endl is sent to the output. 00669 */ 00670 template<class data_t, class complex_t> 00671 std::ostream &operator<< 00672 (std::ostream &os, 00673 const uvector_cx_view_tlate<data_t,complex_t> &v) { 00674 if (v.size()>0) { 00675 for(size_t i=0;i<v.size()-1;i++) { 00676 os << v[i] << ' '; 00677 } 00678 os << v[v.size()-1]; 00679 } else { 00680 os << "<empty>"; 00681 } 00682 return os; 00683 } 00684 00685 #ifndef DOXYGENP 00686 } 00687 #endif 00688 00689 #endif 00690
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