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

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

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