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