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