ovector_tlate.h

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

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

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