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_TLATE_H 00024 #define O2SCL_OVECTOR_TLATE_H 00025 00026 /** \file ovector_tlate.h 00027 \brief File for definitions of vectors 00028 */ 00029 00030 #include <iostream> 00031 #include <cstdlib> 00032 #include <string> 00033 #include <fstream> 00034 #include <sstream> 00035 #include <vector> 00036 #include <gsl/gsl_vector.h> 00037 #include <o2scl/err_hnd.h> 00038 #include <o2scl/string_conv.h> 00039 #include <o2scl/uvector_tlate.h> 00040 #include <o2scl/array.h> 00041 00042 #ifndef DOXYGENP 00043 namespace o2scl { 00044 #endif 00045 00046 /** 00047 \brief A vector view with finite stride 00048 00049 */ 00050 template<class data_t, class vparent_t, class block_t> 00051 class ovector_view_tlate : 00052 public vparent_t { 00053 00054 public: 00055 00056 /// \name Copy constructors 00057 //@{ 00058 /// So2scllow copy constructor - create a new view of the same vector 00059 ovector_view_tlate(const ovector_view_tlate &v) { 00060 vparent_t::block=NULL; 00061 vparent_t::data=v.data; 00062 vparent_t::size=v.size(); 00063 vparent_t::stride=v.stride(); 00064 vparent_t::owner=0; 00065 } 00066 00067 /// So2scllow copy constructor - create a new view of the same vector 00068 ovector_view_tlate& operator=(const ovector_view_tlate &v) { 00069 vparent_t::block=NULL; 00070 vparent_t::data=v.data; 00071 vparent_t::size=v.size(); 00072 vparent_t::stride=v.stride(); 00073 vparent_t::owner=0; 00074 00075 return *this; 00076 } 00077 00078 /// So2scllow copy constructor - view a unit-stride vector 00079 ovector_view_tlate(const uvector_view_tlate<data_t> &v) { 00080 vparent_t::block=NULL; 00081 vparent_t::data=v.data; 00082 vparent_t::size=v.size(); 00083 vparent_t::stride=1; 00084 vparent_t::owner=0; 00085 } 00086 00087 /// So2scllow copy constructor - view a unit-stride vector 00088 ovector_view_tlate& operator=(const uvector_view_tlate<data_t> &v) { 00089 vparent_t::block=NULL; 00090 vparent_t::data=v.data; 00091 vparent_t::size=v.size(); 00092 vparent_t::stride=1; 00093 vparent_t::owner=0; 00094 00095 return *this; 00096 } 00097 //@} 00098 00099 ~ovector_view_tlate() {}; 00100 00101 /// \name Get and set methods 00102 //@{ 00103 /** 00104 \brief Array-like indexing 00105 */ 00106 data_t &operator[](size_t i) { 00107 #if GSL_RANGE_CHECK 00108 if (i>=vparent_t::size) { 00109 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00110 +" in ovector_view_tlate::operator[]. Size: "+ 00111 itos(vparent_t::size)+ 00112 " (index should be less than size).").c_str(),gsl_index); 00113 return vparent_t::data[0]; 00114 } 00115 #endif 00116 return vparent_t::data[i*vparent_t::stride]; 00117 } 00118 00119 /** 00120 \brief Array-like indexing 00121 */ 00122 const data_t &operator[](size_t i) const { 00123 #if GSL_RANGE_CHECK 00124 if (i>=vparent_t::size) { 00125 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00126 +" in ovector_view_tlate::operator[]. Size: "+ 00127 itos(vparent_t::size)+ 00128 " (index should be less than size).").c_str(),gsl_index); 00129 return vparent_t::data[0]; 00130 } 00131 #endif 00132 return vparent_t::data[i*vparent_t::stride]; 00133 } 00134 00135 /** 00136 \brief Array-like indexing 00137 */ 00138 data_t &operator()(size_t i) { 00139 #if GSL_RANGE_CHECK 00140 if (i>=vparent_t::size) { 00141 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00142 +" in ovector_view_tlate::operator(). Size: "+ 00143 itos(vparent_t::size)+ 00144 " (index should be less than size).").c_str(),gsl_index); 00145 return vparent_t::data[0]; 00146 } 00147 #endif 00148 return vparent_t::data[i*vparent_t::stride]; 00149 } 00150 00151 /** 00152 \brief Array-like indexing 00153 */ 00154 const data_t &operator()(size_t i) const { 00155 #if GSL_RANGE_CHECK 00156 if (i>=vparent_t::size) { 00157 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00158 +" in ovector_view_tlate::operator(). Size: "+ 00159 itos(vparent_t::size)+ 00160 " (index should be less than size).").c_str(),gsl_index); 00161 return vparent_t::data[0]; 00162 } 00163 #endif 00164 return vparent_t::data[i*vparent_t::stride]; 00165 } 00166 00167 /** \brief Get (with optional range-checking) */ 00168 data_t get(size_t i) const { 00169 #if GSL_RANGE_CHECK 00170 if (i>=vparent_t::size) { 00171 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00172 +" in ovector_view_tlate::get(). Size: "+ 00173 itos(vparent_t::size)+ 00174 " (index should be less than size).").c_str(),gsl_index); 00175 return vparent_t::data[0]; 00176 } 00177 #endif 00178 return vparent_t::data[i*vparent_t::stride]; 00179 } 00180 00181 /** \brief Get pointer (with optional range-checking) */ 00182 data_t *get_ptr(size_t i) { 00183 #if GSL_RANGE_CHECK 00184 if (i>=vparent_t::size) { 00185 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00186 +" in ovector_view_tlate::get_ptr(). Size: "+ 00187 itos(vparent_t::size)+ 00188 " (index should be less than size).").c_str(),gsl_index); 00189 return vparent_t::data; 00190 } 00191 #endif 00192 return vparent_t::data+i*vparent_t::stride; 00193 } 00194 00195 /** \brief Get pointer (with optional range-checking) */ 00196 const data_t *get_const_ptr(size_t i) const { 00197 #if GSL_RANGE_CHECK 00198 if (i>=vparent_t::size) { 00199 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 00200 +" in ovector_view_tlate::get_const_ptr(). Size: "+ 00201 itos(vparent_t::size)+ 00202 " (index should be less than size).").c_str(),gsl_index); 00203 return vparent_t::data; 00204 } 00205 #endif 00206 return (const data_t *)(vparent_t::data+i*vparent_t::stride); 00207 } 00208 00209 /** \brief Set (with optional range-checking) */ 00210 int set(size_t i, data_t val) { 00211 #if GSL_RANGE_CHECK 00212 if (i>=vparent_t::size) { 00213 set_err_ret((((std::string)"Array index ")+itos(i)+" out of bounds" 00214 +" in ovector_view_tlate::set(). Size: "+ 00215 itos(vparent_t::size)+ 00216 " (index should be less than size).").c_str(),gsl_index); 00217 } 00218 #endif 00219 vparent_t::data[i*vparent_t::stride]=val; 00220 return 0; 00221 } 00222 00223 /** \brief Set all of the value to be the value \c val */ 00224 int set_all(double val) { 00225 for(size_t i=0;i<vparent_t::size;i++) { 00226 vparent_t::data[i*vparent_t::stride]=val; 00227 } 00228 return 0; 00229 } 00230 00231 /** 00232 \brief Method to return vector size 00233 00234 If no memory has been allocated, this will quietly 00235 return zero. 00236 */ 00237 size_t size() const { 00238 return vparent_t::size; 00239 } 00240 00241 /** 00242 \brief Method to return capacity 00243 00244 Analogous to \c std::vector<>.capacity() 00245 */ 00246 size_t capacity() const { 00247 if (vparent_t::block) return vparent_t::block->size; 00248 return 0; 00249 } 00250 00251 /** 00252 \brief Method to return vector stride 00253 00254 If no memory has been allocated, this will quietly 00255 return zero. 00256 */ 00257 size_t stride() const { 00258 return vparent_t::stride; 00259 } 00260 //@} 00261 00262 /// \name Arithmetic 00263 //@{ 00264 /** \brief operator+= */ 00265 ovector_view_tlate<data_t,vparent_t,block_t> &operator+= 00266 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 00267 size_t lsize=x.size(); 00268 if (lsize>this->size()) lsize=this->size(); 00269 for(size_t i=0;i<lsize;i++) (*this)[i]+=x[i]; 00270 00271 return *this; 00272 } 00273 00274 /** \brief operator-= */ 00275 ovector_view_tlate<data_t,vparent_t,block_t> &operator-= 00276 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 00277 size_t lsize=x.size(); 00278 if (lsize>this->size()) lsize=this->size(); 00279 for(size_t i=0;i<lsize;i++) (*this)[i]-=x[i]; 00280 00281 return *this; 00282 } 00283 00284 /** \brief operator+= */ 00285 ovector_view_tlate<data_t,vparent_t,block_t> &operator+=(data_t &x) { 00286 for(size_t i=0;i<this->size();i++) (*this)[i]+=x; 00287 return *this; 00288 } 00289 00290 /** \brief operator-= */ 00291 ovector_view_tlate<data_t,vparent_t,block_t> &operator-=(data_t &x) { 00292 for(size_t i=0;i<this->size();i++) (*this)[i]-=x; 00293 return *this; 00294 } 00295 00296 /** \brief operator*= */ 00297 ovector_view_tlate<data_t,vparent_t,block_t> &operator*=(const data_t &y) { 00298 for(size_t i=0;i<this->size();i++) (*this)[i]*=y; 00299 00300 return *this; 00301 } 00302 00303 /** \brief Norm */ 00304 data_t norm() const { 00305 data_t result=0; 00306 for(size_t i=0;i<this->size;i++) { 00307 result+=(*this)[i]*(*this)[i]; 00308 } 00309 return sqrt(result); 00310 } 00311 //@} 00312 00313 /// \name Other methods 00314 //@{ 00315 /** \brief Swap vectors */ 00316 int swap(ovector_view_tlate<data_t,vparent_t,block_t> &x) { 00317 size_t t1, t2; 00318 double *t3; 00319 block_t *t4; 00320 int t5; 00321 00322 t1=vparent_t::size; 00323 t2=vparent_t::stride; 00324 t3=vparent_t::data; 00325 t4=vparent_t::block; 00326 t5=vparent_t::owner; 00327 00328 vparent_t::size=x.size; 00329 vparent_t::stride=x.stride; 00330 vparent_t::data=x.data; 00331 vparent_t::block=x.block; 00332 vparent_t::owner=x.owner; 00333 00334 x.size=t1; 00335 x.stride=t2; 00336 x.data=t3; 00337 x.block=t4; 00338 x.owner=t5; 00339 00340 return 0; 00341 } 00342 00343 /** 00344 \brief Return true if this object owns the data it refers to 00345 00346 This can be used to determine if an object is a "vector_view", 00347 or a legitmate "vector". If is_owner() is true, then it is 00348 an \ref ovector_tlate object. 00349 00350 If any O2scl class creates a \ref ovector_tlate object in 00351 which \ref is_owner() returns false, then it is a bug! 00352 */ 00353 bool is_owner() const { 00354 if (vparent_t::owner==1) return true; 00355 return false; 00356 } 00357 00358 /** \brief Exhaustively look through the array for a 00359 particular value 00360 00361 This can only fail if \em all of the entries in the array are 00362 not finite, in which case it calls set_err() and returns 00363 0. The error handler is reset at the beginning of lookup(). 00364 */ 00365 size_t lookup(const data_t x0) const { 00366 err_hnd->reset(); 00367 const ovector_view_tlate<data_t,vparent_t,block_t> *a=this; 00368 size_t row=0, i=0, nvar=size(); 00369 while(!finite((*a)[i]) && i<nvar-1) i++; 00370 if (i==nvar-1) { 00371 set_err("Array not finite in ovector_view_tlate::lookup()",1); 00372 return 0; 00373 } 00374 data_t best=(*a)[i], bdiff=fabs((*a)[i]-x0); 00375 for(;i<nvar;i++) { 00376 if (finite((*a)[i]) && fabs((*a)[i]-x0)<bdiff) { 00377 row=i; 00378 best=(*a)[i]; 00379 bdiff=fabs((*a)[i]-x0); 00380 } 00381 } 00382 return row; 00383 } 00384 00385 /** \brief Find the maximum element */ 00386 data_t max() const { 00387 data_t maxval=0; 00388 if (vparent_t::size>0) { 00389 bool setb=false; 00390 for(size_t i=0;i<vparent_t::size;i++) { 00391 double v=vparent_t::data[i]; 00392 if (finite(v)) { 00393 if (setb==false) { 00394 maxval=v; 00395 setb=true; 00396 } else if (v>maxval) { 00397 maxval=v; 00398 } 00399 } 00400 } 00401 if (setb==false) { 00402 set_err("No finite values in ovector_view_tlate::max().", 00403 gsl_efailed); 00404 return 0.0; 00405 } 00406 } else { 00407 return 0.0; 00408 } 00409 return maxval; 00410 } 00411 00412 /** \brief Find the location of the maximum element */ 00413 size_t max_index() const { 00414 data_t maxval; 00415 size_t loc; 00416 if (vparent_t::size>0) { 00417 bool setb=false; 00418 for(size_t i=0;i<vparent_t::size;i++) { 00419 double v=vparent_t::data[i]; 00420 if (finite(v)) { 00421 if (setb==false) { 00422 maxval=v; 00423 loc=i; 00424 setb=true; 00425 } else if (v>maxval) { 00426 maxval=v; 00427 loc=i; 00428 } 00429 } 00430 } 00431 if (setb==false) { 00432 set_err("No finite values in ovector_view_tlate::max().", 00433 gsl_efailed); 00434 return 0; 00435 } 00436 } else { 00437 return 0; 00438 } 00439 return loc; 00440 } 00441 00442 /** \brief Find the minimum element */ 00443 data_t min() const { 00444 data_t minval=0; 00445 if (vparent_t::size>0) { 00446 bool setb=false; 00447 for(size_t i=0;i<vparent_t::size;i++) { 00448 double v=vparent_t::data[i]; 00449 if (finite(v)) { 00450 if (setb==false) { 00451 minval=v; 00452 setb=true; 00453 } else if (v<minval) { 00454 minval=v; 00455 } 00456 } 00457 } 00458 if (setb==false) { 00459 set_err("No finite values in ovector_view_tlate::min().", 00460 gsl_efailed); 00461 return 0.0; 00462 } 00463 } else { 00464 return 0.0; 00465 } 00466 return minval; 00467 } 00468 00469 /** \brief Find the location of the minimum element */ 00470 size_t min_index() const { 00471 data_t maxval; 00472 size_t loc; 00473 if (vparent_t::size>0) { 00474 bool setb=false; 00475 for(size_t i=0;i<vparent_t::size;i++) { 00476 double v=vparent_t::data[i]; 00477 if (finite(v)) { 00478 if (setb==false) { 00479 maxval=v; 00480 loc=i; 00481 setb=true; 00482 } else if (v<maxval) { 00483 maxval=v; 00484 loc=i; 00485 } 00486 } 00487 } 00488 if (setb==false) { 00489 set_err("No finite values in ovector_view_tlate::max().", 00490 gsl_efailed); 00491 return 0; 00492 } 00493 } else { 00494 return 0; 00495 } 00496 return loc; 00497 } 00498 00499 /** \brief Return a gsl vector */ 00500 vparent_t *get_gsl_vector() { return this; }; 00501 00502 /** \brief Return a \c const gsl vector */ 00503 const vparent_t *get_gsl_vector_const() const { return this; }; 00504 00505 //@} 00506 00507 #ifndef DOXYGEN_INTERNAL 00508 00509 protected: 00510 00511 /** \brief Empty constructor provided for use by 00512 ovector_tlate(const ovector_tlate &v) 00513 */ 00514 ovector_view_tlate() {}; 00515 00516 #endif 00517 00518 }; 00519 00520 /** 00521 \brief A vector with finite stride 00522 00523 00524 There are several global binary operators associated with 00525 objects of type \ref uvector_tlate. The are documented in the 00526 "Functions" section of \ref ovector_tlate.h. 00527 */ 00528 template<class data_t, class vparent_t, class block_t> 00529 class ovector_tlate : 00530 public ovector_view_tlate<data_t,vparent_t,block_t> { 00531 public: 00532 00533 /// \name Standard constructor 00534 //@{ 00535 /** \brief Create an ovector of size \c n with owner as 'true' */ 00536 ovector_tlate(size_t n=0) { 00537 00538 vparent_t::data=0; 00539 vparent_t::size=0; 00540 vparent_t::stride=0; 00541 vparent_t::owner=0; 00542 vparent_t::block=0; 00543 00544 // This must be set to 1 even if n=0 so that future calls to 00545 // operator= (and other functions) work properly 00546 vparent_t::owner=1; 00547 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(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 } else { 00558 std::free(vparent_t::block); 00559 set_err("No memory for data in ovector constructor", 00560 gsl_enomem); 00561 } 00562 } else { 00563 set_err("No memory for block in ovector contructor", 00564 gsl_enomem); 00565 } 00566 } 00567 } 00568 //@} 00569 00570 /// \name Copy constructors 00571 //@{ 00572 /// Deep copy constructor, allocate new space and make a copy 00573 ovector_tlate(const ovector_tlate &v) : 00574 ovector_view_tlate<data_t,vparent_t,block_t>() { 00575 00576 vparent_t::data=0; 00577 vparent_t::size=0; 00578 vparent_t::stride=0; 00579 vparent_t::owner=0; 00580 vparent_t::block=0; 00581 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(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[i*vparent_t::stride]=v[i]; 00595 } 00596 } else { 00597 std::free(vparent_t::block); 00598 set_err("No memory for data in ovector constructor", 00599 gsl_enomem); 00600 } 00601 } else { 00602 set_err("No memory for block in ovector contructor", 00603 gsl_enomem); 00604 } 00605 } else { 00606 vparent_t::size=0; 00607 vparent_t::stride=0; 00608 } 00609 00610 } 00611 00612 #ifdef O2SCL_NEVER_DEFINED 00613 } 00614 { 00615 #endif 00616 00617 /// Deep copy constructor, allocate new space and make a copy 00618 ovector_tlate(const ovector_view_tlate<data_t,vparent_t,block_t> &v) : 00619 ovector_view_tlate<data_t,vparent_t,block_t>() { 00620 00621 vparent_t::data=0; 00622 vparent_t::size=0; 00623 vparent_t::stride=0; 00624 vparent_t::owner=0; 00625 vparent_t::block=0; 00626 00627 size_t n=v.size(); 00628 if (n>0) { 00629 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00630 if (vparent_t::block) { 00631 vparent_t::block->data=(data_t *)malloc(n*sizeof(data_t)); 00632 if (vparent_t::block->data) { 00633 vparent_t::block->size=n; 00634 vparent_t::data=vparent_t::block->data; 00635 vparent_t::size=n; 00636 vparent_t::stride=1; 00637 vparent_t::owner=1; 00638 for(size_t i=0;i<n;i++) { 00639 vparent_t::data[i*vparent_t::stride]=v[i]; 00640 } 00641 } else { 00642 std::free(vparent_t::block); 00643 set_err("No memory for data in ovector constructor", 00644 gsl_enomem); 00645 } 00646 } else { 00647 set_err("No memory for block in ovector contructor", 00648 gsl_enomem); 00649 } 00650 } else { 00651 vparent_t::size=0; 00652 vparent_t::stride=0; 00653 } 00654 00655 } 00656 00657 #ifdef O2SCL_NEVER_DEFINED 00658 } 00659 { 00660 #endif 00661 00662 /// Deep copy constructor, allocate new space and make a copy 00663 ovector_tlate(const uvector_view_tlate<data_t> &v) : 00664 ovector_view_tlate<data_t,vparent_t,block_t>() { 00665 00666 vparent_t::data=0; 00667 vparent_t::size=0; 00668 vparent_t::stride=0; 00669 00670 size_t n=v.size(); 00671 00672 if (n>0) { 00673 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00674 if (vparent_t::block) { 00675 vparent_t::block->data=(data_t *)malloc(n*sizeof(data_t)); 00676 if (vparent_t::block->data) { 00677 vparent_t::block->size=n; 00678 vparent_t::data=vparent_t::block->data; 00679 vparent_t::size=n; 00680 vparent_t::stride=1; 00681 vparent_t::owner=1; 00682 for(size_t i=0;i<n;i++) { 00683 vparent_t::data[i*vparent_t::stride]=v[i]; 00684 } 00685 } else { 00686 std::free(vparent_t::block); 00687 set_err("No memory for data in ovector constructor", 00688 gsl_enomem); 00689 } 00690 } else { 00691 set_err("No memory for block in ovector contructor", 00692 gsl_enomem); 00693 } 00694 } else { 00695 vparent_t::size=0; 00696 vparent_t::stride=0; 00697 } 00698 00699 } 00700 00701 #ifdef O2SCL_NEVER_DEFINED 00702 } 00703 { 00704 #endif 00705 00706 /** \brief Deep copy constructor, if owner is true, allocate 00707 space and make a new copy, otherwise, just copy into the 00708 view 00709 */ 00710 ovector_tlate& operator=(const ovector_tlate &v) { 00711 00712 size_t size2=v.size(); 00713 if (this->owner) { 00714 allocate(size2); 00715 } else { 00716 if (this->size()!=size2) { 00717 set_err("Sizes don't match in ovector::operator=(ovector)", 00718 gsl_ebadlen); 00719 return *this; 00720 } 00721 } 00722 for(size_t i=0;i<size2;i++) { 00723 vparent_t::data[i*vparent_t::stride]=v[i]; 00724 } 00725 00726 return *this; 00727 } 00728 00729 /** \brief Deep copy constructor, if owner is true, allocate 00730 space and make a new copy, otherwise, just copy into the 00731 view 00732 */ 00733 ovector_tlate& operator= 00734 (const ovector_view_tlate<data_t,vparent_t,block_t> &v) { 00735 00736 size_t size2=v.size(); 00737 if (this->owner) { 00738 allocate(size2); 00739 } else { 00740 if (this->size()!=size2) { 00741 set_err 00742 ("Sizes don't match in ovector::operator=(ovector_view)", 00743 gsl_ebadlen); 00744 return *this; 00745 } 00746 } 00747 for(size_t i=0;i<size2;i++) { 00748 vparent_t::data[i*vparent_t::stride]=v[i]; 00749 } 00750 00751 return *this; 00752 } 00753 00754 /** \brief Deep copy constructor, if owner is true, allocate 00755 space and make a new copy, otherwise, just copy into the 00756 view 00757 */ 00758 ovector_tlate& operator= 00759 (const uvector_view_tlate<data_t> &v) { 00760 00761 size_t size2=v.size(); 00762 if (this->owner) { 00763 allocate(size2); 00764 } else { 00765 if (this->size()!=size2) { 00766 set_err 00767 ("Sizes don't match in ovector::operator=(uvector_view)", 00768 gsl_ebadlen); 00769 return *this; 00770 } 00771 } 00772 for(size_t i=0;i<size2;i++) { 00773 vparent_t::data[i*vparent_t::stride]=v[i]; 00774 } 00775 00776 return *this; 00777 } 00778 //@} 00779 00780 ~ovector_tlate() { 00781 if (vparent_t::size>0) { 00782 if (vparent_t::owner==1) { 00783 if (vparent_t::block->size>0) { 00784 std::free(vparent_t::block->data); 00785 } 00786 std::free(vparent_t::block); 00787 vparent_t::size=0; 00788 } 00789 } 00790 } 00791 00792 /// \name Memory allocation 00793 //@{ 00794 /** 00795 \brief Allocate memory for size \c n after freeing any memory 00796 presently in use 00797 */ 00798 int allocate(size_t nsize) { 00799 if (vparent_t::size>0) free(); 00800 00801 if (nsize>0) { 00802 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00803 if (vparent_t::block) { 00804 vparent_t::block->data=(data_t *)malloc(nsize*sizeof(data_t)); 00805 if (vparent_t::block->data) { 00806 vparent_t::block->size=nsize; 00807 vparent_t::data=vparent_t::block->data; 00808 vparent_t::size=nsize; 00809 vparent_t::stride=1; 00810 vparent_t::owner=1; 00811 } else { 00812 std::free(vparent_t::block); 00813 set_err_ret("No memory for data in ovector::allocate()", 00814 gsl_enomem); 00815 } 00816 } else { 00817 set_err_ret("No memory for block in ovector::allocate()", 00818 gsl_enomem); 00819 } 00820 } else { 00821 set_err_ret("Zero size in ovector::allocate()",gsl_einval); 00822 } 00823 return 0; 00824 } 00825 00826 /** 00827 \brief Free the memory 00828 00829 This function will safely do nothing if used without first 00830 allocating memory or if called multiple times in succession. 00831 */ 00832 int free() { 00833 if (vparent_t::size>0) { 00834 if (vparent_t::owner==1) { 00835 if (vparent_t::block->size>0) { 00836 std::free(vparent_t::block->data); 00837 } 00838 std::free(vparent_t::block); 00839 } 00840 vparent_t::size=0; 00841 vparent_t::stride=0; 00842 } 00843 return 0; 00844 } 00845 //@} 00846 00847 /// \name Stack-like operations (very experimental) 00848 //@{ 00849 00850 /// Add a value to the end of the vector 00851 int push_back(data_t val) { 00852 00853 if (vparent_t::owner==0) { 00854 00855 set_err_ret 00856 ("Cannot push on a vector view in ovector::push_back().", 00857 gsl_einval); 00858 00859 } else { 00860 00861 if (vparent_t::size==0) { 00862 00863 // Empty, so make a 1-element vector 00864 allocate(1); 00865 vparent_t::data[0]=val; 00866 00867 } else if (vparent_t::block->size==vparent_t::size) { 00868 00869 // Allocate new memory in vparent_t::block 00870 vparent_t::block->data=(data_t *)malloc 00871 (2*vparent_t::block->size*sizeof(data_t)); 00872 vparent_t::block->size*=2; 00873 00874 // Copy the data to the new memory 00875 for(size_t i=0;i<vparent_t::size;i++) { 00876 vparent_t::block->data[i]=vparent_t::data[i]; 00877 } 00878 00879 // Delete the old memory 00880 std::free(vparent_t::data); 00881 00882 // Reset data to the new memory 00883 vparent_t::data=vparent_t::block->data; 00884 00885 // Add the new value to the end of the array and 00886 // increment size 00887 vparent_t::block->data[vparent_t::size]=val; 00888 vparent_t::size++; 00889 00890 } else { 00891 00892 // Add the new value to the end of the array and 00893 // increment size 00894 vparent_t::block->data[vparent_t::size]=val; 00895 vparent_t::size++; 00896 00897 } 00898 00899 } 00900 00901 return 0; 00902 } 00903 00904 /** 00905 \brief Reserve memory by increasing capacity 00906 00907 Increase the maximum capacity of the vector so that calls 00908 to push_back() do not need to automatically increase the 00909 capacity. 00910 00911 This function quietly does nothing if \c cap is smaller than 00912 the present vector size given by \ref size(). 00913 */ 00914 int reserve(size_t cap) { 00915 00916 if (vparent_t::owner==0) { 00917 00918 set_err_ret 00919 ("Can't reserve on a vector view in ovector::reserve().", 00920 gsl_einval); 00921 00922 } else { 00923 00924 // Do nothing if we are reserving memory for less than the 00925 // current size 00926 00927 if (cap>vparent_t::size) { 00928 00929 // If it's empty, we need to allocate a block 00930 if (!vparent_t::block) { 00931 vparent_t::block=(block_t *)malloc(sizeof(block_t)); 00932 } 00933 00934 // Allocate new memory in vparent_t::block 00935 vparent_t::block->data=(data_t *)malloc(cap*sizeof(data_t)); 00936 vparent_t::block->size=cap; 00937 00938 // Copy the data to the new memory 00939 for(size_t i=0;i<vparent_t::size;i++) { 00940 vparent_t::block->data[i]=vparent_t::data[i]; 00941 } 00942 00943 // Delete the old memory 00944 std::free(vparent_t::data); 00945 00946 // Reset data to the new memory 00947 vparent_t::data=vparent_t::block->data; 00948 } 00949 } 00950 return 0; 00951 } 00952 00953 /// Return the last value and shrink the vector size by one 00954 data_t pop() { 00955 if (vparent_t::owner==0) { 00956 set_err("Cannot pop() on a vector view in ovector::pop().", 00957 gsl_einval); 00958 return 0.0; 00959 } else if (vparent_t::size==0) { 00960 set_err("Attempted to pop an empty vector in ovector::pop().", 00961 gsl_einval); 00962 return 0.0; 00963 } 00964 vparent_t::size--; 00965 return vparent_t::data[vparent_t::size]; 00966 } 00967 //@} 00968 00969 /// \name Other methods 00970 //@{ 00971 int erase(size_t ix) { 00972 if (vparent_t::owner==0) { 00973 set_err_ret("Vector view sent to ovector::erase().", 00974 gsl_einval); 00975 } 00976 if (ix<vparent_t::size) { 00977 for(size_t i=ix+1;ix<vparent_t::size;i++) { 00978 vparent_t::data[ix-1]=vparent_t::data[ix]; 00979 } 00980 vparent_t::size--; 00981 } else { 00982 set_err_ret("Tried to erase() past end in ovector::erase().", 00983 gsl_einval); 00984 } 00985 } 00986 //@} 00987 00988 }; 00989 00990 /** 00991 \brief Create a vector from an array 00992 00993 00994 */ 00995 template<class data_t, class vparent_t, class block_t> 00996 class ovector_array_tlate : 00997 public ovector_view_tlate<data_t,vparent_t,block_t> { 00998 public: 00999 /** \brief Create a vector from \c dat with size \c n */ 01000 ovector_array_tlate(size_t n, data_t *dat) { 01001 if (n>0) { 01002 vparent_t::block=NULL; 01003 vparent_t::data=dat; 01004 vparent_t::size=n; 01005 vparent_t::stride=1; 01006 vparent_t::owner=0; 01007 } 01008 } 01009 }; 01010 01011 /** 01012 \brief Create a vector from an array with a stride 01013 01014 01015 */ 01016 template<class data_t, class vparent_t, class block_t> 01017 class ovector_array_stride_tlate : 01018 public ovector_view_tlate<data_t,vparent_t,block_t> { 01019 public: 01020 /** \brief Create a vector from \c dat with size \c n and stride \c s 01021 */ 01022 ovector_array_stride_tlate(size_t n, data_t *dat, size_t s) { 01023 if (n>0) { 01024 vparent_t::block=NULL; 01025 vparent_t::data=dat; 01026 vparent_t::size=n; 01027 vparent_t::stride=s; 01028 vparent_t::owner=0; 01029 } 01030 } 01031 }; 01032 01033 /** 01034 \brief Create a vector from a subvector of another 01035 01036 01037 */ 01038 template<class data_t, class vparent_t, class block_t> 01039 class ovector_subvector_tlate : 01040 public ovector_view_tlate<data_t,vparent_t,block_t> { 01041 public: 01042 /** \brief Create a vector from \c orig */ 01043 ovector_subvector_tlate 01044 (ovector_view_tlate<data_t,vparent_t,block_t> &orig, 01045 size_t offset, size_t n) { 01046 if (offset+n-1<orig.size()) { 01047 vparent_t::block=NULL; 01048 vparent_t::data=orig.data+offset*orig.stride(); 01049 vparent_t::size=n; 01050 vparent_t::stride=orig.stride(); 01051 vparent_t::owner=0; 01052 } else { 01053 vparent_t::size=0; 01054 set_err("Subvector failed in ovector_subvector() constructor.", 01055 gsl_efailed); 01056 } 01057 } 01058 }; 01059 01060 /** 01061 \brief Create a const vector from an array 01062 01063 01064 */ 01065 template<class data_t, class vparent_t, class block_t> 01066 class ovector_const_array_tlate : 01067 public ovector_view_tlate<data_t,vparent_t,block_t> { 01068 public: 01069 /** \brief Create a vector from \c dat with size \c n */ 01070 ovector_const_array_tlate(size_t n, const data_t *dat) { 01071 if (n>0) { 01072 vparent_t::block=NULL; 01073 // We have to do an explicit cast here, but we prevent the 01074 // user from changing the data. 01075 vparent_t::data=(data_t *)dat; 01076 vparent_t::size=n; 01077 vparent_t::stride=1; 01078 vparent_t::owner=0; 01079 } 01080 } 01081 01082 ~ovector_const_array_tlate() {}; 01083 01084 #ifndef DOXYGEN_INTERNAL 01085 01086 protected: 01087 01088 /** \name Ensure \c const by hiding non-const members 01089 */ 01090 //@{ 01091 data_t &operator[](size_t i) { return vparent_t::data[0]; } 01092 data_t &operator()(size_t i) { return vparent_t::data[0]; } 01093 data_t *get_ptr(size_t i) { return NULL; } 01094 int set(size_t i, data_t val) { return 0; } 01095 int swap(ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01096 return 0; 01097 } 01098 int set_all(double val) { return 0; } 01099 vparent_t *get_gsl_vector() { return NULL; } 01100 ovector_view_tlate<data_t,vparent_t,block_t> &operator+= 01101 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01102 return *this; 01103 } 01104 ovector_view_tlate<data_t,vparent_t,block_t> &operator-= 01105 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01106 return *this; 01107 } 01108 ovector_view_tlate<data_t,vparent_t,block_t> &operator*=(const data_t &y) { 01109 return *this; 01110 } 01111 //@} 01112 01113 #endif 01114 01115 }; 01116 01117 /** 01118 \brief Create a const vector from an array with a stride 01119 01120 01121 */ 01122 template<class data_t, class vparent_t, class block_t> 01123 class ovector_const_array_stride_tlate : 01124 public ovector_view_tlate<data_t,vparent_t,block_t> { 01125 public: 01126 /** \brief Create a vector from \c dat with size \c n */ 01127 ovector_const_array_stride_tlate(size_t n, const data_t *dat, size_t s) { 01128 if (n>0) { 01129 vparent_t::block=NULL; 01130 // We have to do an explicit cast here, but we prevent the 01131 // user from changing the data. 01132 vparent_t::data=(data_t *)dat; 01133 vparent_t::size=n; 01134 vparent_t::stride=s; 01135 vparent_t::owner=0; 01136 } 01137 } 01138 01139 #ifndef DOXYGEN_INTERNAL 01140 01141 protected: 01142 01143 /** \name Ensure \c const by hiding non-const members 01144 */ 01145 //@{ 01146 data_t &operator[](size_t i) { return vparent_t::data[0]; } 01147 data_t &operator()(size_t i) { return vparent_t::data[0]; } 01148 data_t *get_ptr(size_t i) { return NULL; } 01149 int set(size_t i, data_t val) { return 0; } 01150 int swap(ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01151 return 0; 01152 } 01153 int set_all(double val) { return 0; } 01154 vparent_t *get_gsl_vector() { return NULL; } 01155 ovector_view_tlate<data_t,vparent_t,block_t> &operator+= 01156 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01157 return *this; 01158 } 01159 ovector_view_tlate<data_t,vparent_t,block_t> &operator-= 01160 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01161 return *this; 01162 } 01163 ovector_view_tlate<data_t,vparent_t,block_t> &operator*=(const data_t &y) { 01164 return *this; 01165 } 01166 //@} 01167 01168 #endif 01169 01170 }; 01171 01172 /** 01173 \brief Create a const vector from a subvector of another vector 01174 01175 01176 */ 01177 template<class data_t, class vparent_t, class block_t> 01178 class ovector_const_subvector_tlate : 01179 public ovector_view_tlate<data_t,vparent_t,block_t> { 01180 public: 01181 /** \brief Create a vector from \c orig 01182 */ 01183 ovector_const_subvector_tlate 01184 (const ovector_view_tlate<data_t,vparent_t,block_t> &orig, 01185 size_t offset, size_t n) { 01186 if (offset+n-1<orig.size()) { 01187 vparent_t::block=NULL; 01188 vparent_t::data=orig.data+offset*orig.stride(); 01189 vparent_t::size=n; 01190 vparent_t::stride=orig.stride(); 01191 vparent_t::owner=0; 01192 } else { 01193 vparent_t::block=0; 01194 vparent_t::data=0; 01195 vparent_t::size=0; 01196 vparent_t::stride=0; 01197 vparent_t::owner=0; 01198 set_err("Failed in ovector_subvector() constructor.",gsl_efailed); 01199 } 01200 } 01201 01202 /** 01203 \brief Array-like indexing 01204 */ 01205 const data_t &operator[](size_t i) const { 01206 #if GSL_RANGE_CHECK 01207 if (i>=vparent_t::size) { 01208 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01209 +" in ovector_const_subvector_tlate::operator[]. Size: "+ 01210 itos(vparent_t::size)+ 01211 " (index should be less than size).").c_str(),gsl_index); 01212 } 01213 #endif 01214 return vparent_t::data[i*vparent_t::stride]; 01215 } 01216 01217 #ifndef DOXYGEN_INTERNAL 01218 01219 protected: 01220 01221 /** \name Ensure \c const by hiding non-const members 01222 */ 01223 //@{ 01224 data_t &operator[](size_t i) { return vparent_t::data[0]; } 01225 data_t &operator()(size_t i) { return vparent_t::data[0]; } 01226 data_t *get_ptr(size_t i) { return NULL; } 01227 int set(size_t i, data_t val) { return 0; } 01228 int swap(ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01229 return 0; 01230 } 01231 int set_all(double val) { return 0; } 01232 vparent_t *get_gsl_vector() { return NULL; } 01233 ovector_view_tlate<data_t,vparent_t,block_t> &operator+= 01234 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01235 return *this; 01236 } 01237 ovector_view_tlate<data_t,vparent_t,block_t> &operator-= 01238 (const ovector_view_tlate<data_t,vparent_t,block_t> &x) { 01239 return *this; 01240 } 01241 ovector_view_tlate<data_t,vparent_t,block_t> &operator*=(const data_t &y) { 01242 return *this; 01243 } 01244 //@} 01245 01246 #endif 01247 01248 }; 01249 01250 /** 01251 \brief Reversed view of a vector 01252 01253 01254 01255 Note that you cannot reverse a reversed vector and expect to get 01256 the original vector back. 01257 */ 01258 template<class data_t, class vparent_t, class block_t> 01259 class ovector_reverse_tlate : 01260 public ovector_view_tlate<data_t,vparent_t,block_t> { 01261 public: 01262 /** \brief Create a vector from \c dat with size \c n and stride \c s 01263 */ 01264 ovector_reverse_tlate(ovector_view_tlate<data_t,vparent_t,block_t> &v) { 01265 vparent_t::block=v.block; 01266 vparent_t::data=v.data; 01267 vparent_t::size=v.size(); 01268 vparent_t::stride=v.stride(); 01269 vparent_t::owner=0; 01270 } 01271 01272 /// \name Get and set methods 01273 //@{ 01274 /** 01275 \brief Array-like indexing 01276 */ 01277 data_t &operator[](size_t i) { 01278 #if GSL_RANGE_CHECK 01279 if (i>=vparent_t::size) { 01280 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01281 +" in ovector_reverse_tlate::operator[]. Size: "+ 01282 itos(vparent_t::size)+ 01283 " (index should be less than size).").c_str(),gsl_index); 01284 return vparent_t::data[0]; 01285 } 01286 #endif 01287 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01288 } 01289 01290 /** 01291 \brief Array-like indexing 01292 */ 01293 const data_t &operator[](size_t i) const { 01294 #if GSL_RANGE_CHECK 01295 if (i>=vparent_t::size) { 01296 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01297 +" in ovector_reverse_tlate::operator[]. Size: "+ 01298 itos(vparent_t::size)+ 01299 " (index should be less than size).").c_str(),gsl_index); 01300 return vparent_t::data[0]; 01301 } 01302 #endif 01303 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01304 } 01305 01306 /** 01307 \brief Array-like indexing 01308 */ 01309 data_t &operator()(size_t i) { 01310 #if GSL_RANGE_CHECK 01311 if (i>=vparent_t::size) { 01312 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01313 +" in ovector_reverse_tlate::operator(). Size: "+ 01314 itos(vparent_t::size)+ 01315 " (index should be less than size).").c_str(),gsl_index); 01316 return vparent_t::data[0]; 01317 } 01318 #endif 01319 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01320 } 01321 01322 /** 01323 \brief Array-like indexing 01324 */ 01325 const data_t &operator()(size_t i) const { 01326 #if GSL_RANGE_CHECK 01327 if (i>=vparent_t::size) { 01328 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01329 +" in ovector_reverse_tlate::operator(). Size: "+ 01330 itos(vparent_t::size)+ 01331 " (index should be less than size).").c_str(),gsl_index); 01332 return vparent_t::data[0]; 01333 } 01334 #endif 01335 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01336 } 01337 01338 /** \brief Get (with optional range-checking) */ 01339 data_t get(size_t i) const { 01340 #if GSL_RANGE_CHECK 01341 if (i>=vparent_t::size) { 01342 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01343 +" in ovector_reverse_tlate::get(). Size: "+ 01344 itos(vparent_t::size)+ 01345 " (index should be less than size).").c_str(),gsl_index); 01346 return vparent_t::data[0]; 01347 } 01348 #endif 01349 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01350 } 01351 01352 /** \brief Get pointer (with optional range-checking) */ 01353 data_t *get_ptr(size_t i) { 01354 #if GSL_RANGE_CHECK 01355 if (i>=vparent_t::size) { 01356 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01357 +" in ovector_reverse_tlate::get_ptr(). Size: "+ 01358 itos(vparent_t::size)+ 01359 " (index should be less than size).").c_str(),gsl_index); 01360 return vparent_t::data; 01361 } 01362 #endif 01363 return vparent_t::data+(vparent_t::size-1-i)*vparent_t::stride; 01364 } 01365 01366 /** \brief Get pointer (with optional range-checking) */ 01367 const data_t *get_const_ptr(size_t i) const { 01368 #if GSL_RANGE_CHECK 01369 if (i>=vparent_t::size) { 01370 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01371 +" in ovector_reverse_tlate::get_const_ptr(). Size: "+ 01372 itos(vparent_t::size)+ 01373 " (index should be less than size).").c_str(),gsl_index); 01374 return (const data_t *)vparent_t::data; 01375 } 01376 #endif 01377 return (const data_t *)(vparent_t::data+ 01378 (vparent_t::size-1-i)*vparent_t::stride); 01379 } 01380 01381 /** \brief Set (with optional range-checking) */ 01382 int set(size_t i, data_t val) { 01383 #if GSL_RANGE_CHECK 01384 if (i>=vparent_t::size) { 01385 set_err_ret((((std::string)"Array index ")+itos(i)+" out of bounds" 01386 +" in ovector_reverse_tlate::set(). Size: "+ 01387 itos(vparent_t::size)+ 01388 " (index should be less than size).").c_str(),gsl_index); 01389 } 01390 #endif 01391 vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]=val; 01392 return 0; 01393 } 01394 01395 /** \brief Set all of the value to be the value \c val */ 01396 int set_all(double val) { 01397 for(size_t i=0;i<vparent_t::size;i++) { 01398 vparent_t::data[i*vparent_t::stride]=val; 01399 } 01400 return 0; 01401 } 01402 01403 }; 01404 01405 /** 01406 \brief Reversed view of a vector 01407 01408 01409 */ 01410 template<class data_t, class vparent_t, class block_t> 01411 class ovector_const_reverse_tlate : 01412 public ovector_view_tlate<data_t,vparent_t,block_t> { 01413 public: 01414 /** \brief Create a vector from \c dat with size \c n and stride \c s 01415 */ 01416 ovector_const_reverse_tlate 01417 (const ovector_view_tlate<data_t,vparent_t,block_t> &v) { 01418 vparent_t::block=v.block; 01419 vparent_t::data=v.data; 01420 vparent_t::size=v.size(); 01421 vparent_t::stride=v.stride(); 01422 vparent_t::owner=0; 01423 } 01424 01425 /// \name Get and set methods 01426 //@{ 01427 /** 01428 \brief Array-like indexing 01429 */ 01430 /** 01431 \brief Array-like indexing 01432 */ 01433 const data_t &operator[](size_t i) const { 01434 #if GSL_RANGE_CHECK 01435 if (i>=vparent_t::size) { 01436 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01437 +" in ovector_const_reverse_tlate::operator[]. Size: "+ 01438 itos(vparent_t::size)+ 01439 " (index should be less than size).").c_str(),gsl_index); 01440 return vparent_t::data[0]; 01441 } 01442 #endif 01443 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01444 } 01445 01446 /** 01447 \brief Array-like indexing 01448 */ 01449 const data_t &operator()(size_t i) const { 01450 #if GSL_RANGE_CHECK 01451 if (i>=vparent_t::size) { 01452 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01453 +" in ovector_const_reverse_tlate::operator(). Size: "+ 01454 itos(vparent_t::size)+ 01455 " (index should be less than size).").c_str(),gsl_index); 01456 return vparent_t::data[0]; 01457 } 01458 #endif 01459 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01460 } 01461 01462 /** \brief Get (with optional range-checking) */ 01463 data_t get(size_t i) const { 01464 #if GSL_RANGE_CHECK 01465 if (i>=vparent_t::size) { 01466 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01467 +" in ovector_const_reverse_tlate::get(). Size: "+ 01468 itos(vparent_t::size)+ 01469 " (index should be less than size).").c_str(),gsl_index); 01470 return vparent_t::data[0]; 01471 } 01472 #endif 01473 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01474 } 01475 01476 /** \brief Get pointer (with optional range-checking) */ 01477 const data_t *get_const_ptr(size_t i) const { 01478 #if GSL_RANGE_CHECK 01479 if (i>=vparent_t::size) { 01480 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01481 +" in ovector_const_reverse_tlate::get_const_ptr(). Size: "+ 01482 itos(vparent_t::size)+ 01483 " (index should be less than size).").c_str(),gsl_index); 01484 return (const data_t *)vparent_t::data; 01485 } 01486 #endif 01487 return (const data_t *)(vparent_t::data+ 01488 (vparent_t::size-1-i)*vparent_t::stride); 01489 } 01490 01491 }; 01492 01493 /** 01494 \brief Reversed view of a subvector 01495 01496 01497 01498 Note that you cannot reverse a reversed vector and expect to get 01499 the original vector back. 01500 */ 01501 template<class data_t, class vparent_t, class block_t> 01502 class ovector_subvector_reverse_tlate : 01503 public ovector_view_tlate<data_t,vparent_t,block_t> { 01504 public: 01505 /** \brief Create a vector from \c dat with size \c n and stride \c s 01506 */ 01507 ovector_subvector_reverse_tlate 01508 (ovector_view_tlate<data_t,vparent_t,block_t> &v, size_t offset, 01509 size_t n) { 01510 vparent_t::data=0; 01511 vparent_t::size=0; 01512 vparent_t::stride=0; 01513 if (offset+n-1<v.size()) { 01514 vparent_t::block=NULL; 01515 vparent_t::data=v.data+offset*v.stride(); 01516 vparent_t::size=n; 01517 vparent_t::stride=v.stride(); 01518 vparent_t::owner=0; 01519 } else { 01520 set_err("Failed in ovector_sub_reverse() constructor.",gsl_einval); 01521 } 01522 } 01523 01524 /// \name Get and set methods 01525 //@{ 01526 /** 01527 \brief Array-like indexing 01528 */ 01529 data_t &operator[](size_t i) { 01530 #if GSL_RANGE_CHECK 01531 if (i>=vparent_t::size) { 01532 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01533 +" in ovector_subvector_reverse_tlate::operator[]. Size: "+ 01534 itos(vparent_t::size)+ 01535 " (index should be less than size).").c_str(),gsl_index); 01536 return vparent_t::data[0]; 01537 } 01538 #endif 01539 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01540 } 01541 01542 /** 01543 \brief Array-like indexing 01544 */ 01545 const data_t &operator[](size_t i) const { 01546 #if GSL_RANGE_CHECK 01547 if (i>=vparent_t::size) { 01548 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01549 +" in ovector_subvector_reverse_tlate::operator[]. Size: "+ 01550 itos(vparent_t::size)+ 01551 " (index should be less than size).").c_str(),gsl_index); 01552 return vparent_t::data[0]; 01553 } 01554 #endif 01555 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01556 } 01557 01558 /** 01559 \brief Array-like indexing 01560 */ 01561 data_t &operator()(size_t i) { 01562 #if GSL_RANGE_CHECK 01563 if (i>=vparent_t::size) { 01564 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01565 +" in ovector_subvector_reverse_tlate::operator(). Size: "+ 01566 itos(vparent_t::size)+ 01567 " (index should be less than size).").c_str(),gsl_index); 01568 return vparent_t::data[0]; 01569 } 01570 #endif 01571 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01572 } 01573 01574 /** 01575 \brief Array-like indexing 01576 */ 01577 const data_t &operator()(size_t i) const { 01578 #if GSL_RANGE_CHECK 01579 if (i>=vparent_t::size) { 01580 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01581 +" in ovector_subvector_reverse_tlate::operator(). Size: "+ 01582 itos(vparent_t::size)+ 01583 " (index should be less than size).").c_str(),gsl_index); 01584 return vparent_t::data[0]; 01585 } 01586 #endif 01587 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01588 } 01589 01590 /** \brief Get (with optional range-checking) */ 01591 data_t get(size_t i) const { 01592 #if GSL_RANGE_CHECK 01593 if (i>=vparent_t::size) { 01594 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01595 +" in ovector_subvector_reverse_tlate::get(). Size: "+ 01596 itos(vparent_t::size)+ 01597 " (index should be less than size).").c_str(),gsl_index); 01598 return vparent_t::data[0]; 01599 } 01600 #endif 01601 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01602 } 01603 01604 /** \brief Get pointer (with optional range-checking) */ 01605 data_t *get_ptr(size_t i) { 01606 #if GSL_RANGE_CHECK 01607 if (i>=vparent_t::size) { 01608 set_err((((std::string)"Array index ")+itos(i)+" out of bounds" 01609 +" in ovector_subvector_reverse_tlate::get_ptr(). Size: "+ 01610 itos(vparent_t::size)+ 01611 " (index should be less than size).").c_str(),gsl_index); 01612 return vparent_t::data; 01613 } 01614 #endif 01615 return vparent_t::data+(vparent_t::size-1-i)*vparent_t::stride; 01616 } 01617 01618 /** \brief Get pointer (with optional range-checking) */ 01619 const data_t *get_const_ptr(size_t i) const { 01620 #if GSL_RANGE_CHECK 01621 if (i>=vparent_t::size) { 01622 set_err((((std::string)"Array index ")+itos(i)+" out of bounds in " 01623 +"ovector_subvector_reverse_tlate::get_const_ptr(). Size: "+ 01624 itos(vparent_t::size)+ 01625 " (index should be less than size).").c_str(),gsl_index); 01626 return (const data_t *)vparent_t::data; 01627 } 01628 #endif 01629 return (const data_t *)(vparent_t::data+ 01630 (vparent_t::size-1-i)*vparent_t::stride); 01631 } 01632 01633 /** \brief Set (with optional range-checking) */ 01634 int set(size_t i, data_t val) { 01635 #if GSL_RANGE_CHECK 01636 if (i>=vparent_t::size) { 01637 set_err_ret((((std::string)"Array index ")+itos(i)+" out of bounds " 01638 +" in ovector_subvector_reverse_tlate::get_const_ptr(). "+ 01639 "Size: "+itos(vparent_t::size)+ 01640 " (index should be less than size).").c_str(),gsl_index); 01641 } 01642 #endif 01643 vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]=val; 01644 return 0; 01645 } 01646 01647 /** \brief Set all of the value to be the value \c val */ 01648 int set_all(double val) { 01649 for(size_t i=0;i<vparent_t::size;i++) { 01650 vparent_t::data[i*vparent_t::stride]=val; 01651 } 01652 return 0; 01653 } 01654 01655 }; 01656 01657 /** 01658 \brief Reversed view of a const subvector 01659 01660 01661 */ 01662 template<class data_t, class vparent_t, class block_t> 01663 class ovector_const_subvector_reverse_tlate : 01664 public ovector_view_tlate<data_t,vparent_t,block_t> { 01665 01666 public: 01667 01668 /** \brief Create a vector from \c dat with size \c n and stride \c s 01669 */ 01670 ovector_const_subvector_reverse_tlate 01671 (const ovector_view_tlate<data_t,vparent_t,block_t> &v, size_t offset, 01672 size_t n) { 01673 if (offset+n-1<v.size()) { 01674 vparent_t::block=NULL; 01675 vparent_t::data=v.data+offset*v.stride(); 01676 vparent_t::size=n; 01677 vparent_t::stride=v.stride(); 01678 vparent_t::owner=0; 01679 } else { 01680 set_err("Subvector failed in ovector_sub_reverse().",gsl_einval); 01681 } 01682 } 01683 01684 /// \name Get and set methods 01685 //@{ 01686 /** 01687 \brief Array-like indexing 01688 */ 01689 /** 01690 \brief Array-like indexing 01691 */ 01692 const data_t &operator[](size_t i) const { 01693 #if GSL_RANGE_CHECK 01694 if (i>=vparent_t::size) { 01695 set_err((((std::string)"Array index ")+itos(i)+" out of bounds"+ 01696 " in ovector_const_subvector_reverse_tlate::operator[]."+ 01697 " Size: "+itos(vparent_t::size)+ 01698 " (index should be less than size).").c_str(),gsl_index); 01699 return vparent_t::data[0]; 01700 } 01701 #endif 01702 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01703 } 01704 01705 /** 01706 \brief Array-like indexing 01707 */ 01708 const data_t &operator()(size_t i) const { 01709 #if GSL_RANGE_CHECK 01710 if (i>=vparent_t::size) { 01711 set_err((((std::string)"Array index ")+itos(i)+" out of bounds"+ 01712 " in ovector_const_subvector_reverse_tlate::operator()."+ 01713 " Size: "+itos(vparent_t::size)+ 01714 " (index should be less than size).").c_str(),gsl_index); 01715 return vparent_t::data[0]; 01716 } 01717 #endif 01718 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01719 } 01720 01721 /** \brief Get (with optional range-checking) */ 01722 data_t get(size_t i) const { 01723 #if GSL_RANGE_CHECK 01724 if (i>=vparent_t::size) { 01725 set_err((((std::string)"Array index ")+itos(i)+" out of bounds"+ 01726 " in ovector_const_subvector_reverse_tlate::get()."+ 01727 " Size: "+itos(vparent_t::size)+ 01728 " (index should be less than size).").c_str(),gsl_index); 01729 return vparent_t::data[0]; 01730 } 01731 #endif 01732 return vparent_t::data[(vparent_t::size-1-i)*vparent_t::stride]; 01733 } 01734 01735 /** \brief Get pointer (with optional range-checking) */ 01736 const data_t *get_const_ptr(size_t i) const { 01737 #if GSL_RANGE_CHECK 01738 if (i>=vparent_t::size) { 01739 set_err((((std::string)"Array index ")+itos(i)+" out of bounds"+ 01740 " in ovector_const_subvector_reverse_tlate::get_const_ptr()."+ 01741 " Size: "+itos(vparent_t::size)+ 01742 " (index should be less than size).").c_str(),gsl_index); 01743 return (const data_t *)vparent_t::data; 01744 } 01745 #endif 01746 return (const data_t *)(vparent_t::data+ 01747 (vparent_t::size-1-i)*vparent_t::stride); 01748 } 01749 01750 }; 01751 01752 /// ovector typedef 01753 typedef ovector_tlate<double,gsl_vector,gsl_block> ovector; 01754 /// ovector_view typedef 01755 #ifdef DOXYGENP 01756 typedef ovector_view_tlate<data_t,vparent_t,block_t> ovector_view; 01757 #else 01758 typedef ovector_view_tlate<double,gsl_vector,gsl_block> ovector_view; 01759 #endif 01760 /// ovector_array typedef 01761 typedef ovector_array_tlate<double,gsl_vector,gsl_block> ovector_array; 01762 /// ovector_array_stride typedef 01763 typedef ovector_array_stride_tlate<double,gsl_vector,gsl_block> 01764 ovector_array_stride; 01765 /// ovector_subvector typedef 01766 typedef ovector_subvector_tlate<double,gsl_vector,gsl_block> 01767 ovector_subvector; 01768 /// ovector_const_array typedef 01769 typedef ovector_const_array_tlate<double,gsl_vector,gsl_block> 01770 ovector_const_array; 01771 /// ovector_const_array_stride typedef 01772 typedef ovector_const_array_stride_tlate<double,gsl_vector,gsl_block> 01773 ovector_const_array_stride; 01774 /// ovector_const_subvector typedef 01775 typedef ovector_const_subvector_tlate<double,gsl_vector,gsl_block> 01776 ovector_const_subvector; 01777 /// ovector_reverse typedef 01778 typedef ovector_reverse_tlate<double,gsl_vector,gsl_block> 01779 ovector_reverse; 01780 /// ovector_const_reverse typedef 01781 typedef ovector_const_reverse_tlate<double,gsl_vector,gsl_block> 01782 ovector_const_reverse; 01783 /// ovector_subvector_reverse typedef 01784 typedef ovector_subvector_reverse_tlate<double,gsl_vector,gsl_block> 01785 ovector_subvector_reverse; 01786 /// ovector_const_subvector_reverse typedef 01787 typedef ovector_const_subvector_reverse_tlate<double,gsl_vector,gsl_block> 01788 ovector_const_subvector_reverse; 01789 01790 /// ovector_int typedef 01791 typedef ovector_tlate<int,gsl_vector_int,gsl_block_int> ovector_int; 01792 /// ovector_int_view typedef 01793 typedef ovector_view_tlate<int,gsl_vector_int,gsl_block_int> 01794 ovector_int_view; 01795 /// ovector_int_array typedef 01796 typedef ovector_array_tlate<int,gsl_vector_int,gsl_block_int> 01797 ovector_int_array; 01798 /// ovector_int_array_stride typedef 01799 typedef ovector_array_stride_tlate<int,gsl_vector_int,gsl_block_int> 01800 ovector_int_array_stride; 01801 /// ovector_int_subvector typedef 01802 typedef ovector_subvector_tlate<int,gsl_vector_int,gsl_block_int> 01803 ovector_int_subvector; 01804 /// ovector_int_const_array typedef 01805 typedef ovector_const_array_tlate<int,gsl_vector_int,gsl_block_int> 01806 ovector_int_const_array; 01807 /// ovector_int_const_array_stride typedef 01808 typedef ovector_const_array_stride_tlate<int,gsl_vector_int,gsl_block_int> 01809 ovector_int_const_array_stride; 01810 /// ovector_int_const_subvector typedef 01811 typedef ovector_const_subvector_tlate<int,gsl_vector_int,gsl_block_int> 01812 ovector_int_const_subvector; 01813 /// ovector_int_reverse typedef 01814 typedef ovector_reverse_tlate<int,gsl_vector_int,gsl_block_int> 01815 ovector_int_reverse; 01816 /// ovector_int_const_reverse typedef 01817 typedef ovector_const_reverse_tlate<int,gsl_vector_int,gsl_block_int> 01818 ovector_int_const_reverse; 01819 /// ovector_int_subvector_reverse typedef 01820 typedef ovector_subvector_reverse_tlate<int,gsl_vector_int,gsl_block_int> 01821 ovector_int_subvector_reverse; 01822 /// ovector_int_const_subvector_reverse typedef 01823 typedef ovector_const_subvector_reverse_tlate<int,gsl_vector_int, 01824 gsl_block_int> ovector_int_const_subvector_reverse; 01825 01826 /** 01827 \brief A operator for naive vector output 01828 01829 This outputs all of the vector elements. All of these are 01830 separated by one space character, though no trailing space or \c 01831 endl is sent to the output. 01832 */ 01833 template<class data_t, class vparent_t, class block_t> 01834 std::ostream &operator<< 01835 (std::ostream &os, 01836 const ovector_view_tlate<data_t,vparent_t,block_t> &v) { 01837 for(size_t i=0;i<v.size()-1;i++) { 01838 os << v[i] << ' '; 01839 } 01840 os << v[v.size()-1]; 01841 return os; 01842 } 01843 01844 /** \brief A simple class to provide an \c allocate() function 01845 for \ref ovector 01846 01847 01848 */ 01849 class ovector_alloc { 01850 public: 01851 /// Allocate \c v for \c i elements 01852 void allocate(ovector &o, int i) { o.allocate(i); } 01853 /// Free memory 01854 void free(ovector &o) { o.free(); } 01855 }; 01856 01857 /** \brief A simple class to provide an \c allocate() function 01858 for \ref ovector_int 01859 */ 01860 class ovector_int_alloc { 01861 public: 01862 /// Allocate \c v for \c i elements 01863 void allocate(ovector_int &o, int i) { o.allocate(i); } 01864 /// Free memory 01865 void free(ovector_int &o) { o.free(); } 01866 }; 01867 01868 /** \brief A vector where the memory allocation is performed in 01869 the constructor 01870 01871 01872 */ 01873 #ifdef DOXYGENP 01874 template<size_t N=0> class ofvector : 01875 public ovector_tlate<data_t,vparent_t,block_t> 01876 #else 01877 template<size_t N=0> class ofvector : 01878 public ovector_tlate<double,gsl_vector,gsl_block> 01879 #endif 01880 { 01881 public: 01882 ofvector() : ovector_tlate<double,gsl_vector,gsl_block>(N) { 01883 } 01884 }; 01885 01886 #ifndef DOXYGENP 01887 } 01888 #endif 01889 01890 #endif 01891
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