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