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