omatrix_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_OMATRIX_TLATE_H
00024 #define O2SCL_OMATRIX_TLATE_H
00025 
00026 /** \file omatrix_tlate.h
00027     \brief File for definitions of matrices
00028 */
00029 
00030 #include <iostream>
00031 #include <cstdlib>
00032 #include <string>
00033 #include <fstream>
00034 #include <sstream>
00035 
00036 #include <gsl/gsl_matrix.h>
00037 #include <gsl/gsl_ieee_utils.h>
00038 
00039 #include <o2scl/err_hnd.h>
00040 #include <o2scl/ovector_tlate.h>
00041 
00042 #ifndef DOXYGENP
00043 namespace o2scl {
00044 #endif
00045 
00046   /** 
00047       \brief A matrix view of double-precision numbers
00048 
00049       \todo This class isn't sufficiently general for some applications,
00050       such as sub-matrices of higher-dimensional structures. It might
00051       be nice to create a more general class with a "stride" and a "tda". 
00052   */
00053   template<class data_t, class mparent_t, class block_t> 
00054     class omatrix_view_tlate : 
00055     public mparent_t {
00056 
00057     public:
00058     
00059     /// \name Copy constructors
00060     //@{
00061     /// So2scllow copy constructor - create a new view of the same matrix
00062     omatrix_view_tlate(const omatrix_view_tlate &v) {
00063       mparent_t::block=NULL;
00064       mparent_t::data=v.data;
00065       mparent_t::size1=v.size1;
00066       mparent_t::size2=v.size2;
00067       mparent_t::tda=v.tda;
00068       mparent_t::owner=0;      
00069     }
00070     
00071     /// So2scllow copy constructor - create a new view of the same matrix
00072     omatrix_view_tlate& operator=(const omatrix_view_tlate &v) {
00073       mparent_t::block=NULL;
00074       mparent_t::data=v.data;
00075       mparent_t::size1=v.size1;
00076       mparent_t::size2=v.size2;
00077       mparent_t::tda=v.tda;
00078       mparent_t::owner=0;      
00079 
00080       return *this;
00081     }
00082     //@}
00083 
00084     ~omatrix_view_tlate() {};
00085     
00086     /// \name Get and set methods
00087     //@{
00088     /** 
00089         \brief Array-like indexing 
00090     */
00091     data_t *operator[](size_t i) {
00092 #if GSL_RANGE_CHECK
00093       if (i>=mparent_t::size1) {
00094         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00095                  +" in omatrix_view_tlate::operator[]. Size: "+
00096                  itos(mparent_t::size1)+
00097                  " (index should be less than size).").c_str(),gsl_index);
00098         return (mparent_t::data);
00099       }
00100 #endif
00101       return mparent_t::data+i*mparent_t::tda;
00102     }
00103     
00104     /** 
00105         \brief Array-like indexing 
00106     */
00107     const data_t *operator[](size_t i) const {
00108 #if GSL_RANGE_CHECK
00109       if (i>=mparent_t::size1) {
00110         set_err((((std::string)"Array index ")+itos(i)+" out of bounds"
00111                  +" in omatrix_view_tlate::operator[] const. Size: "+
00112                  itos(mparent_t::size1)+
00113                  " (index should be less than size).").c_str(),gsl_index);
00114         return (mparent_t::data);
00115       }
00116 #endif
00117       return mparent_t::data+i*mparent_t::tda;
00118     }
00119     
00120     /** 
00121         \brief Array-like indexing 
00122     */
00123     data_t &operator()(size_t i, size_t j) {
00124 #if GSL_RANGE_CHECK
00125       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00126         set_err((((std::string)"Array indices ")+itos(i)+
00127                  ", "+itos(j)+" out of bounds"
00128                  +" in omatrix_cx_view_tlate::operator(). Sizes: "+
00129                  itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00130                  " (indices should be less than sizes).").c_str(),
00131                 gsl_index);
00132         return *(mparent_t::data);
00133       }
00134 #endif
00135       return *(mparent_t::data+i*mparent_t::tda+j);
00136     }
00137     
00138     /** 
00139         \brief Array-like indexing 
00140     */
00141     const data_t &operator()(size_t i, size_t j) const {
00142 #if GSL_RANGE_CHECK
00143       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00144         set_err((((std::string)"Array indices ")+itos(i)+
00145                  ", "+itos(j)+" out of bounds"
00146                  +" in omatrix_cx_view_tlate::operator() const. Sizes: "+
00147                  itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00148                  " (indices should be less than sizes).").c_str(),
00149                 gsl_index);
00150         return *(mparent_t::data);
00151       }
00152 #endif
00153       return *(mparent_t::data+i*mparent_t::tda+j);
00154     }
00155     
00156     /** \brief Get (with optional range-checking) */
00157     data_t get(size_t i, size_t j) const {
00158 #if GSL_RANGE_CHECK
00159       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00160         set_err((((std::string)"Array indices ")+itos(i)+
00161                  ", "+itos(j)+" out of bounds"
00162                  +" in omatrix_cx_view_tlate::get() const. Sizes: "+
00163                  itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00164                  " (indices should be less than sizes).").c_str(),
00165                 gsl_index);
00166         return *(mparent_t::data);
00167       }
00168 #endif
00169       return (mparent_t::data+i*mparent_t::tda+j);
00170     }
00171     
00172     /** \brief Get pointer (with optional range-checking) */
00173     data_t *get_ptr(size_t i, size_t j) {
00174 #if GSL_RANGE_CHECK
00175       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00176         set_err((((std::string)"Array indices ")+itos(i)+
00177                  ", "+itos(j)+" out of bounds"
00178                  +" in omatrix_cx_view_tlate::get_ptr(). Sizes: "+
00179                  itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00180                  " (indices should be less than sizes).").c_str(),
00181                 gsl_index);
00182         return (mparent_t::data);
00183       }
00184 #endif
00185       return mparent_t::data+i*mparent_t::tda+j;
00186     }
00187     
00188     /** \brief Get pointer (with optional range-checking) */
00189     const data_t *get_const_ptr(size_t i, size_t j) const {
00190 #if GSL_RANGE_CHECK
00191       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00192         set_err((((std::string)"Array indices ")+itos(i)+
00193                  ", "+itos(j)+" out of bounds"
00194                  +" in omatrix_cx_view_tlate::get_const_ptr(). Sizes: "+
00195                  itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00196                  " (indices should be less than sizes).").c_str(),
00197                 gsl_index);
00198         return (mparent_t::data);
00199       }
00200 #endif
00201       return (const data_t *)(mparent_t::data+i*mparent_t::tda+j);
00202     }
00203     
00204     /** \brief Set (with optional range-checking) */
00205     int set(size_t i, size_t j, data_t val) {
00206 #if GSL_RANGE_CHECK
00207       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00208         set_err_ret((((std::string)"Array indices ")+itos(i)+
00209                      ", "+itos(j)+" out of bounds"
00210                      +" in omatrix_cx_view_tlate::set(). Sizes: "+
00211                      itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00212                      " (indices should be less than sizes).").c_str(),
00213                     gsl_index);
00214       }
00215 #endif
00216       *(mparent_t::data+i*mparent_t::tda+j)=val;
00217       return 0;
00218     }
00219 
00220     /** \brief Set all of the value to be the value \c val */
00221     int set_all(double val) {
00222       for(size_t i=0;i<mparent_t::size1;i++) {
00223         for(size_t j=0;j<mparent_t::size2;j++) {
00224           *(mparent_t::data+i*mparent_t::tda+j)=val;
00225         }
00226       }
00227       return 0;
00228     }
00229 
00230     /** 
00231         \brief Method to return number of rows
00232         
00233         If no memory has been allocated, this will quietly 
00234         return zero.
00235     */
00236     size_t rows() const {
00237       return mparent_t::size1;
00238     }
00239 
00240     /** 
00241         \brief Method to return number of columns
00242         
00243         If no memory has been allocated, this will quietly 
00244         return zero.
00245     */
00246     size_t cols() const {
00247       return mparent_t::size2;
00248     }
00249 
00250     /** 
00251         \brief Method to return matrix tda 
00252         
00253         If no memory has been allocated, this will quietly 
00254         return zero.
00255     */
00256     size_t tda() const {
00257       return mparent_t::tda;
00258     }
00259     //@}
00260 
00261     /// \name Other methods
00262     //@{
00263     /// Return true if this object owns the data it refers to
00264     bool is_owner() const {
00265       if (mparent_t::owner==1) return true;
00266       return false;
00267     }
00268     
00269     /** \brief Return a gsl matrix */
00270     mparent_t *get_gsl_matrix() { return this; };
00271     
00272     /** \brief Return a \c const gsl matrix */
00273     const mparent_t *get_gsl_matrix_const() const { return this; };
00274     //@}
00275 
00276     /// \name Arithmetic 
00277     //@{
00278     /** \brief operator+= */
00279     omatrix_view_tlate<data_t,mparent_t,block_t> &operator+=
00280       (const omatrix_view_tlate<data_t,mparent_t,block_t> &x) {
00281       size_t lsize=x.size1;
00282       if (lsize>mparent_t::size1) lsize=mparent_t::size1;
00283       size_t lsize2=x.size2;
00284       if (lsize2>mparent_t::size2) lsize2=mparent_t::size2;
00285       for(size_t i=0;i<lsize;i++) {
00286         for(size_t j=0;j<lsize2;j++) {
00287           (*this)[i][j]+=x[i][j];
00288         }
00289       }
00290       
00291       return *this;
00292     }
00293     
00294     /** \brief operator-= */
00295     omatrix_view_tlate<data_t,mparent_t,block_t> &operator-=
00296       (const omatrix_view_tlate<data_t,mparent_t,block_t> &x) {
00297       size_t lsize=x.size1;
00298       if (lsize>mparent_t::size1) lsize=mparent_t::size1;
00299       size_t lsize2=x.size2;
00300       if (lsize2>mparent_t::size2) lsize2=mparent_t::size2;
00301       for(size_t i=0;i<lsize;i++) {
00302         for(size_t j=0;j<lsize2;j++) {
00303           (*this)[i][j]+=x[i][j];
00304         }
00305       }
00306 
00307       return *this;
00308     }
00309     
00310     /** \brief operator+= */
00311     omatrix_view_tlate<data_t,mparent_t,block_t> &operator+=(const data_t &y) {
00312       for(size_t i=0;i<mparent_t::size1;i++) {
00313         for(size_t j=0;j<mparent_t::size2;j++) {
00314           (*this)[i][j]+=y;
00315         }
00316       }
00317       
00318       return *this;
00319     }
00320 
00321     /** \brief operator-= */
00322     omatrix_view_tlate<data_t,mparent_t,block_t> &operator-=(const data_t &y) {
00323       for(size_t i=0;i<mparent_t::size1;i++) {
00324         for(size_t j=0;j<mparent_t::size2;j++) {
00325           (*this)[i][j]-=y;
00326         }
00327       }
00328       
00329       return *this;
00330     }
00331 
00332     /** \brief operator*= */
00333     omatrix_view_tlate<data_t,mparent_t,block_t> &operator*=(const data_t &y) {
00334       for(size_t i=0;i<mparent_t::size1;i++) {
00335         for(size_t j=0;j<mparent_t::size2;j++) {
00336           (*this)[i][j]*=y;
00337         }
00338       }
00339       
00340       return *this;
00341     }
00342     //@}
00343 
00344 #ifndef DOXYGEN_INTERNAL
00345 
00346     protected:
00347 
00348     /** \brief Empty constructor provided for use by 
00349         omatrix_tlate(const omatrix_tlate &v)
00350     */
00351     omatrix_view_tlate() {};
00352 
00353 #endif
00354     
00355   };
00356 
00357   /** 
00358       \brief A matrix of double-precision numbers
00359   
00360   */
00361   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00362     class omatrix_tlate : 
00363     public omatrix_view_tlate<data_t,mparent_t,block_t> {
00364     public:
00365     
00366     /// \name Standard constructor
00367     //@{
00368     /** \brief Create an omatrix of size \c n with owner as \c true.
00369      */
00370     omatrix_tlate(size_t r=0, size_t c=0) {
00371 
00372       mparent_t::data=0;
00373       mparent_t::size1=0;
00374       mparent_t::size2=0;
00375       mparent_t::tda=0;
00376 
00377       // This must be set to 1 even if n=0 so that future
00378       // calls to operator= work properly
00379       mparent_t::owner=1;
00380 
00381       if (r>0 && c>0) {
00382         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00383         if (mparent_t::block) {
00384           mparent_t::block->data=(data_t *)malloc(r*c*sizeof(data_t));
00385           if (mparent_t::block->data) {
00386             mparent_t::block->size=r*c;
00387             mparent_t::data=mparent_t::block->data;
00388             mparent_t::size1=r;
00389             mparent_t::size2=c;
00390             mparent_t::tda=c;
00391           } else {
00392             std::free(mparent_t::block);
00393             set_err("No memory for data in omatrix_tlate constructor",
00394                     gsl_enomem);
00395           }
00396         } else {
00397           set_err("No memory for block in omatrix_tlate contructor",
00398                   gsl_enomem);
00399         }
00400       }
00401     }
00402     //@}
00403     
00404     /// \name Copy constructors
00405     //@{
00406     /// Deep copy constructor, allocate new space and make a copy
00407     omatrix_tlate(const omatrix_tlate &v) : 
00408       omatrix_view_tlate<data_t,mparent_t,block_t>() {
00409       size_t n=v.size1;
00410       size_t n2=v.size2;
00411       mparent_t::data=0;
00412       if (n>0 && n2>0) {
00413         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00414         if (mparent_t::block) {
00415           mparent_t::block->data=(data_t *)malloc(n*n2*sizeof(data_t));
00416           if (mparent_t::block->data) {
00417             mparent_t::block->size=n*n2;
00418             mparent_t::data=mparent_t::block->data;
00419             mparent_t::size1=n;
00420             mparent_t::size2=n2;
00421             mparent_t::tda=n2;
00422             mparent_t::owner=1;
00423             for(size_t i=0;i<n;i++) {
00424               for(size_t j=0;j<n2;j++) {
00425                 *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00426               }
00427             }
00428           } else {
00429             std::free(mparent_t::block);
00430             set_err("No memory for data in omatrix_tlate constructor",
00431                     gsl_enomem);
00432           }
00433         } else {
00434           set_err("No memory for block in omatrix_tlate contructor",
00435                   gsl_enomem);
00436         }
00437       } else {
00438         mparent_t::size1=0;
00439         mparent_t::size2=0;
00440         mparent_t::tda=0;
00441       }
00442     }
00443     
00444     /// Deep copy constructor, allocate new space and make a copy
00445     omatrix_tlate
00446       (const omatrix_view_tlate<data_t,mparent_t,block_t> &v) : 
00447       omatrix_view_tlate<data_t,mparent_t,block_t>() {
00448       size_t r=v.rows();
00449       size_t c=v.cols();
00450       mparent_t::data=0;
00451       if (r>0 && c>0) {
00452         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00453         if (mparent_t::block) {
00454           mparent_t::block->data=(data_t *)malloc(r*c*sizeof(data_t));
00455           if (mparent_t::block->data) {
00456             mparent_t::block->size=r*c;
00457             mparent_t::data=mparent_t::block->data;
00458             mparent_t::size1=v.size1;
00459             mparent_t::size2=v.size2;
00460             mparent_t::tda=v.tda;
00461             mparent_t::owner=1;
00462             for(size_t i=0;i<r;i++) {
00463               for(size_t j=0;i<c;j++) {
00464                 *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00465               }
00466             }
00467           } else {
00468             std::free(mparent_t::block);
00469             set_err("No memory for data in omatrix_tlate constructor",
00470                     gsl_enomem);
00471           }
00472         } else {
00473           set_err("No memory for block in omatrix_tlate contructor",
00474                   gsl_enomem);
00475         }
00476       } else {
00477         mparent_t::size1=0;
00478         mparent_t::size2=0;
00479         mparent_t::tda=0;
00480       }
00481     }
00482     
00483     /** \brief Deep copy constructor, if owner is true, allocate space and
00484         make a new copy, otherwise, just copy into the view
00485     */
00486     omatrix_tlate& operator=(const omatrix_tlate &v) {
00487       size_t size=v.size1;
00488       size_t size2=v.size2;
00489       mparent_t::data=0;
00490       if (mparent_t::owner) {
00491         allocate(mparent_t::size,mparent_t::size2);
00492       } else {
00493         if (mparent_t::size1!=size || mparent_t::size2!=size2) {
00494           set_err("Sizes don't match in omatrix_tlate::operator=()",
00495                   gsl_ebadlen);
00496           return *this;
00497         }
00498       }
00499       for(size_t i=0;i<size;i++) {
00500         for(size_t j=0;j<size2;j++) {
00501           *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00502         }
00503       }
00504       return *this;
00505     }
00506 
00507     /** \brief Deep copy constructor, if owner is true, allocate space and
00508         make a new copy, otherwise, just copy into the view
00509     */
00510     omatrix_tlate& operator=
00511       (const omatrix_view_tlate<data_t,mparent_t,block_t> &v) {
00512       size_t size=v.rows();
00513       size_t size2=v.cols();
00514       mparent_t::data=0;
00515       if (mparent_t::owner) {
00516         allocate(size,size2);
00517       } else {
00518         if (mparent_t::size!=size || mparent_t::size2!=size2) {
00519           set_err("Sizes don't match in omatrix_tlate::operator=()",
00520                   gsl_ebadlen);
00521           return *this;
00522         }
00523       }
00524       for(size_t i=0;i<size;i++) {
00525         for(size_t j=0;j<size2;j++) {
00526           *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00527         }
00528       }
00529       return *this;
00530     }
00531     
00532     /** \brief Deep copy from an array of ovectors
00533      */
00534     omatrix_tlate(size_t n,
00535                   ovector_view_tlate<data_t,vparent_t,block_t> ova[]) {
00536       if (n>0) {
00537         size_t n2=ova[0];
00538         if (n2>0) {
00539           allocate(n,n2);
00540           for(size_t i=0;i<n;i++) {
00541             for(size_t j=0;j<n2;j++) {
00542               (*this)[i][j]=ova[i][j];
00543             }
00544           }
00545         }
00546       }
00547     }
00548 
00549     /** \brief Deep copy from an array of uvectors
00550      */
00551     omatrix_tlate(size_t n, uvector_view_tlate<data_t> uva[]) {
00552       if (n>0) {
00553         size_t n2=uva[0];
00554         if (n2>0) {
00555           allocate(n,n2);
00556           for(size_t i=0;i<n;i++) {
00557             for(size_t j=0;j<n2;j++) {
00558               (*this)[i][j]=uva[i][j];
00559             }
00560           }
00561         }
00562       }
00563     }
00564 
00565     /** \brief Deep copy from a C-style 2-d array
00566      */
00567     omatrix_tlate(size_t n, size_t n2, data_t **csa) {
00568       if (n>0 && n2>0) {
00569         allocate(n,n2);
00570         for(size_t i=0;i<n;i++) {
00571           for(size_t j=0;j<n2;j++) {
00572             (*this)[i][j]=csa[i][j];
00573           }
00574         }
00575       }
00576     }
00577 
00578     //@}
00579     
00580     ~omatrix_tlate() {
00581       if (mparent_t::size1>0) {
00582         if (mparent_t::owner==1) {
00583           if (mparent_t::block->size>0) {
00584             std::free(mparent_t::block->data);
00585           }
00586           std::free(mparent_t::block);
00587           mparent_t::size1=0;
00588           mparent_t::size2=0;
00589         }
00590       }
00591     }
00592 
00593     /// \name Memory allocation
00594     //@{
00595     /** 
00596         \brief Allocate memory after freeing any memory
00597         presently in use
00598     */
00599     int allocate(size_t nrows, size_t ncols) {
00600       if (mparent_t::size1>0 || mparent_t::size2>0) free();
00601       
00602       if (nrows>0 && ncols>0) {
00603         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00604         if (mparent_t::block) {
00605           mparent_t::block->data=(data_t *)malloc(nrows*ncols*sizeof(data_t));
00606           if (mparent_t::block->data) {
00607             mparent_t::block->size=nrows*ncols;
00608             mparent_t::data=mparent_t::block->data;
00609             mparent_t::size1=nrows;
00610             mparent_t::size2=ncols;
00611             mparent_t::tda=ncols;
00612             mparent_t::owner=1;
00613           } else {
00614             std::free(mparent_t::block);
00615             set_err_ret("No memory for data in omatrix_tlate::allocate()",
00616                         gsl_enomem);
00617           }
00618         } else {
00619           set_err_ret("No memory for block in omatrix_tlate::allocate()",
00620                       gsl_enomem);
00621         }
00622       } else {
00623         set_err_ret("Zero size in omatrix::allocate()",gsl_einval);
00624       }
00625       return 0;
00626     }
00627 
00628     /** 
00629         \brief Free the memory 
00630     
00631         This function will safely do nothing if used without first
00632         allocating memory or if called multiple times in succession.
00633     */
00634     int free() {
00635       if (mparent_t::size1>0) {
00636         if (mparent_t::owner==1) {
00637           if (mparent_t::block->size>0) {
00638             std::free(mparent_t::block->data);
00639           }
00640           std::free(mparent_t::block);
00641         }
00642         mparent_t::size1=0;
00643         mparent_t::size2=0;
00644         mparent_t::tda=0;
00645       }
00646       return 0;
00647     }
00648     //@}
00649 
00650     /// \name Other methods
00651     //@{
00652     /// \brief Compute the transpose (even if matrix is not square)
00653     omatrix_tlate<data_t,mparent_t,vparent_t,block_t> transpose() {
00654       omatrix_tlate<data_t,mparent_t,vparent_t,block_t> 
00655         result(mparent_t::size2,mparent_t::size1);
00656       for(size_t i=0;i<mparent_t::size1;i++) {
00657         for(size_t j=0;j<mparent_t::size2;j++) {
00658           result[j][i]=(*this)[i][j];
00659         }
00660       }
00661     }
00662     //@}
00663     
00664   };
00665 
00666   /** \brief Create a vector from a row of a matrix 
00667    */
00668   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00669     class omatrix_row_tlate : 
00670     public ovector_view_tlate<data_t,vparent_t,block_t> {
00671     public:
00672     /** \brief Create a vector from row \c i of matrix \c m */
00673     omatrix_row_tlate(omatrix_view_tlate<data_t,mparent_t,block_t> &m, 
00674                       size_t i) {
00675       if (i<m.size1) {
00676         vparent_t::size=m.size2;
00677         vparent_t::stride=1;
00678         vparent_t::data=m.data+m.tda()*i;
00679         vparent_t::owner=0;
00680         vparent_t::block=NULL;
00681       }
00682     }
00683   };
00684     
00685   /** \brief Create a const vector from a row of a matrix 
00686    */
00687   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00688     class omatrix_const_row_tlate :
00689     public ovector_view_tlate<data_t,vparent_t,block_t> {
00690     public:
00691     /** \brief Create a vector from row \c i of matrix \c m */
00692     omatrix_const_row_tlate
00693       (const omatrix_view_tlate<data_t,mparent_t,block_t> &m, 
00694        size_t i) {
00695       if (i<m.size1) {
00696         vparent_t::size=m.size2;
00697         vparent_t::stride=1;
00698         vparent_t::data=m.data+m.tda*i;
00699         vparent_t::owner=0;
00700         vparent_t::block=NULL;
00701       } else {
00702         vparent_t::size=0;
00703         vparent_t::stride=0;
00704         vparent_t::data=0;
00705         vparent_t::owner=0;
00706         vparent_t::block=0;
00707       }
00708     }
00709   };
00710     
00711   /** \brief Create a vector from a column of a matrix
00712    */
00713   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00714     class omatrix_col_tlate :
00715     public ovector_view_tlate<data_t,vparent_t,block_t> {
00716     public:
00717     /** \brief Create a vector from col \c i of matrix \c m */
00718     omatrix_col_tlate(omatrix_view_tlate<data_t,mparent_t,block_t> &m, 
00719                       size_t i) {
00720       if (i<m.size2) {
00721         vparent_t::size=m.size1;
00722         vparent_t::stride=m.tda();
00723         vparent_t::data=m.data+i;
00724         vparent_t::owner=0;
00725         vparent_t::block=NULL;
00726       } else {
00727         vparent_t::size=0;
00728         vparent_t::stride=0;
00729         vparent_t::data=0;
00730         vparent_t::owner=0;
00731         vparent_t::block=0;
00732       }
00733     }
00734   };
00735     
00736   /** \brief Create a const vector from a column of a matrix
00737    */
00738   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00739     class omatrix_const_col_tlate :
00740     public ovector_view_tlate<data_t,vparent_t,block_t> {
00741     public:
00742     /** \brief Create a vector from col \c i of matrix \c m */
00743     omatrix_const_col_tlate(omatrix_view_tlate<data_t,mparent_t,block_t> &m,
00744                             size_t i) {
00745       if (i<m.size2) {
00746         vparent_t::size=m.size1;
00747         vparent_t::stride=m.tda();
00748         vparent_t::data=m.data+i;
00749         vparent_t::owner=0;
00750         vparent_t::block=NULL;
00751       }
00752     }
00753   };
00754 
00755   /** \brief Create a vector from the main diagonal
00756    */
00757   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00758     class omatrix_diag_tlate :
00759     public ovector_view_tlate<data_t,vparent_t,block_t> {
00760     public:
00761     /** \brief Create a vector of the diagonal of matrix \c m */
00762     omatrix_diag_tlate(omatrix_view_tlate<data_t,mparent_t,block_t> &m) {
00763 
00764       if (m.size2<m.size1) vparent_t::size=m.size2;
00765       else vparent_t::size=m.size1;
00766       vparent_t::stride=m.tda()+1;
00767       vparent_t::data=m.data;
00768       vparent_t::owner=0;
00769       vparent_t::block=NULL;
00770     }
00771   };
00772   
00773   
00774   /// omatrix typedef
00775   typedef omatrix_tlate<double,gsl_matrix,gsl_vector,gsl_block> omatrix;
00776   /// omatrix_view typedef
00777   typedef omatrix_view_tlate<double,gsl_matrix,gsl_block> omatrix_view;
00778   /// omatrix_row typedef
00779   typedef omatrix_row_tlate<double,gsl_matrix,gsl_vector,gsl_block> 
00780     omatrix_row;
00781   /// omatrix_col typedef
00782   typedef omatrix_col_tlate<double,gsl_matrix,gsl_vector,gsl_block> 
00783     omatrix_col;
00784   /// omatrix_const_row typedef
00785   typedef omatrix_const_row_tlate<double,gsl_matrix,gsl_vector,gsl_block> 
00786     omatrix_const_row;
00787   /// omatrix_const_col typedef
00788   typedef omatrix_const_col_tlate<double,gsl_matrix,gsl_vector,gsl_block> 
00789     omatrix_const_col;
00790   /// omatrix_diag typedef
00791   typedef omatrix_diag_tlate<double,gsl_matrix,gsl_vector,gsl_block> 
00792     omatrix_diag;
00793 
00794   /// omatrix_int typedef
00795   typedef omatrix_tlate<int,gsl_matrix_int,gsl_vector_int,gsl_block_int> 
00796     omatrix_int;
00797   /// omatrix_int_view typedef
00798   typedef omatrix_view_tlate<int,gsl_matrix_int,gsl_block_int> 
00799     omatrix_int_view;
00800   /// omatrix_int_row typedef
00801   typedef omatrix_row_tlate<int,gsl_matrix_int,gsl_vector_int,
00802     gsl_block_int> omatrix_int_row;
00803   /// omatrix_int_col typedef
00804   typedef omatrix_col_tlate<int,gsl_matrix_int,gsl_vector_int,
00805     gsl_block_int> omatrix_int_col;
00806   /// omatrix_int_const_row typedef
00807   typedef omatrix_const_row_tlate<int,gsl_matrix_int,gsl_vector_int,
00808     gsl_block_int> omatrix_int_const_row;
00809   /// omatrix_int_const_col typedef
00810   typedef omatrix_const_col_tlate<int,gsl_matrix_int,gsl_vector_int,
00811     gsl_block_int> omatrix_int_const_col;
00812   /// omatrix_int_diag typedef
00813   typedef omatrix_diag_tlate<int,gsl_matrix_int,gsl_vector_int,
00814     gsl_block_int> omatrix_int_diag;
00815 
00816   /** 
00817       \brief A operator for naive matrix output
00818 
00819 
00820       
00821       This outputs all of the matrix elements. Each row is output with
00822       an endline character at the end of each row. Positive values are
00823       preceeded by an extra space. A 2x2 example:
00824       \verbatim
00825       -3.751935e-05 -6.785864e-04
00826       -6.785864e-04  1.631984e-02
00827       \endverbatim
00828 
00829       The function \c gsl_ieee_double_to_rep() is used to determine
00830       the sign of a number, so that "-0.0" as distinct from "+0.0" 
00831       is handled correctly.
00832 
00833       \todo Maybe remove this function, as it's superceded by matrix_out()?
00834       \todo This assumes that scientific mode is on and showpos 
00835       is off. It'd be nice to fix this.
00836 
00837   */
00838   template<class data_t, class parent_t, class block_t>
00839     std::ostream &operator<<
00840     (std::ostream &os, 
00841      const omatrix_view_tlate<data_t,parent_t,block_t> &v) {
00842     size_t i;
00843     gsl_ieee_double_rep r;
00844     for(i=0;i<v.rows()-1;i++) {
00845       for(size_t j=0;j<v.cols();j++) {
00846         gsl_ieee_double_to_rep(&(v[i][j]), &r);
00847         if (r.sign==1) os << v[i][j] << ' ';
00848         else os << ' ' << v[i][j] << ' ';
00849       }
00850       os << '\n';
00851     }
00852     i=v.rows()-1;
00853     if (i>0) {
00854       for(size_t j=0;j<v.cols();j++) {
00855         gsl_ieee_double_to_rep(&(v[i][j]), &r);
00856         if (r.sign==1) os << v[i][j] << ' ';
00857         else os << ' ' << v[i][j] << ' ';
00858       }
00859     }
00860     return os;
00861   }
00862   
00863   /** \brief A simple class to provide an \c allocate() function
00864       for \ref omatrix
00865       
00866   */
00867   class omatrix_alloc {
00868   public:
00869     /// Allocate \c v for \c i elements
00870     void allocate(omatrix &o, size_t i, size_t j) { o.allocate(i,j); }
00871     /// Free memory
00872     void free(omatrix &o, size_t i) { o.free(); }
00873   };
00874 
00875   /** \brief A matrix where the memory allocation is performed in 
00876       the constructor
00877   */
00878 #ifdef DOXYGENP
00879   template<size_t N, size_t M> class ofmatrix : 
00880     public omatrix_tlate<data_t,mparent_t,vparent_t,block_t>
00881 #else  
00882     template<size_t N, size_t M> class ofmatrix : 
00883     public omatrix_tlate<double,gsl_matrix,gsl_vector,gsl_block>
00884 #endif
00885     {
00886     public:
00887       ofmatrix() : omatrix_tlate<double,gsl_matrix,gsl_vector,
00888         gsl_block>(N,M) {
00889       }
00890     };
00891   
00892   
00893 #ifndef DOXYGENP
00894 }
00895 #endif
00896 
00897 #endif
00898 

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