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