00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_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 /// So2scllow 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 /// So2scllow 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 public: 00506 00507 /// \name Standard constructor 00508 //@{ 00509 /** \brief Create an ovector_cx of size \c n with owner as 'true' */ 00510 ovector_cx_tlate(size_t n=0) { 00511 00512 vparent_t::data=0; 00513 vparent_t::size=0; 00514 vparent_t::stride=0; 00515 00516 // This must be set to 1 even if n=0 so that future 00517 // calls to operator= work properly 00518 vparent_t::owner=1; 00519 00520 if (n>0) { 00521 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00522 if (vparent_t::block) { 00523 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00524 if (vparent_t::block->data) { 00525 vparent_t::block->size=n; 00526 vparent_t::data=vparent_t::block->data; 00527 vparent_t::size=n; 00528 vparent_t::stride=1; 00529 } else { 00530 std::free(vparent_t::block); 00531 set_err("No memory for data in ovector_cx_tlate constructor", 00532 gsl_enomem); 00533 } 00534 } else { 00535 set_err("No memory for block in ovector_cx_tlate contructor", 00536 gsl_enomem); 00537 } 00538 } 00539 } 00540 //@} 00541 00542 /// \name Copy constructors 00543 //@{ 00544 /// Deep copy constructor, allocate new space and make a copy 00545 ovector_cx_tlate(const ovector_cx_tlate &v) : 00546 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t>() { 00547 size_t n=v.size(); 00548 if (n>0) { 00549 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00550 if (vparent_t::block) { 00551 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00552 if (vparent_t::block->data) { 00553 vparent_t::block->size=n; 00554 vparent_t::data=vparent_t::block->data; 00555 vparent_t::size=n; 00556 vparent_t::stride=1; 00557 vparent_t::owner=1; 00558 for(size_t i=0;i<n;i++) { 00559 vparent_t::data[2*i]=v.data[2*i*v.stride()]; 00560 vparent_t::data[2*i+1]=v.data[2*i*v.stride()+1]; 00561 } 00562 } else { 00563 std::free(vparent_t::block); 00564 set_err("No memory for data in ovector_cx_tlate constructor", 00565 gsl_enomem); 00566 } 00567 } else { 00568 set_err("No memory for block in ovector_cx_tlate contructor", 00569 gsl_enomem); 00570 } 00571 } else { 00572 vparent_t::size=0; 00573 vparent_t::stride=0; 00574 } 00575 } 00576 00577 /// Deep copy constructor, allocate new space and make a copy 00578 ovector_cx_tlate 00579 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) : 00580 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t>() { 00581 size_t n=v.size(); 00582 if (n>0) { 00583 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00584 if (vparent_t::block) { 00585 vparent_t::block->data=(data_t *)malloc(2*n*sizeof(data_t)); 00586 if (vparent_t::block->data) { 00587 vparent_t::block->size=n; 00588 vparent_t::data=vparent_t::block->data; 00589 vparent_t::size=n; 00590 vparent_t::stride=1; 00591 vparent_t::owner=1; 00592 for(size_t i=0;i<n;i++) { 00593 vparent_t::data[2*i]=v.data[2*i*v.stride()]; 00594 vparent_t::data[2*i+1]=v.data[2*i*v.stride()+1]; 00595 } 00596 } else { 00597 std::free(vparent_t::block); 00598 set_err("No memory for data in ovector_cx_tlate constructor", 00599 gsl_enomem); 00600 } 00601 } else { 00602 set_err("No memory for block in ovector_cx_tlate contructor", 00603 gsl_enomem); 00604 } 00605 } else { 00606 vparent_t::size=0; 00607 vparent_t::stride=0; 00608 } 00609 } 00610 00611 /** \brief Deep copy constructor, if owner is true, allocate space and 00612 make a new copy, otherwise, just copy into the view 00613 */ 00614 ovector_cx_tlate& operator=(const ovector_cx_tlate &v) { 00615 size_t size=v.size; 00616 if (vparent_t::owner) { 00617 allocate(size); 00618 } else { 00619 if (vparent_t::size!=size) { 00620 set_err("Sizes don't match in ovector_cx_tlate::operator=()", 00621 gsl_ebadlen); 00622 return *this; 00623 } 00624 } 00625 for(size_t i=0;i<size;i++) { 00626 vparent_t::data[2*i*vparent_t::stride]=v.data[2*i*v.stride()]; 00627 vparent_t::data[2*i*vparent_t::stride+1]=v.data[2*i*v.stride()+1]; 00628 } 00629 return *this; 00630 } 00631 00632 /** \brief Deep copy constructor, if owner is true, allocate space and 00633 make a new copy, otherwise, just copy into the view 00634 */ 00635 ovector_cx_tlate& operator= 00636 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) { 00637 size_t size=v.size(); 00638 if (vparent_t::owner) { 00639 allocate(size); 00640 } else { 00641 if (vparent_t::size!=size) { 00642 set_err("Sizes don't match in ovector_cx_tlate::operator=()", 00643 gsl_ebadlen); 00644 return *this; 00645 } 00646 } 00647 for(size_t i=0;i<size;i++) { 00648 vparent_t::data[2*i*vparent_t::stride]=v.data[2*i*v.stride()]; 00649 vparent_t::data[2*i*vparent_t::stride+1]=v.data[2*i*v.stride()+1]; 00650 } 00651 return *this; 00652 } 00653 //@} 00654 00655 ~ovector_cx_tlate() { 00656 if (vparent_t::size>0) { 00657 if (vparent_t::owner==1) { 00658 if (vparent_t::block->size>0) { 00659 std::free(vparent_t::block->data); 00660 } 00661 std::free(vparent_t::block); 00662 vparent_t::size=0; 00663 } 00664 } 00665 } 00666 00667 /// \name Memory allocation 00668 //@{ 00669 /** 00670 \brief Allocate memory for size \c n after freeing any memory 00671 presently in use 00672 */ 00673 int allocate(size_t nsize) { 00674 if (vparent_t::size>0) free(); 00675 00676 if (nsize>0) { 00677 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00678 if (vparent_t::block) { 00679 vparent_t::block->data=(data_t *)malloc(2*nsize*sizeof(data_t)); 00680 if (vparent_t::block->data) { 00681 vparent_t::block->size=nsize; 00682 vparent_t::data=vparent_t::block->data; 00683 vparent_t::size=nsize; 00684 vparent_t::stride=1; 00685 vparent_t::owner=1; 00686 } else { 00687 std::free(vparent_t::block); 00688 set_err_ret("No memory for data in ovector_cx_tlate::allocate()", 00689 gsl_enomem); 00690 } 00691 } else { 00692 set_err_ret("No memory for block in ovector_cx_tlate::allocate()", 00693 gsl_enomem); 00694 } 00695 } else { 00696 set_err_ret("Zero size in ovector_cx::allocate()",gsl_einval); 00697 } 00698 return 0; 00699 } 00700 00701 /** 00702 \brief Free the memory 00703 00704 This function will safely do nothing if used without first 00705 allocating memory or if called multiple times in succession. 00706 */ 00707 int free() { 00708 if (vparent_t::size>0) { 00709 if (vparent_t::owner==1) { 00710 if (vparent_t::block->size>0) { 00711 std::free(vparent_t::block->data); 00712 } 00713 std::free(vparent_t::block); 00714 } 00715 vparent_t::size=0; 00716 vparent_t::stride=0; 00717 } 00718 return 0; 00719 } 00720 //@} 00721 00722 /// \name Other methods 00723 //@{ 00724 /** \brief Return a gsl vector_cx */ 00725 vparent_t *get_gsl_vector_complex() { return this; } 00726 00727 /** \brief Return a gsl vector_cx */ 00728 const vparent_t *get_gsl_vector_complex_const() const 00729 { return this; } 00730 //@} 00731 00732 }; 00733 00734 /** \brief Create a vector from an array 00735 */ 00736 template<class data_t, class vparent_t, class block_t, class complex_t> 00737 class ovector_cx_array_tlate : 00738 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00739 public: 00740 /** \brief Create a vector from \c dat with size \c n */ 00741 ovector_cx_array_tlate(size_t n, complex_t *dat) { 00742 if (n>0) { 00743 vparent_t::block=NULL; 00744 vparent_t::data=dat; 00745 vparent_t::size=n; 00746 vparent_t::stride=1; 00747 vparent_t::owner=0; 00748 } 00749 } 00750 }; 00751 00752 /** \brief Create a vector from an array with a stride 00753 */ 00754 template<class data_t, class vparent_t, class block_t, class complex_t> 00755 class ovector_cx_array_stride_tlate : 00756 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00757 public: 00758 /** \brief Create a vector from \c dat with size \c n and stride \c s 00759 */ 00760 ovector_cx_array_stride_tlate(size_t n, complex_t *dat, size_t s) { 00761 if (n>0) { 00762 vparent_t::block=NULL; 00763 vparent_t::data=dat; 00764 vparent_t::size=n; 00765 vparent_t::stride=s; 00766 vparent_t::owner=0; 00767 } 00768 } 00769 }; 00770 00771 /** \brief Create a vector from a subvector of another 00772 */ 00773 template<class data_t, class vparent_t, class block_t, class complex_t> 00774 class ovector_cx_subvector_tlate : 00775 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00776 public: 00777 /** \brief Create a vector from \c orig */ 00778 ovector_cx_subvector_tlate 00779 (ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &orig, 00780 size_t offset, size_t n) { 00781 00782 vparent_t::size=0; 00783 vparent_t::stride=0; 00784 vparent_t::data=0; 00785 00786 if (offset+n-1<orig.size()) { 00787 vparent_t::block=NULL; 00788 vparent_t::data=orig.data+offset*2*orig.stride(); 00789 vparent_t::size=n; 00790 vparent_t::stride=orig.stride(); 00791 vparent_t::owner=0; 00792 } else { 00793 set_err("Subvector failed in ovector_cx_sub_view().",1); 00794 } 00795 } 00796 }; 00797 00798 /** \brief Create a vector from an array 00799 */ 00800 template<class data_t, class vparent_t, class block_t, class complex_t> 00801 class ovector_cx_const_array_tlate : 00802 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00803 public: 00804 /** \brief Create a vector from \c dat with size \c n */ 00805 ovector_cx_const_array_tlate(size_t n, const complex_t *dat) { 00806 if (n>0) { 00807 vparent_t::block=NULL; 00808 // We have to do an explicit cast here, but we prevent the 00809 // user from changing the data. 00810 vparent_t::data=(data_t *)dat; 00811 vparent_t::size=n; 00812 vparent_t::stride=1; 00813 vparent_t::owner=0; 00814 } 00815 } 00816 00817 ~ovector_cx_const_array_tlate() {}; 00818 00819 #ifndef DOXYGEN_INTERNAL 00820 00821 protected: 00822 00823 /** \name These are inaccessible to ensure the vector is \c const. 00824 */ 00825 //@{ 00826 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00827 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00828 data_t *get_ptr(size_t i) { return NULL; } 00829 int set(size_t i, data_t val) { return 0; } 00830 int swap(ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00831 return 0; 00832 } 00833 int set_all(double val) { return 0; } 00834 vparent_t *get_gsl_vector() { return NULL; } 00835 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00836 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00837 return *this; 00838 } 00839 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00840 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00841 return *this; 00842 } 00843 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00844 (const data_t &y) { 00845 return *this; 00846 } 00847 //@} 00848 00849 #endif 00850 00851 }; 00852 00853 /** \brief Create a vector from an array_stride 00854 */ 00855 template<class data_t, class vparent_t, class block_t, class complex_t> 00856 class ovector_cx_const_array_stride_tlate : 00857 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00858 public: 00859 /** \brief Create a vector from \c dat with size \c n */ 00860 ovector_cx_const_array_stride_tlate(size_t n, const complex_t *dat, 00861 size_t s) { 00862 if (n>0) { 00863 vparent_t::block=NULL; 00864 // We have to do an explicit cast here, but we prevent the 00865 // user from changing the data. 00866 vparent_t::data=(data_t *)dat; 00867 vparent_t::size=n; 00868 vparent_t::stride=s; 00869 vparent_t::owner=0; 00870 } 00871 } 00872 00873 #ifndef DOXYGEN_INTERNAL 00874 00875 protected: 00876 00877 /** \name These are inaccessible to ensure the vector is \c const. 00878 */ 00879 //@{ 00880 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00881 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00882 data_t *get_ptr(size_t i) { return NULL; } 00883 int set(size_t i, data_t val) { return 0; } 00884 int swap(ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00885 return 0; 00886 } 00887 int set_all(double val) { return 0; } 00888 vparent_t *get_gsl_vector() { return NULL; } 00889 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00890 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00891 return *this; 00892 } 00893 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00894 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00895 return *this; 00896 } 00897 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00898 (const data_t &y) { 00899 return *this; 00900 } 00901 //@} 00902 00903 #endif 00904 00905 }; 00906 00907 /** \brief Create a vector from a subvector of another 00908 */ 00909 template<class data_t, class vparent_t, class block_t, class complex_t> 00910 class ovector_cx_const_subvector_tlate : 00911 public ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> { 00912 public: 00913 /** \brief Create a vector from \c orig 00914 */ 00915 ovector_cx_const_subvector_tlate 00916 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &orig, 00917 size_t offset, size_t n) { 00918 if (offset+n-1<orig.size) { 00919 vparent_t::block=NULL; 00920 vparent_t::data=orig.data+offset*2*orig.stride; 00921 vparent_t::size=n; 00922 vparent_t::stride=orig.stride; 00923 vparent_t::owner=0; 00924 } else { 00925 vparent_t::size=0; 00926 set_err("Subvector failed in ovector_cx_subvector().",1); 00927 } 00928 } 00929 00930 #ifndef DOXYGEN_INTERNAL 00931 00932 protected: 00933 00934 /** \name These are inaccessible to ensure the vector is \c const. 00935 */ 00936 //@{ 00937 data_t &operator[](size_t i) { return vparent_t::data[0]; } 00938 data_t &operator()(size_t i) { return vparent_t::data[0]; } 00939 data_t *get_ptr(size_t i) { return NULL; } 00940 int set(size_t i, data_t val) { return 0; } 00941 int swap(ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00942 return 0; 00943 } 00944 int set_all(double val) { return 0; } 00945 vparent_t *get_gsl_vector() { return NULL; } 00946 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator+= 00947 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00948 return *this; 00949 } 00950 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator-= 00951 (const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &x) { 00952 return *this; 00953 } 00954 ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &operator*= 00955 (const data_t &y) { 00956 return *this; 00957 } 00958 //@} 00959 00960 #endif 00961 00962 }; 00963 00964 /** \brief Create a real vector from the real parts of a complex vector 00965 */ 00966 template<class data_t, class vparent_t, class block_t, 00967 class cvparent_t, class cblock_t, class complex_t> 00968 class ovector_cx_real_tlate : 00969 public ovector_view_tlate<data_t,vparent_t,block_t> { 00970 public: 00971 /** \brief Create a real vector from the real parts of a complex vector 00972 */ 00973 ovector_cx_real_tlate 00974 (ovector_cx_view_tlate<data_t,cvparent_t,cblock_t,complex_t> &x) { 00975 vparent_t::block=NULL; 00976 vparent_t::data=x.data; 00977 vparent_t::size=x.size; 00978 vparent_t::stride=2*x.stride; 00979 vparent_t::owner=false; 00980 } 00981 }; 00982 00983 /** \brief Create a imaginary vector from the imaginary parts of a 00984 complex vector 00985 */ 00986 template<class data_t, class vparent_t, class block_t, 00987 class cvparent_t, class cblock_t, class complex_t> 00988 class ovector_cx_imag_tlate : 00989 public ovector_view_tlate<data_t,vparent_t,block_t> { 00990 public: 00991 /** \brief Create a imaginary vector from the imaginary parts of a 00992 complex vector 00993 */ 00994 ovector_cx_imag_tlate 00995 (ovector_cx_view_tlate<data_t,cvparent_t,cblock_t,complex_t> &x) { 00996 vparent_t::block=NULL; 00997 vparent_t::data=x.data+1; 00998 vparent_t::size=x.size; 00999 vparent_t::stride=2*x.stride; 01000 vparent_t::owner=false; 01001 } 01002 }; 01003 01004 /** \brief A vector where the memory allocation is performed in 01005 the constructor 01006 */ 01007 #ifdef DOXYGENP 01008 template<size_t N=0> class ofvector_cx : 01009 public ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> 01010 #else 01011 template<size_t N=0> class ofvector_cx : 01012 public ovector_cx_tlate<double,gsl_vector_complex,gsl_block_complex, 01013 gsl_complex> 01014 #endif 01015 { 01016 public: 01017 ofvector_cx() : ovector_cx_tlate<double,gsl_vector_complex, 01018 gsl_block_complex,gsl_complex>(N) { 01019 } 01020 }; 01021 01022 /// ovector_cx typedef 01023 typedef ovector_cx_tlate<double,gsl_vector_complex,gsl_block_complex, 01024 gsl_complex> ovector_cx; 01025 /// ovector_cx_view typedef 01026 typedef ovector_cx_view_tlate<double,gsl_vector_complex,gsl_block_complex, 01027 gsl_complex> ovector_cx_view; 01028 /// ovector_cx_array typedef 01029 typedef ovector_cx_array_tlate<double,gsl_vector_complex,gsl_block_complex, 01030 gsl_complex> ovector_cx_array; 01031 /// ovector_cx_array_stride typedef 01032 typedef ovector_cx_array_stride_tlate<double,gsl_vector_complex, 01033 gsl_block_complex,gsl_complex> 01034 ovector_cx_array_stride; 01035 /// ovector_cx_subvector typedef 01036 typedef ovector_cx_subvector_tlate<double,gsl_vector_complex, 01037 gsl_block_complex,gsl_complex> 01038 ovector_cx_subvector; 01039 /// ovector_cx_const_array typedef 01040 typedef ovector_cx_const_array_tlate<double,gsl_vector_complex, 01041 gsl_block_complex,gsl_complex> 01042 ovector_cx_const_array; 01043 /// ovector_cx_const_array_stride typedef 01044 typedef ovector_cx_const_array_stride_tlate<double,gsl_vector_complex, 01045 gsl_block_complex,gsl_complex> 01046 ovector_cx_const_array_stride; 01047 /// ovector_cx_const_subvector typedef 01048 typedef ovector_cx_const_subvector_tlate<double,gsl_vector_complex, 01049 gsl_block_complex,gsl_complex> 01050 ovector_cx_const_subvector; 01051 /// ovector_cx_real typedef 01052 typedef ovector_cx_real_tlate<double,gsl_vector,gsl_block, 01053 gsl_vector_complex,gsl_block_complex,gsl_complex> ovector_cx_real; 01054 /// ovector_cx_imag typedef 01055 typedef ovector_cx_imag_tlate<double,gsl_vector,gsl_block, 01056 gsl_vector_complex,gsl_block_complex,gsl_complex> ovector_cx_imag; 01057 01058 /** \brief Conjugate a vector */ 01059 template<class data_t,class vparent_t,class block_t, class complex_t> 01060 ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> 01061 conjugate(ovector_cx_tlate<data_t,vparent_t,block_t,complex_t> &v) { 01062 ovector_tlate<data_t,vparent_t,block_t> result(v.size()); 01063 for(size_t i=0;i<v.size();i++) { 01064 double *p=vparent_t::data+i*vparent_t::stride*2+1; 01065 (*p)=-(*p); 01066 } 01067 return result; 01068 } 01069 01070 /** 01071 \brief A operator for naive vector output 01072 01073 This outputs all of the vector elements in the form \c (r,i). 01074 All of these are separated by one space character, though no 01075 trailing space or \c endl is sent to the output. 01076 */ 01077 template<class data_t, class vparent_t, class block_t, class complex_t> 01078 std::ostream &operator<< 01079 (std::ostream &os, 01080 const ovector_cx_view_tlate<data_t,vparent_t,block_t,complex_t> &v) { 01081 for(size_t i=0;i<v.size()-1;i++) { 01082 os << '(' << v.real(i) << ',' << v.imag(i) << ") "; 01083 } 01084 os << '(' << v.real(v.size()-1) << ',' 01085 << v.imag(v.size()-1) << ") "; 01086 return os; 01087 } 01088 01089 #ifndef DOXYGENP 01090 } 01091 #endif 01092 01093 #endif 01094
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