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