ovector_tlate.h

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

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page