![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_OVECTOR_CX_TLATE_H 00024 #define O2SCL_OVECTOR_CX_TLATE_H 00025 00026 /** \file ovector_cx_tlate.h 00027 \brief File for definitions of complex vectors 00028 */ 00029 00030 #include <iostream> 00031 #include <cstdlib> 00032 #include <string> 00033 #include <fstream> 00034 #include <sstream> 00035 #include <vector> 00036 #include <complex> 00037 #include <o2scl/err_hnd.h> 00038 #include <o2scl/ovector_tlate.h> 00039 #include <gsl/gsl_vector.h> 00040 #include <gsl/gsl_complex.h> 00041 00042 //#include <o2scl/cx_arith.h> 00043 00044 #ifndef DOXYGENP 00045 namespace o2scl { 00046 #endif 00047 00048 /** \brief A vector view of double-precision numbers 00049 */ 00050 template<class data_t, class vparent_t, class block_t, class complex_t> 00051 class ovector_cx_view_tlate : 00052 public vparent_t { 00053 00054 protected: 00055 00056 public: 00057 00058 /// \name Copy constructors 00059 //@{ 00060 /// Shallow copy constructor - create a new view of the same vector 00061 ovector_cx_view_tlate(const ovector_cx_view_tlate &v) { 00062 vparent_t::block=0; 00063 vparent_t::data=v.data; 00064 vparent_t::size=v.size; 00065 vparent_t::stride=v.stride; 00066 vparent_t::owner=0; 00067 } 00068 00069 /// Shallow copy constructor - create a new view of the same vector 00070 ovector_cx_view_tlate& operator=(const ovector_cx_view_tlate &v) { 00071 vparent_t::block=0; 00072 vparent_t::data=v.data; 00073 vparent_t::size=v.size; 00074 vparent_t::stride=v.stride; 00075 vparent_t::owner=0; 00076 00077 return *this; 00078 } 00079 //@} 00080 00081 ~ovector_cx_view_tlate() {}; 00082 00083 /// \name Get and set methods 00084 //@{ 00085 /** \brief Array-like indexing 00086 */ 00087 complex_t &operator[](size_t i) { 00088 #if O2SCL_NO_RANGE_CHECK 00089 #else 00090 if (i>=vparent_t::size) { 00091 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00092 +" in ovector_cx_view_tlate::operator[]. Size: "+ 00093 itos(vparent_t::size)+ 00094 " (index should be less than size).").c_str(),gsl_eindex); 00095 return *(complex_t *)vparent_t::data; 00096 } 00097 #endif 00098 return *(complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00099 } 00100 00101 /** \brief Array-like indexing 00102 */ 00103 const complex_t &operator[](size_t i) const { 00104 #if O2SCL_NO_RANGE_CHECK 00105 #else 00106 if (i>=vparent_t::size) { 00107 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00108 +" in ovector_cx_view_tlate::operator[] const. Size: "+ 00109 itos(vparent_t::size)+ 00110 " (index should be less than size).").c_str(),gsl_eindex); 00111 return *(complex_t *)vparent_t::data; 00112 } 00113 #endif 00114 return *(complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00115 } 00116 00117 /** \brief Array-like indexing 00118 */ 00119 complex_t &operator()(size_t i) { 00120 #if O2SCL_NO_RANGE_CHECK 00121 #else 00122 if (i>=vparent_t::size) { 00123 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00124 +" in ovector_cx_view_tlate::operator(). Size: "+ 00125 itos(vparent_t::size)+ 00126 " (index should be less than size).").c_str(),gsl_eindex); 00127 return *(complex_t *)vparent_t::data; 00128 } 00129 #endif 00130 return *(complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00131 } 00132 00133 /** \brief Array-like indexing 00134 */ 00135 const complex_t &operator()(size_t i) const { 00136 #if O2SCL_NO_RANGE_CHECK 00137 #else 00138 if (i>=vparent_t::size) { 00139 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00140 +" in ovector_cx_view_tlate::operator() const. Size: "+ 00141 itos(vparent_t::size)+ 00142 " (index should be less than size).").c_str(),gsl_eindex); 00143 return *(complex_t *)vparent_t::data; 00144 } 00145 #endif 00146 return *(complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00147 } 00148 00149 /** \brief Get (with optional range-checking) */ 00150 complex_t get(size_t i) const { 00151 #if O2SCL_NO_RANGE_CHECK 00152 #else 00153 if (i>=vparent_t::size) { 00154 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00155 +" in ovector_cx_view_tlate::get(). Size: "+ 00156 itos(vparent_t::size)+ 00157 " (index should be less than size).").c_str(),gsl_eindex); 00158 return *(complex_t *)vparent_t::data; 00159 } 00160 #endif 00161 return *(complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00162 } 00163 00164 /** \brief Get real part (with optional range-checking) */ 00165 data_t real(size_t i) const { 00166 #if O2SCL_NO_RANGE_CHECK 00167 #else 00168 if (i>=vparent_t::size) { 00169 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00170 +" in ovector_cx_view_tlate::real(). Size: "+ 00171 itos(vparent_t::size)+ 00172 " (index should be less than size).").c_str(),gsl_eindex); 00173 return *(data_t *)vparent_t::data; 00174 } 00175 #endif 00176 return *(data_t *)(vparent_t::data+i*vparent_t::stride*2); 00177 } 00178 00179 /** \brief Get imaginary part (with optional range-checking) */ 00180 data_t imag(size_t i) const { 00181 #if O2SCL_NO_RANGE_CHECK 00182 #else 00183 if (i>=vparent_t::size) { 00184 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00185 +" in ovector_cx_view_tlate::imag(). Size: "+ 00186 itos(vparent_t::size)+ 00187 " (index should be less than size).").c_str(),gsl_eindex); 00188 return *(data_t *)vparent_t::data; 00189 } 00190 #endif 00191 return *(data_t *)(vparent_t::data+i*vparent_t::stride*2+1); 00192 } 00193 00194 /** \brief Get STL-like complex number (with optional range-checking) */ 00195 std::complex<data_t> get_stl(size_t i) const { 00196 #if O2SCL_NO_RANGE_CHECK 00197 #else 00198 if (i>=vparent_t::size) { 00199 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00200 +" in ovector_cx_view_tlate::get_stl(). Size: "+ 00201 itos(vparent_t::size)+ 00202 " (index should be less than size).").c_str(),gsl_eindex); 00203 std::complex<data_t> zero(0,0); 00204 return zero; 00205 } 00206 #endif 00207 return *(std::complex<data_t> *)(vparent_t::data+i*vparent_t::stride*2); 00208 } 00209 00210 /** \brief Get pointer (with optional range-checking) */ 00211 complex_t *get_ptr(size_t i) { 00212 #if O2SCL_NO_RANGE_CHECK 00213 #else 00214 if (i>=vparent_t::size) { 00215 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00216 +" in ovector_cx_view_tlate::get_ptr(). Size: "+ 00217 itos(vparent_t::size)+ 00218 " (index should be less than size).").c_str(),gsl_eindex); 00219 return (complex_t *)vparent_t::data; 00220 } 00221 #endif 00222 return (complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00223 } 00224 00225 /** \brief Get pointer (with optional range-checking) */ 00226 const complex_t *get_const_ptr(size_t i) const { 00227 #if O2SCL_NO_RANGE_CHECK 00228 #else 00229 if (i>=vparent_t::size) { 00230 O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds" 00231 +" in ovector_cx_view_tlate::get_const_ptr(). Size: "+ 00232 itos(vparent_t::size)+ 00233 " (index should be less than size).").c_str(),gsl_eindex); 00234 return (complex_t *)vparent_t::data; 00235 } 00236 #endif 00237 return (const complex_t *)(vparent_t::data+i*vparent_t::stride*2); 00238 } 00239 00240 /** \brief Set (with optional range-checking) */ 00241 int set(size_t i, const complex_t &val) { 00242 #if O2SCL_NO_RANGE_CHECK 00243 #else 00244 if (i>=vparent_t::size) { 00245 O2SCL_ERR_RET((((std::string)"Array index ")+itos(i)+" out of bounds" 00246 +" in ovector_cx_view_tlate::set(). Size: "+ 00247 itos(vparent_t::size)+ 00248 " (index should be less than size).").c_str(),gsl_eindex); 00249 } 00250 #endif 00251 vparent_t::data[i*vparent_t::stride*2]=GSL_REAL(val); 00252 vparent_t::data[i*vparent_t::stride*2+1]=GSL_IMAG(val); 00253 return 0; 00254 } 00255 00256 /** \brief Set (with optional range-checking) */ 00257 int set_stl(size_t i, const std::complex<data_t> &d) { 00258 #if O2SCL_NO_RANGE_CHECK 00259 #else 00260 if (i>=vparent_t::size) { 00261 O2SCL_ERR_RET((((std::string)"Array index ")+itos(i)+" out of bounds" 00262 +" in ovector_cx_view_tlate::set_stl(). Size: "+ 00263 itos(vparent_t::size)+ 00264 " (index should be less than size).").c_str(),gsl_eindex); 00265 } 00266 #endif 00267 vparent_t::data[i*vparent_t::stride*2]=d.real(); 00268 vparent_t::data[i*vparent_t::stride*2+1]=d.imag(); 00269 return 0; 00270 } 00271 00272 /** \brief Set (with optional range-checking) */ 00273 int set(size_t i, data_t vr, data_t vi) { 00274 #if O2SCL_NO_RANGE_CHECK 00275 #else 00276 if (i>=vparent_t::size) { 00277 O2SCL_ERR_RET((((std::string)"Array index ")+itos(i)+" out of bounds" 00278 +" in ovector_cx_view_tlate::set(). Size: "+ 00279 itos(vparent_t::size)+ 00280 " (index should be less than size).").c_str(),gsl_eindex); 00281 } 00282 #endif 00283 vparent_t::data[i*vparent_t::stride*2]=vr; 00284 vparent_t::data[i*vparent_t::stride*2+1]=vi; 00285 return 0; 00286 } 00287 00288 /** \brief Set all of the value to be the value \c val */ 00289 int set_all(const complex_t &g) { 00290 for(size_t i=0;i<vparent_t::size;i++) { 00291 data_t gr=GSL_REAL(g), gi=GSL_IMAG(g); 00292 vparent_t::data[i*vparent_t::stride]=gr; 00293 vparent_t::data[i*vparent_t::stride+1]=gi; 00294 } 00295 return 0; 00296 } 00297 00298 /** \brief Method to return vector size 00299 00300 If no memory has been allocated, this will quietly 00301 return zero. 00302 */ 00303 size_t size() const { 00304 return vparent_t::size; 00305 } 00306 00307 /** \brief Method to return vector stride 00308 00309 If no memory has been allocated, this will quietly 00310 return zero. 00311 */ 00312 size_t stride() const { 00313 return vparent_t::stride; 00314 } 00315 //@} 00316 00317 /// \name Other methods 00318 //@{ 00319 /// Return true if this object owns the data it refers to 00320 bool is_owner() const { 00321 if (vparent_t::owner==1) return true; 00322 return false; 00323 } 00324 //@} 00325 00326 /// \name Arithmetic 00327 //@{ 00328 /** \brief operator+= */ 00329 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00330 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00331 size_t lsize=x.size; 00332 if (lsize>size) lsize=size; 00333 for(size_t i=0;i<lsize;i++) { 00334 vparent_t::data[i*vparent_t::stride*2]+=x.data[i*x.stride*2]; 00335 vparent_t::data[i*vparent_t::stride*2+1]+=x.data[i*x.stride*2+1]; 00336 } 00337 00338 return *this; 00339 } 00340 00341 /** \brief operator-= */ 00342 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00343 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00344 size_t lsize=x.size; 00345 if (lsize>size) lsize=size; 00346 for(size_t i=0;i<lsize;i++) { 00347 vparent_t::data[i*vparent_t::stride*2]-=x.data[i*x.stride*2]; 00348 vparent_t::data[i*vparent_t::stride*2+1]-=x.data[i*x.stride*2+1]; 00349 } 00350 00351 return *this; 00352 } 00353 00354 /** \brief operator+= */ 00355 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00356 (const complex_t &x) { 00357 data_t re=*(data_t *)x; 00358 data_t im=*(((data_t *)x)+1); 00359 for(size_t i=0;i<size;i++) { 00360 vparent_t::data[i*vparent_t::stride*2]+=re; 00361 vparent_t::data[i*vparent_t::stride*2+1]+=im; 00362 } 00363 00364 return *this; 00365 } 00366 00367 /** \brief operator-= */ 00368 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00369 (const complex_t &x) { 00370 data_t re=*(data_t *)x; 00371 data_t im=*(((data_t *)x)+1); 00372 for(size_t i=0;i<size;i++) { 00373 vparent_t::data[i*vparent_t::stride*2]-=re; 00374 vparent_t::data[i*vparent_t::stride*2+1]-=im; 00375 } 00376 00377 return *this; 00378 } 00379 00380 /** \brief operator*= */ 00381 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00382 (const complex_t &x) { 00383 data_t re=*(data_t *)x; 00384 data_t im=*(((data_t *)x)+1); 00385 for(size_t i=0;i<size;i++) { 00386 data_t rold=vparent_t::data[i*vparent_t::stride*2]; 00387 data_t iold=vparent_t::data[i*vparent_t::stride*2+1]; 00388 vparent_t::data[i*vparent_t::stride*2]=re*rold-im*iold; 00389 vparent_t::data[i*vparent_t::stride*2+1]=re*iold+im*rold; 00390 } 00391 00392 return *this; 00393 } 00394 00395 /** \brief operator+= */ 00396 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00397 (const data_t &x) { 00398 for(size_t i=0;i<size;i++) { 00399 vparent_t::data[i*vparent_t::stride*2]+=x; 00400 } 00401 00402 return *this; 00403 } 00404 00405 /** \brief operator-= */ 00406 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00407 (const data_t &x) { 00408 for(size_t i=0;i<size;i++) { 00409 vparent_t::data[i*vparent_t::stride*2]-=x; 00410 } 00411 00412 return *this; 00413 } 00414 00415 /** \brief operator*= */ 00416 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00417 (const data_t &x) { 00418 for(size_t i=0;i<size;i++) { 00419 vparent_t::data[i*vparent_t::stride*2]*=x; 00420 vparent_t::data[i*vparent_t::stride*2+1]*=x; 00421 } 00422 00423 return *this; 00424 } 00425 //@} 00426 00427 /// Conjugate the vector 00428 int conjugate() { 00429 size_t sz=vparent_t::size; 00430 for(size_t i=0;i<sz;i++) { 00431 data_t tmp=(*this)[i].dat[1]; 00432 (*this)[i].dat[1]=-tmp; 00433 //vparent_t::data[i*vparent_t::stride*2+1]*=-1.0; 00434 } 00435 return 0; 00436 } 00437 00438 /** \brief Complex norm \f$ v^{\dagger} v \f$ */ 00439 data_t norm() const { 00440 data_t result=0; 00441 for(size_t i=0;i<vparent_t::size;i++) { 00442 data_t re=vparent_t::data[i*vparent_t::stride*2]; 00443 data_t im=vparent_t::data[i*vparent_t::stride*2+1]; 00444 result+=re*re+im*im; 00445 } 00446 return sqrt(result); 00447 } 00448 00449 #ifndef DOXYGEN_INTERNAL 00450 00451 protected: 00452 00453 /** \brief Empty constructor provided for use by 00454 ovector_cx_tlate(const ovector_cx_tlate &v) [protected] 00455 */ 00456 ovector_cx_view_tlate() {}; 00457 00458 #endif 00459 00460 }; 00461 00462 /** \brief A vector of double-precision numbers 00463 00464 If the memory allocation fails, either in the constructor or in 00465 allocate(), then the error handler will be called, partially 00466 allocated memory will be freed, and the size will be reset to 00467 zero. You can test to see if the allocation succeeded using 00468 something like 00469 \code 00470 const size_t n=10; 00471 ovector_cx x(10); 00472 if (x.size()==0) cout << "Failed." << endl; 00473 \endcode 00474 00475 \todo Add subvector_stride, const_subvector_stride 00476 00477 */ 00478 template<class data_t, class vparent_t, class block_t, class complex_t> 00479 class ovector_cx_tlate : 00480 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00481 00482 public: 00483 00484 /// \name Standard constructor 00485 //@{ 00486 /** \brief Create an ovector_cx of size \c n with owner as 'true' */ 00487 ovector_cx_tlate(size_t n=0) { 00488 00489 vparent_t::data=0; 00490 vparent_t::size=0; 00491 vparent_t::stride=0; 00492 00493 // This must be set to 1 even if n=0 so that future 00494 // calls to operator= work properly 00495 vparent_t::owner=1; 00496 00497 if (n>0) { 00498 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00499 if (vparent_t::block) { 00500 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00501 if (vparent_t::block->data) { 00502 vparent_t::block->size=n; 00503 vparent_t::data=vparent_t::block->data; 00504 vparent_t::size=n; 00505 vparent_t::stride=1; 00506 } else { 00507 std::free(vparent_t::block); 00508 O2SCL_ERR("No memory for data in ovector_cx_tlate constructor", 00509 gsl_enomem); 00510 } 00511 } else { 00512 O2SCL_ERR("No memory for block in ovector_cx_tlate contructor", 00513 gsl_enomem); 00514 } 00515 } 00516 } 00517 //@} 00518 00519 /// \name Copy constructors 00520 //@{ 00521 /// Deep copy constructor, allocate new space and make a copy 00522 ovector_cx_tlate(const ovector_cx_tlate &v) : 00523 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t>() { 00524 size_t n=v.size(); 00525 if (n>0) { 00526 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00527 if (vparent_t::block) { 00528 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00529 if (vparent_t::block->data) { 00530 vparent_t::block->size=n; 00531 vparent_t::data=vparent_t::block->data; 00532 vparent_t::size=n; 00533 vparent_t::stride=1; 00534 vparent_t::owner=1; 00535 for(size_t i=0;i<n;i++) { 00536 vparent_t::data[2*i]=v.data[2*i*v.stride()]; 00537 vparent_t::data[2*i+1]=v.data[2*i*v.stride()+1]; 00538 } 00539 } else { 00540 std::free(vparent_t::block); 00541 O2SCL_ERR("No memory for data in ovector_cx_tlate constructor", 00542 gsl_enomem); 00543 } 00544 } else { 00545 O2SCL_ERR("No memory for block in ovector_cx_tlate contructor", 00546 gsl_enomem); 00547 } 00548 } else { 00549 vparent_t::size=0; 00550 vparent_t::stride=0; 00551 } 00552 } 00553 00554 /// Deep copy constructor, allocate new space and make a copy 00555 ovector_cx_tlate 00556 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) : 00557 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t>() { 00558 size_t n=v.size(); 00559 if (n>0) { 00560 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00561 if (vparent_t::block) { 00562 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00563 if (vparent_t::block->data) { 00564 vparent_t::block->size=n; 00565 vparent_t::data=vparent_t::block->data; 00566 vparent_t::size=n; 00567 vparent_t::stride=1; 00568 vparent_t::owner=1; 00569 for(size_t i=0;i<n;i++) { 00570 vparent_t::data[2*i]=v.data[2*i*v.stride()]; 00571 vparent_t::data[2*i+1]=v.data[2*i*v.stride()+1]; 00572 } 00573 } else { 00574 std::free(vparent_t::block); 00575 O2SCL_ERR("No memory for data in ovector_cx_tlate constructor", 00576 gsl_enomem); 00577 } 00578 } else { 00579 O2SCL_ERR("No memory for block in ovector_cx_tlate contructor", 00580 gsl_enomem); 00581 } 00582 } else { 00583 vparent_t::size=0; 00584 vparent_t::stride=0; 00585 } 00586 } 00587 00588 /** \brief Deep copy constructor, if owner is true, allocate space and 00589 make a new copy, otherwise, just copy into the view 00590 */ 00591 ovector_cx_tlate& operator=(const ovector_cx_tlate &v) { 00592 00593 // Check for self-assignment 00594 if (this==&v) return *this; 00595 00596 size_t size=v.size; 00597 if (vparent_t::owner) { 00598 allocate(size); 00599 } else { 00600 if (vparent_t::size!=size) { 00601 O2SCL_ERR("Sizes don't match in ovector_cx_tlate::operator=()", 00602 gsl_ebadlen); 00603 return *this; 00604 } 00605 } 00606 for(size_t i=0;i<size;i++) { 00607 vparent_t::data[2*i*vparent_t::stride]=v.data[2*i*v.stride()]; 00608 vparent_t::data[2*i*vparent_t::stride+1]=v.data[2*i*v.stride()+1]; 00609 } 00610 return *this; 00611 } 00612 00613 /** \brief Deep copy constructor, if owner is true, allocate space and 00614 make a new copy, otherwise, just copy into the view 00615 */ 00616 ovector_cx_tlate& operator= 00617 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) { 00618 00619 // Check for self-assignment 00620 if (this==&v) return *this; 00621 00622 size_t size=v.size(); 00623 if (vparent_t::owner) { 00624 allocate(size); 00625 } else { 00626 if (vparent_t::size!=size) { 00627 O2SCL_ERR("Sizes don't match in ovector_cx_tlate::operator=()", 00628 gsl_ebadlen); 00629 return *this; 00630 } 00631 } 00632 for(size_t i=0;i<size;i++) { 00633 vparent_t::data[2*i*vparent_t::stride]=v.data[2*i*v.stride()]; 00634 vparent_t::data[2*i*vparent_t::stride+1]=v.data[2*i*v.stride()+1]; 00635 } 00636 return *this; 00637 } 00638 //@} 00639 00640 ~ovector_cx_tlate() { 00641 if (vparent_t::size>0) { 00642 if (vparent_t::owner==1) { 00643 if (vparent_t::block->size>0) { 00644 std::free(vparent_t::block->data); 00645 } 00646 std::free(vparent_t::block); 00647 vparent_t::size=0; 00648 } 00649 } 00650 } 00651 00652 /// \name Memory allocation 00653 //@{ 00654 /** \brief Allocate memory for size \c n after freeing any memory 00655 presently in use 00656 */ 00657 int allocate(size_t nsize) { 00658 if (vparent_t::size>0) free(); 00659 00660 if (nsize>0) { 00661 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00662 if (vparent_t::block) { 00663 vparent_t::block->data=(data_t *)malloc(2*nsize*sizeof(data_t)); 00664 if (vparent_t::block->data) { 00665 vparent_t::block->size=nsize; 00666 vparent_t::data=vparent_t::block->data; 00667 vparent_t::size=nsize; 00668 vparent_t::stride=1; 00669 vparent_t::owner=1; 00670 } else { 00671 std::free(vparent_t::block); 00672 O2SCL_ERR_RET("No memory for data in ovector_cx_tlate::allocate()", 00673 gsl_enomem); 00674 } 00675 } else { 00676 O2SCL_ERR_RET("No memory for block in ovector_cx_tlate::allocate()", 00677 gsl_enomem); 00678 } 00679 } else { 00680 O2SCL_ERR_RET("Zero size in ovector_cx::allocate()",gsl_einval); 00681 } 00682 return 0; 00683 } 00684 00685 /** \brief Free the memory 00686 00687 This function will safely do nothing if used without first 00688 allocating memory or if called multiple times in succession. 00689 */ 00690 int free() { 00691 if (vparent_t::size>0) { 00692 if (vparent_t::owner==1) { 00693 if (vparent_t::block->size>0) { 00694 std::free(vparent_t::block->data); 00695 } 00696 std::free(vparent_t::block); 00697 } 00698 vparent_t::size=0; 00699 vparent_t::stride=0; 00700 } 00701 return 0; 00702 } 00703 //@} 00704 00705 /// \name Other methods 00706 //@{ 00707 /** \brief Return a gsl vector_cx */ 00708 vparent_t *get_gsl_vector_complex() { return this; } 00709 00710 /** \brief Return a gsl vector_cx */ 00711 const vparent_t *get_gsl_vector_complex_const() const 00712 { return this; } 00713 //@} 00714 00715 }; 00716 00717 /** \brief Create a vector from an array 00718 */ 00719 template<class data_t, class vparent_t, class block_t, class complex_t> 00720 class ovector_cx_array_tlate : 00721 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00722 00723 public: 00724 00725 /** \brief Create a vector from \c dat with size \c n */ 00726 ovector_cx_array_tlate(size_t n, complex_t *dat) { 00727 if (n>0) { 00728 vparent_t::block=0; 00729 vparent_t::data=dat; 00730 vparent_t::size=n; 00731 vparent_t::stride=1; 00732 vparent_t::owner=0; 00733 } 00734 } 00735 }; 00736 00737 /** \brief Create a vector from an array with a stride 00738 */ 00739 template<class data_t, class vparent_t, class block_t, class complex_t> 00740 class ovector_cx_array_stride_tlate : 00741 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00742 00743 public: 00744 00745 /** \brief Create a vector from \c dat with size \c n and stride \c s 00746 */ 00747 ovector_cx_array_stride_tlate(size_t n, complex_t *dat, size_t s) { 00748 if (n>0) { 00749 vparent_t::block=0; 00750 vparent_t::data=dat; 00751 vparent_t::size=n; 00752 vparent_t::stride=s; 00753 vparent_t::owner=0; 00754 } 00755 } 00756 }; 00757 00758 /** \brief Create a vector from a subvector of another 00759 */ 00760 template<class data_t, class vparent_t, class block_t, class complex_t> 00761 class ovector_cx_subvector_tlate : 00762 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00763 00764 public: 00765 00766 /** \brief Create a vector from \c orig */ 00767 ovector_cx_subvector_tlate 00768 (ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &orig, 00769 size_t offset, size_t n) { 00770 00771 vparent_t::size=0; 00772 vparent_t::stride=0; 00773 vparent_t::data=0; 00774 00775 if (offset+n-1<orig.size()) { 00776 vparent_t::block=0; 00777 vparent_t::data=orig.data+offset*2*orig.stride(); 00778 vparent_t::size=n; 00779 vparent_t::stride=orig.stride(); 00780 vparent_t::owner=0; 00781 } else { 00782 O2SCL_ERR("Subvector failed in ovector_cx_sub_view().",1); 00783 } 00784 } 00785 }; 00786 00787 /** \brief Create a vector from an array 00788 */ 00789 template<class data_t, class vparent_t, class block_t, class complex_t> 00790 class ovector_cx_const_array_tlate : 00791 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00792 public: 00793 /** \brief Create a vector from \c dat with size \c n */ 00794 ovector_cx_const_array_tlate(size_t n, const complex_t *dat) { 00795 if (n>0) { 00796 vparent_t::block=0; 00797 // We have to do an explicit cast here, but we prevent the 00798 // user from changing the data. 00799 vparent_t::data=(data_t *)dat; 00800 vparent_t::size=n; 00801 vparent_t::stride=1; 00802 vparent_t::owner=0; 00803 } 00804 } 00805 00806 ~ovector_cx_const_array_tlate() {}; 00807 00808 #ifndef DOXYGEN_INTERNAL 00809 00810 protected: 00811 00812 /** \name These are inaccessible to ensure the vector is \c const. 00813 */ 00814 //@{ 00815 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00816 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00817 data_t *get_ptr(size_t i) { return 0; } 00818 int set(size_t i, data_t val) { return 0; } 00819 int set_all(double val) { return 0; } 00820 vparent_t *get_gsl_vector() { return 0; } 00821 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00822 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00823 return *this; 00824 } 00825 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00826 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00827 return *this; 00828 } 00829 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00830 (const data_t &y) { 00831 return *this; 00832 } 00833 //@} 00834 00835 #endif 00836 00837 }; 00838 00839 /** \brief Create a vector from an array_stride 00840 */ 00841 template<class data_t, class vparent_t, class block_t, class complex_t> 00842 class ovector_cx_const_array_stride_tlate : 00843 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00844 00845 public: 00846 00847 /** \brief Create a vector from \c dat with size \c n */ 00848 ovector_cx_const_array_stride_tlate(size_t n, const complex_t *dat, 00849 size_t s) { 00850 if (n>0) { 00851 vparent_t::block=0; 00852 // We have to do an explicit cast here, but we prevent the 00853 // user from changing the data. 00854 vparent_t::data=(data_t *)dat; 00855 vparent_t::size=n; 00856 vparent_t::stride=s; 00857 vparent_t::owner=0; 00858 } 00859 } 00860 00861 #ifndef DOXYGEN_INTERNAL 00862 00863 protected: 00864 00865 /** \name These are inaccessible to ensure the vector is \c const. 00866 */ 00867 //@{ 00868 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00869 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00870 data_t *get_ptr(size_t i) { return 0; } 00871 int set(size_t i, data_t val) { return 0; } 00872 int set_all(double val) { return 0; } 00873 vparent_t *get_gsl_vector() { return 0; } 00874 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00875 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00876 return *this; 00877 } 00878 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00879 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00880 return *this; 00881 } 00882 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00883 (const data_t &y) { 00884 return *this; 00885 } 00886 //@} 00887 00888 #endif 00889 00890 }; 00891 00892 /** \brief Create a vector from a subvector of another 00893 */ 00894 template<class data_t, class vparent_t, class block_t, class complex_t> 00895 class ovector_cx_const_subvector_tlate : 00896 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00897 00898 public: 00899 00900 /** \brief Create a vector from \c orig 00901 */ 00902 ovector_cx_const_subvector_tlate 00903 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &orig, 00904 size_t offset, size_t n) { 00905 if (offset+n-1<orig.size) { 00906 vparent_t::block=0; 00907 vparent_t::data=orig.data+offset*2*orig.stride; 00908 vparent_t::size=n; 00909 vparent_t::stride=orig.stride; 00910 vparent_t::owner=0; 00911 } else { 00912 vparent_t::size=0; 00913 O2SCL_ERR("Subvector failed in ovector_cx_subvector().",1); 00914 } 00915 } 00916 00917 #ifndef DOXYGEN_INTERNAL 00918 00919 protected: 00920 00921 /** \name These are inaccessible to ensure the vector is \c const. 00922 */ 00923 //@{ 00924 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00925 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00926 data_t *get_ptr(size_t i) { return 0; } 00927 int set(size_t i, data_t val) { return 0; } 00928 int set_all(double val) { return 0; } 00929 vparent_t *get_gsl_vector() { return 0; } 00930 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00931 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00932 return *this; 00933 } 00934 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00935 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00936 return *this; 00937 } 00938 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00939 (const data_t &y) { 00940 return *this; 00941 } 00942 //@} 00943 00944 #endif 00945 00946 }; 00947 00948 /** \brief Create a real vector from the real parts of a complex vector 00949 */ 00950 template<class data_t, class vparent_t, class block_t, 00951 class cvparent_t, class cblock_t, class complex_t> 00952 class ovector_cx_real_tlate : 00953 public ovector_view_tlate<data_t,vparent_t,block_t> { 00954 00955 public: 00956 00957 /** \brief Create a real vector from the real parts of a complex vector 00958 */ 00959 ovector_cx_real_tlate 00960 (ovector_cx_view_tlate<data_t,cvparent_t,cblock_t,complex_t> &x) { 00961 vparent_t::block=0; 00962 vparent_t::data=x.data; 00963 vparent_t::size=x.size; 00964 vparent_t::stride=2*x.stride; 00965 vparent_t::owner=false; 00966 } 00967 }; 00968 00969 /** \brief Create a imaginary vector from the imaginary parts of a 00970 complex vector 00971 */ 00972 template<class data_t, class vparent_t, class block_t, 00973 class cvparent_t, class cblock_t, class complex_t> 00974 class ovector_cx_imag_tlate : 00975 public ovector_view_tlate<data_t,vparent_t,block_t> { 00976 00977 public: 00978 00979 /** \brief Create a imaginary vector from the imaginary parts of a 00980 complex vector 00981 */ 00982 ovector_cx_imag_tlate 00983 (ovector_cx_view_tlate<data_t,cvparent_t,cblock_t,complex_t> &x) { 00984 vparent_t::block=0; 00985 vparent_t::data=x.data+1; 00986 vparent_t::size=x.size; 00987 vparent_t::stride=2*x.stride; 00988 vparent_t::owner=false; 00989 } 00990 }; 00991 00992 /** \brief A complex vector where the memory allocation is performed in 00993 the constructor 00994 */ 00995 #ifdef DOXYGENP 00996 template<size_t N=0> class ofvector_cx : 00997 public ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> 00998 #else 00999 template<size_t N=0> class ofvector_cx : 01000 public ovector_cx_tlate<double,gsl_vector_complex,gsl_block_complex, 01001 gsl_complex> 01002 #endif 01003 { 01004 public: 01005 ofvector_cx() : ovector_cx_tlate<double,gsl_vector_complex, 01006 gsl_block_complex,gsl_complex>(N) { 01007 } 01008 }; 01009 01010 /// ovector_cx typedef 01011 typedef ovector_cx_tlate<double,gsl_vector_complex,gsl_block_complex, 01012 gsl_complex> ovector_cx; 01013 /// ovector_cx_view typedef 01014 typedef ovector_cx_view_tlate<double,gsl_vector_complex,gsl_block_complex, 01015 gsl_complex> ovector_cx_view; 01016 /// ovector_cx_array typedef 01017 typedef ovector_cx_array_tlate<double,gsl_vector_complex,gsl_block_complex, 01018 gsl_complex> ovector_cx_array; 01019 /// ovector_cx_array_stride typedef 01020 typedef ovector_cx_array_stride_tlate<double,gsl_vector_complex, 01021 gsl_block_complex,gsl_complex> 01022 ovector_cx_array_stride; 01023 /// ovector_cx_subvector typedef 01024 typedef ovector_cx_subvector_tlate<double,gsl_vector_complex, 01025 gsl_block_complex,gsl_complex> 01026 ovector_cx_subvector; 01027 /// ovector_cx_const_array typedef 01028 typedef ovector_cx_const_array_tlate<double,gsl_vector_complex, 01029 gsl_block_complex,gsl_complex> 01030 ovector_cx_const_array; 01031 /// ovector_cx_const_array_stride typedef 01032 typedef ovector_cx_const_array_stride_tlate<double,gsl_vector_complex, 01033 gsl_block_complex,gsl_complex> 01034 ovector_cx_const_array_stride; 01035 /// ovector_cx_const_subvector typedef 01036 typedef ovector_cx_const_subvector_tlate<double,gsl_vector_complex, 01037 gsl_block_complex,gsl_complex> 01038 ovector_cx_const_subvector; 01039 /// ovector_cx_real typedef 01040 typedef ovector_cx_real_tlate<double,gsl_vector,gsl_block, 01041 gsl_vector_complex,gsl_block_complex,gsl_complex> ovector_cx_real; 01042 /// ovector_cx_imag typedef 01043 typedef ovector_cx_imag_tlate<double,gsl_vector,gsl_block, 01044 gsl_vector_complex,gsl_block_complex,gsl_complex> ovector_cx_imag; 01045 01046 /** \brief Conjugate a vector */ 01047 template<class data_t,class vparent_t,class block_t, class complex_t> 01048 ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> 01049 conjugate(ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> &v) { 01050 ovector_tlate<data_t,vparent_t,block_t> result(v.size()); 01051 for(size_t i=0;i<v.size();i++) { 01052 double *p=vparent_t::data+i*vparent_t::stride*2+1; 01053 (*p)=-(*p); 01054 } 01055 return result; 01056 } 01057 01058 /** \brief A operator for naive vector output 01059 01060 This outputs all of the vector elements in the form \c (r,i). 01061 All of these are separated by one space character, though no 01062 trailing space or \c endl is sent to the output. 01063 */ 01064 template<class data_t, class vparent_t, class block_t, class complex_t> 01065 std::ostream &operator<< 01066 (std::ostream &os, 01067 const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) { 01068 for(size_t i=0;i<v.size()-1;i++) { 01069 os << '(' << v.real(i) << ',' << v.imag(i) << ") "; 01070 } 01071 os << '(' << v.real(v.size()-1) << ',' 01072 << v.imag(v.size()-1) << ") "; 01073 return os; 01074 } 01075 01076 #ifndef DOXYGENP 01077 } 01078 #endif 01079 01080 #endif 01081
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).