Object-oriented Scientific Computing Library: Version 0.910
omatrix_tlate.h
Go to the documentation of this file.
00001 /*
00002    -------------------------------------------------------------------
00003   
00004    Copyright (C) 2006-2012, 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     \future The \c xmatrix class demonstrates how operator[] could
00030     return an ovector_array object and thus provide more
00031     bounds-checking. This would demand including a new parameter in
00032     omatrix_view_tlate which contains the vector type.
00033 */
00034 
00035 #include <iostream>
00036 #include <cstdlib>
00037 #include <string>
00038 #include <fstream>
00039 #include <sstream>
00040 
00041 #include <gsl/gsl_matrix.h>
00042 #include <gsl/gsl_ieee_utils.h>
00043 
00044 #include <o2scl/err_hnd.h>
00045 #include <o2scl/ovector_tlate.h>
00046 #include <o2scl/array.h>
00047 
00048 #ifndef DOXYGENP
00049 namespace o2scl {
00050 #endif
00051 
00052   /** \brief A const matrix view of omatrix objects
00053   */
00054   template<class data_t, class mparent_t, class block_t> 
00055     class omatrix_const_view_tlate : 
00056   public mparent_t {
00057 
00058   public:
00059     
00060     /// \name Copy constructors
00061     //@{
00062     /// Shallow copy constructor - create a new view of the same matrix
00063     omatrix_const_view_tlate(const omatrix_const_view_tlate &v) {
00064       mparent_t::block=0;
00065       mparent_t::data=v.data;
00066       mparent_t::size1=v.size1;
00067       mparent_t::size2=v.size2;
00068       mparent_t::tda=v.tda();
00069       mparent_t::owner=0;      
00070     }
00071     
00072     /// Shallow copy constructor - create a new view of the same matrix
00073     omatrix_const_view_tlate& operator=(const omatrix_const_view_tlate &v) {
00074       mparent_t::block=0;
00075       mparent_t::data=v.data;
00076       mparent_t::size1=v.size1;
00077       mparent_t::size2=v.size2;
00078       mparent_t::tda=v.tda;
00079       mparent_t::owner=0;      
00080 
00081       return *this;
00082     }
00083     //@}
00084 
00085     ~omatrix_const_view_tlate() {};
00086     
00087     /// \name Get and set methods
00088     //@{
00089     /** \brief Array-like indexing 
00090     */
00091     const data_t *operator[](size_t i) const {
00092 #if O2SCL_NO_RANGE_CHECK
00093 #else
00094       if (i>=mparent_t::size1) {
00095         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00096                    +" in omatrix_const_view_tlate::operator[] const. Size: "+
00097                    itos(mparent_t::size1)+
00098                    " (index should be less than size).").c_str(),gsl_eindex);
00099         return (mparent_t::data);
00100       }
00101 #endif
00102       return mparent_t::data+i*mparent_t::tda;
00103     }
00104     
00105     /** \brief Array-like indexing 
00106     */
00107     const data_t &operator()(size_t i, size_t j) const {
00108 #if O2SCL_NO_RANGE_CHECK
00109 #else
00110       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00111         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00112                    ", "+itos(j)+" out of bounds"
00113                    +" in omatrix_cx_view_tlate::operator() const. Sizes: "+
00114                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00115                    " (indices should be less than sizes).").c_str(),
00116                   gsl_eindex);
00117         return *(mparent_t::data);
00118       }
00119 #endif
00120       return *(mparent_t::data+i*mparent_t::tda+j);
00121     }
00122     
00123     /** \brief Get (with optional range-checking) */
00124     data_t get(size_t i, size_t j) const {
00125 #if O2SCL_NO_RANGE_CHECK
00126 #else
00127       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00128         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00129                    ", "+itos(j)+" out of bounds"
00130                    +" in omatrix_cx_view_tlate::get() const. Sizes: "+
00131                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00132                    " (indices should be less than sizes).").c_str(),
00133                   gsl_eindex);
00134         return *(mparent_t::data);
00135       }
00136 #endif
00137       return *(mparent_t::data+i*mparent_t::tda+j);
00138     }
00139     
00140     /** \brief Get pointer (with optional range-checking) */
00141     data_t *get_ptr(size_t i, size_t j) {
00142 #if O2SCL_NO_RANGE_CHECK
00143 #else
00144       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00145         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00146                    ", "+itos(j)+" out of bounds"
00147                    +" in omatrix_cx_view_tlate::get_ptr(). Sizes: "+
00148                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00149                    " (indices should be less than sizes).").c_str(),
00150                   gsl_eindex);
00151         return (mparent_t::data);
00152       }
00153 #endif
00154       return mparent_t::data+i*mparent_t::tda+j;
00155     }
00156     
00157     /** \brief Get pointer (with optional range-checking) */
00158     const data_t *get_const_ptr(size_t i, size_t j) const {
00159 #if O2SCL_NO_RANGE_CHECK
00160 #else
00161       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00162         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00163                    ", "+itos(j)+" out of bounds"
00164                    +" in omatrix_cx_view_tlate::get_const_ptr(). Sizes: "+
00165                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00166                    " (indices should be less than sizes).").c_str(),
00167                   gsl_eindex);
00168         return (mparent_t::data);
00169       }
00170 #endif
00171       return (const data_t *)(mparent_t::data+i*mparent_t::tda+j);
00172     }
00173     
00174     /** \brief Method to return number of rows
00175         
00176         If no memory has been allocated, this will quietly 
00177         return zero.
00178     */
00179     size_t rows() const {
00180       return mparent_t::size1;
00181     }
00182 
00183     /** \brief Method to return number of columns
00184         
00185         If no memory has been allocated, this will quietly 
00186         return zero.
00187     */
00188     size_t cols() const {
00189       return mparent_t::size2;
00190     }
00191 
00192     /** \brief Method to return matrix tda 
00193         
00194         If no memory has been allocated, this will quietly 
00195         return zero.
00196     */
00197     size_t tda() const {
00198       return mparent_t::tda;
00199     }
00200     //@}
00201 
00202     /// \name Other methods
00203     //@{
00204     /** \brief Return true if this object owns the data it refers to
00205         
00206         This can be used to determine if an object is a "matrix_view",
00207         or a "matrix". If is_owner() is true, then it is an \ref
00208         omatrix_tlate object.
00209     */
00210     bool is_owner() const {
00211       if (mparent_t::owner==1) return true;
00212       return false;
00213     }
00214 
00215     /// The largest matrix element
00216     data_t max() const {
00217       data_t mx=*mparent_t::data;
00218       for(size_t i=0;i<mparent_t::size1;i++) {
00219         for(size_t j=0;j<mparent_t::size2;j++) {
00220           if (*(mparent_t::data+i*mparent_t::tda+j)>mx) {
00221             mx=*(mparent_t::data+i*mparent_t::tda+j);
00222           }
00223         }
00224       }
00225       return mx;
00226     }
00227     
00228     /// The smallest matrix element
00229     data_t min() const {
00230       data_t mx=*mparent_t::data;
00231       for(size_t i=0;i<mparent_t::size1;i++) {
00232         for(size_t j=0;j<mparent_t::size2;j++) {
00233           if (*(mparent_t::data+i*mparent_t::tda+j)<mx) {
00234             mx=*(mparent_t::data+i*mparent_t::tda+j);
00235           }
00236         }
00237       }
00238       return mx;
00239     }
00240     
00241     /** \brief Return a \c const gsl matrix */
00242     const mparent_t *get_gsl_matrix_const() const { return this; };
00243     //@}
00244 
00245 #ifndef DOXYGEN_INTERNAL
00246 
00247   protected:
00248 
00249     /** \brief The default constructor
00250      */
00251     omatrix_const_view_tlate() {};
00252 
00253 #endif
00254     
00255   };
00256 
00257   /** \brief A base class for omatrix and omatrix_view
00258   */
00259   template<class data_t, class mparent_t, class block_t> 
00260     class omatrix_base_tlate : 
00261   public omatrix_const_view_tlate<data_t,mparent_t,block_t> {
00262     
00263   public:
00264     
00265     /// \name Copy constructors
00266     //@{
00267     /// Shallow copy constructor - create a new view of the same matrix
00268     omatrix_base_tlate(const omatrix_base_tlate &v) {
00269       mparent_t::block=0;
00270       mparent_t::data=v.data;
00271       mparent_t::size1=v.size1;
00272       mparent_t::size2=v.size2;
00273       mparent_t::tda=v.tda();
00274       mparent_t::owner=0;      
00275     }
00276     
00277     /// Shallow copy constructor - create a new view of the same matrix
00278     omatrix_base_tlate& operator=(const omatrix_base_tlate &v) {
00279       mparent_t::block=0;
00280       mparent_t::data=v.data;
00281       mparent_t::size1=v.size1;
00282       mparent_t::size2=v.size2;
00283       mparent_t::tda=v.tda;
00284       mparent_t::owner=0;      
00285 
00286       return *this;
00287     }
00288     //@}
00289 
00290     ~omatrix_base_tlate() {};
00291     
00292     /// \name Get and set methods
00293     //@{
00294     /** \brief Array-like indexing 
00295     */
00296     data_t *operator[](size_t i) {
00297 #if O2SCL_NO_RANGE_CHECK
00298 #else
00299       if (i>=mparent_t::size1) {
00300         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00301                    +" in omatrix_base_tlate::operator[]. Size: "+
00302                    itos(mparent_t::size1)+
00303                    " (index should be less than size).").c_str(),gsl_eindex);
00304         return (mparent_t::data);
00305       }
00306 #endif
00307       return mparent_t::data+i*mparent_t::tda;
00308     }
00309     
00310     /** \brief Array-like indexing 
00311     */
00312     const data_t *operator[](size_t i) const {
00313 #if O2SCL_NO_RANGE_CHECK
00314 #else
00315       if (i>=mparent_t::size1) {
00316         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00317                    +" in omatrix_base_tlate::operator[] const. Size: "+
00318                    itos(mparent_t::size1)+
00319                    " (index should be less than size).").c_str(),gsl_eindex);
00320         return (mparent_t::data);
00321       }
00322 #endif
00323       return mparent_t::data+i*mparent_t::tda;
00324     }
00325     
00326     /** \brief Array-like indexing 
00327     */
00328     data_t &operator()(size_t i, size_t j) {
00329 #if O2SCL_NO_RANGE_CHECK
00330 #else
00331       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00332         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00333                    ", "+itos(j)+" out of bounds"
00334                    +" in omatrix_cx_view_tlate::operator(). Sizes: "+
00335                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00336                    " (indices should be less than sizes).").c_str(),
00337                   gsl_eindex);
00338         return *(mparent_t::data);
00339       }
00340 #endif
00341       return *(mparent_t::data+i*mparent_t::tda+j);
00342     }
00343     
00344     /** \brief Array-like indexing 
00345     */
00346     const data_t &operator()(size_t i, size_t j) const {
00347 #if O2SCL_NO_RANGE_CHECK
00348 #else
00349       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00350         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00351                    ", "+itos(j)+" out of bounds"
00352                    +" in omatrix_cx_view_tlate::operator() const. Sizes: "+
00353                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00354                    " (indices should be less than sizes).").c_str(),
00355                   gsl_eindex);
00356         return *(mparent_t::data);
00357       }
00358 #endif
00359       return *(mparent_t::data+i*mparent_t::tda+j);
00360     }
00361     
00362     /** \brief Get pointer (with optional range-checking) */
00363     data_t *get_ptr(size_t i, size_t j) {
00364 #if O2SCL_NO_RANGE_CHECK
00365 #else
00366       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00367         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00368                    ", "+itos(j)+" out of bounds"
00369                    +" in omatrix_cx_view_tlate::get_ptr(). Sizes: "+
00370                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00371                    " (indices should be less than sizes).").c_str(),
00372                   gsl_eindex);
00373         return (mparent_t::data);
00374       }
00375 #endif
00376       return mparent_t::data+i*mparent_t::tda+j;
00377     }
00378     
00379     /** \brief Set (with optional range-checking) */
00380     int set(size_t i, size_t j, data_t val) {
00381 #if O2SCL_NO_RANGE_CHECK
00382 #else
00383       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00384         O2SCL_ERR_RET((((std::string)"Array indices ")+itos(i)+
00385                        ", "+itos(j)+" out of bounds"
00386                        +" in omatrix_cx_view_tlate::set(). Sizes: "+
00387                        itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00388                        " (indices should be less than sizes).").c_str(),
00389                       gsl_eindex);
00390       }
00391 #endif
00392       *(mparent_t::data+i*mparent_t::tda+j)=val;
00393       return 0;
00394     }
00395 
00396     /** \brief Set all of the value to be the value \c val */
00397     int set_all(double val) {
00398       for(size_t i=0;i<mparent_t::size1;i++) {
00399         for(size_t j=0;j<mparent_t::size2;j++) {
00400           *(mparent_t::data+i*mparent_t::tda+j)=val;
00401         }
00402       }
00403       return 0;
00404     }
00405     //@}
00406 
00407     /// \name Other methods
00408     //@{
00409     /** \brief Return a gsl matrix */
00410     mparent_t *get_gsl_matrix() { return this; };
00411     //@}
00412 
00413     /// \name Arithmetic 
00414     //@{
00415     /** \brief operator+= */
00416     omatrix_base_tlate<data_t,mparent_t,block_t> &operator+=
00417       (const omatrix_base_tlate<data_t,mparent_t,block_t> &x) {
00418       size_t lsize=x.size1;
00419       if (lsize>mparent_t::size1) lsize=mparent_t::size1;
00420       size_t lsize2=x.size2;
00421       if (lsize2>mparent_t::size2) lsize2=mparent_t::size2;
00422       for(size_t i=0;i<lsize;i++) {
00423         for(size_t j=0;j<lsize2;j++) {
00424           (*this)[i][j]+=x[i][j];
00425         }
00426       }
00427       
00428       return *this;
00429     }
00430     
00431     /** \brief operator-= */
00432     omatrix_base_tlate<data_t,mparent_t,block_t> &operator-=
00433       (const omatrix_base_tlate<data_t,mparent_t,block_t> &x) {
00434       size_t lsize=x.size1;
00435       if (lsize>mparent_t::size1) lsize=mparent_t::size1;
00436       size_t lsize2=x.size2;
00437       if (lsize2>mparent_t::size2) lsize2=mparent_t::size2;
00438       for(size_t i=0;i<lsize;i++) {
00439         for(size_t j=0;j<lsize2;j++) {
00440           (*this)[i][j]+=x[i][j];
00441         }
00442       }
00443 
00444       return *this;
00445     }
00446     
00447     /** \brief operator+= */
00448     omatrix_base_tlate<data_t,mparent_t,block_t> 
00449       &operator+=(const data_t &y) {
00450       for(size_t i=0;i<mparent_t::size1;i++) {
00451         for(size_t j=0;j<mparent_t::size2;j++) {
00452           (*this)[i][j]+=y;
00453         }
00454       }
00455       
00456       return *this;
00457     }
00458 
00459     /** \brief operator-= */
00460     omatrix_base_tlate<data_t,mparent_t,block_t> 
00461       &operator-=(const data_t &y) {
00462       for(size_t i=0;i<mparent_t::size1;i++) {
00463         for(size_t j=0;j<mparent_t::size2;j++) {
00464           (*this)[i][j]-=y;
00465         }
00466       }
00467       
00468       return *this;
00469     }
00470 
00471     /** \brief operator*= */
00472     omatrix_base_tlate<data_t,mparent_t,block_t> 
00473       &operator*=(const data_t &y) {
00474       for(size_t i=0;i<mparent_t::size1;i++) {
00475         for(size_t j=0;j<mparent_t::size2;j++) {
00476           (*this)[i][j]*=y;
00477         }
00478       }
00479       
00480       return *this;
00481     }
00482     //@}
00483 
00484 #ifndef DOXYGEN_INTERNAL
00485 
00486   protected:
00487 
00488     /** \brief The default constructor
00489      */
00490     omatrix_base_tlate() {};
00491 
00492 #endif
00493     
00494   };
00495 
00496   /** \brief A matrix view of double-precision numbers
00497 
00498       This is a matrix view, which views a matrix stored somewhere
00499       else. For a full matrix template class with its own memory, see
00500       \ref omatrix_tlate . The basic matrix classes are built upon
00501       these templates. A matrix of double-precision numbers is an
00502       object of type \ref omatrix . See \ref vecmat_section in the
00503       User's Guide for more information.
00504   */
00505   template<class data_t, class mparent_t, class block_t> 
00506     class omatrix_view_tlate : 
00507   public omatrix_base_tlate<data_t,mparent_t,block_t> {
00508 
00509   public:
00510 
00511     /// \name Copy constructors
00512     //@{
00513     /// Shallow copy constructor - create a new view of the same matrix
00514   omatrix_view_tlate(const omatrix_view_tlate &v) : 
00515     omatrix_base_tlate<data_t,mparent_t,block_t>() {
00516       mparent_t::block=0;
00517       mparent_t::data=v.data;
00518       mparent_t::size1=v.size1;
00519       mparent_t::size2=v.size2;
00520       mparent_t::tda=v.tda();
00521       mparent_t::owner=0;      
00522     }
00523     
00524     /// Shallow copy constructor - create a new view of the same matrix
00525     omatrix_view_tlate& operator=(const omatrix_view_tlate &v) {
00526       mparent_t::block=0;
00527       mparent_t::data=v.data;
00528       mparent_t::size1=v.size1;
00529       mparent_t::size2=v.size2;
00530       mparent_t::tda=v.tda;
00531       mparent_t::owner=0;      
00532 
00533       return *this;
00534     }
00535 
00536     /// Shallow copy constructor - create a new view of the same matrix
00537   omatrix_view_tlate(omatrix_base_tlate<data_t,mparent_t,block_t> &v) :
00538     omatrix_base_tlate<data_t,mparent_t,block_t>() {
00539       mparent_t::block=0;
00540       mparent_t::data=v.data;
00541       mparent_t::size1=v.size1;
00542       mparent_t::size2=v.size2;
00543       mparent_t::tda=v.tda();
00544       mparent_t::owner=0;      
00545     }
00546     
00547     /// Shallow copy constructor - create a new view of the same matrix
00548     omatrix_view_tlate& operator=
00549       (omatrix_base_tlate<data_t,mparent_t,block_t> &v) {
00550       mparent_t::block=0;
00551       mparent_t::data=v.data;
00552       mparent_t::size1=v.size1;
00553       mparent_t::size2=v.size2;
00554       mparent_t::tda=v.tda;
00555       mparent_t::owner=0;      
00556 
00557       return *this;
00558     }
00559     //@}
00560 
00561     ~omatrix_view_tlate() {};
00562     
00563     /// \name Get and set methods
00564     //@{
00565     /** \brief Array-like indexing 
00566     */
00567     data_t *operator[](size_t i) const {
00568 #if O2SCL_NO_RANGE_CHECK
00569 #else
00570       if (i>=mparent_t::size1) {
00571         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00572                    +" in omatrix_view_tlate::operator[]. Size: "+
00573                    itos(mparent_t::size1)+
00574                    " (index should be less than size).").c_str(),gsl_eindex);
00575         return (mparent_t::data);
00576       }
00577 #endif
00578       return mparent_t::data+i*mparent_t::tda;
00579     }
00580     
00581     /** \brief Array-like indexing 
00582     */
00583     data_t &operator()(size_t i, size_t j) const {
00584 #if O2SCL_NO_RANGE_CHECK
00585 #else
00586       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00587         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00588                    ", "+itos(j)+" out of bounds"
00589                    +" in omatrix_cx_view_tlate::operator(). Sizes: "+
00590                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00591                    " (indices should be less than sizes).").c_str(),
00592                   gsl_eindex);
00593         return *(mparent_t::data);
00594       }
00595 #endif
00596       return *(mparent_t::data+i*mparent_t::tda+j);
00597     }
00598     
00599     /** \brief Get pointer (with optional range-checking) */
00600     data_t *get_ptr(size_t i, size_t j) const {
00601 #if O2SCL_NO_RANGE_CHECK
00602 #else
00603       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00604         O2SCL_ERR((((std::string)"Array indices ")+itos(i)+
00605                    ", "+itos(j)+" out of bounds"
00606                    +" in omatrix_cx_view_tlate::get_ptr(). Sizes: "+
00607                    itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00608                    " (indices should be less than sizes).").c_str(),
00609                   gsl_eindex);
00610         return (mparent_t::data);
00611       }
00612 #endif
00613       return mparent_t::data+i*mparent_t::tda+j;
00614     }
00615     
00616     /** \brief Set (with optional range-checking) */
00617     int set(size_t i, size_t j, data_t val) const {
00618 #if O2SCL_NO_RANGE_CHECK
00619 #else
00620       if (i>=mparent_t::size1 || j>=mparent_t::size2) {
00621         O2SCL_ERR_RET((((std::string)"Array indices ")+itos(i)+
00622                        ", "+itos(j)+" out of bounds"
00623                        +" in omatrix_cx_view_tlate::set(). Sizes: "+
00624                        itos(mparent_t::size1)+","+itos(mparent_t::size2)+
00625                        " (indices should be less than sizes).").c_str(),
00626                       gsl_eindex);
00627       }
00628 #endif
00629       *(mparent_t::data+i*mparent_t::tda+j)=val;
00630       return 0;
00631     }
00632 
00633     /** \brief Set all of the value to be the value \c val */
00634     int set_all(double val) const {
00635       for(size_t i=0;i<mparent_t::size1;i++) {
00636         for(size_t j=0;j<mparent_t::size2;j++) {
00637           *(mparent_t::data+i*mparent_t::tda+j)=val;
00638         }
00639       }
00640       return 0;
00641     }
00642     //@}
00643 
00644 #ifndef DOXYGEN_INTERNAL
00645 
00646   protected:
00647 
00648     /** \brief The default constructor
00649      */
00650     omatrix_view_tlate() {};
00651 
00652 #endif
00653 
00654   };
00655 
00656   /** \brief A matrix of double-precision numbers
00657   
00658       The basic matrix classes are built upon this template. A matrix
00659       of double-precision numbers is an object of type \ref omatrix ,
00660       which is just a <tt>typedef</tt> defined using this class
00661       template. See \ref vecmat_section in the User's Guide for more
00662       information.
00663   */
00664   template<class data_t, class mparent_t, class vparent_t, class block_t> 
00665     class omatrix_tlate : 
00666   public omatrix_base_tlate<data_t,mparent_t,block_t> {
00667   public:
00668     
00669     /// \name Standard constructor
00670     //@{
00671     /** \brief Create an omatrix of size \c n with owner as \c true.
00672      */
00673     omatrix_tlate(size_t r=0, size_t c=0) {
00674 
00675       mparent_t::block=0;
00676       mparent_t::data=0;
00677       mparent_t::size1=0;
00678       mparent_t::size2=0;
00679       mparent_t::tda=0;
00680 
00681       // This must be set to 1 even if n=0 so that future
00682       // calls to operator= work properly
00683       mparent_t::owner=1;
00684 
00685       if (r>0 && c>0) {
00686         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00687         if (mparent_t::block) {
00688           mparent_t::block->data=(data_t *)malloc(r*c*sizeof(data_t));
00689           if (mparent_t::block->data) {
00690             mparent_t::block->size=r*c;
00691             mparent_t::data=mparent_t::block->data;
00692             mparent_t::size1=r;
00693             mparent_t::size2=c;
00694             mparent_t::tda=c;
00695           } else {
00696             std::free(mparent_t::block);
00697             O2SCL_ERR("No memory for data in omatrix_tlate constructor",
00698                       gsl_enomem);
00699           }
00700         } else {
00701           O2SCL_ERR("No memory for block in omatrix_tlate contructor",
00702                     gsl_enomem);
00703         }
00704       }
00705     }
00706     //@}
00707     
00708     /// \name Copy constructors
00709     //@{
00710     /// Deep copy constructor, allocate new space and make a copy
00711   omatrix_tlate(const omatrix_tlate &v) : 
00712     omatrix_base_tlate<data_t,mparent_t,block_t>() {
00713 
00714       mparent_t::block=0;
00715       mparent_t::data=0;
00716       mparent_t::size1=0;
00717       mparent_t::size2=0;
00718       mparent_t::tda=0;
00719       mparent_t::owner=1;
00720 
00721       size_t n=v.size1;
00722       size_t n2=v.size2;
00723       if (n>0 && n2>0) {
00724         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00725         if (mparent_t::block) {
00726           mparent_t::block->data=(data_t *)malloc(n*n2*sizeof(data_t));
00727           if (mparent_t::block->data) {
00728             mparent_t::block->size=n*n2;
00729             mparent_t::data=mparent_t::block->data;
00730             mparent_t::size1=n;
00731             mparent_t::size2=n2;
00732             mparent_t::tda=n2;
00733             mparent_t::owner=1;
00734             for(size_t i=0;i<n;i++) {
00735               for(size_t j=0;j<n2;j++) {
00736                 *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00737               }
00738             }
00739           } else {
00740             std::free(mparent_t::block);
00741             O2SCL_ERR("No memory for data in omatrix_tlate constructor",
00742                       gsl_enomem);
00743           }
00744         } else {
00745           O2SCL_ERR("No memory for block in omatrix_tlate contructor",
00746                     gsl_enomem);
00747         }
00748       } else {
00749         mparent_t::size1=0;
00750         mparent_t::size2=0;
00751         mparent_t::tda=0;
00752       }
00753     }
00754     
00755     /// Deep copy constructor, allocate new space and make a copy
00756     omatrix_tlate
00757       (const omatrix_const_view_tlate<data_t,mparent_t,block_t> &v) : 
00758     omatrix_view_tlate<data_t,mparent_t,block_t>() {
00759 
00760       mparent_t::block=0;
00761       mparent_t::data=0;
00762       mparent_t::size1=0;
00763       mparent_t::size2=0;
00764       mparent_t::tda=0;
00765       mparent_t::owner=1;
00766 
00767       size_t r=v.rows();
00768       size_t c=v.cols();
00769       if (r>0 && c>0) {
00770         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00771         if (mparent_t::block) {
00772           mparent_t::block->data=(data_t *)malloc(r*c*sizeof(data_t));
00773           if (mparent_t::block->data) {
00774             mparent_t::block->size=r*c;
00775             mparent_t::data=mparent_t::block->data;
00776             mparent_t::size1=v.size1;
00777             mparent_t::size2=v.size2;
00778             mparent_t::tda=v.tda;
00779             mparent_t::owner=1;
00780             for(size_t i=0;i<r;i++) {
00781               for(size_t j=0;i<c;j++) {
00782                 *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00783               }
00784             }
00785           } else {
00786             std::free(mparent_t::block);
00787             O2SCL_ERR("No memory for data in omatrix_tlate constructor",
00788                       gsl_enomem);
00789           }
00790         } else {
00791           O2SCL_ERR("No memory for block in omatrix_tlate contructor",
00792                     gsl_enomem);
00793         }
00794       } else {
00795         mparent_t::size1=0;
00796         mparent_t::size2=0;
00797         mparent_t::tda=0;
00798       }
00799     }
00800     
00801     /** \brief Deep copy constructor, if owner is true, allocate
00802         space and make a new copy, otherwise, just copy into the
00803         view
00804     */
00805     omatrix_tlate& operator=(const omatrix_tlate &v) {
00806           
00807       // Check for self-assignment
00808       if (this==&v) return *this;
00809       
00810       mparent_t::block=0;
00811       mparent_t::data=0;
00812       mparent_t::size1=0;
00813       mparent_t::size2=0;
00814       mparent_t::tda=0;
00815       mparent_t::owner=1;
00816       
00817       size_t sz=v.rows();
00818       size_t sz2=v.cols();
00819       mparent_t::data=0;
00820       if (mparent_t::owner) {
00821         allocate(mparent_t::size1,mparent_t::size2);
00822       } else {
00823         if (mparent_t::size1!=sz || mparent_t::size2!=sz2) {
00824           O2SCL_ERR("Sizes don't match in omatrix_tlate::operator=()",
00825                     gsl_ebadlen);
00826           return *this;
00827         }
00828       }
00829       for(size_t i=0;i<sz;i++) {
00830         for(size_t j=0;j<sz2;j++) {
00831           *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00832         }
00833       }
00834       return *this;
00835     }
00836 
00837     /** \brief Deep copy constructor, if owner is true, allocate
00838         space and make a new copy, otherwise, just copy into the
00839         view
00840     */
00841     omatrix_tlate& operator=
00842       (const omatrix_const_view_tlate<data_t,mparent_t,block_t> &v) {
00843 
00844       mparent_t::block=0;
00845       mparent_t::data=0;
00846       mparent_t::size1=0;
00847       mparent_t::size2=0;
00848       mparent_t::tda=0;
00849       mparent_t::owner=1;
00850       
00851       // Check for self-assignment
00852       if (this==&v) return *this;
00853 
00854       size_t r=v.rows();
00855       size_t c=v.cols();
00856       mparent_t::data=0;
00857       if (mparent_t::owner) {
00858         allocate(r,c);
00859       } else {
00860         if (mparent_t::size1!=r || mparent_t::size2!=c) {
00861           O2SCL_ERR("Sizes don't match in omatrix_tlate::operator=()",
00862                     gsl_ebadlen);
00863           return *this;
00864         }
00865       }
00866       for(size_t i=0;i<r;i++) {
00867         for(size_t j=0;j<c;j++) {
00868           *(mparent_t::data+i*mparent_t::tda+j)=v[i][j];
00869         }
00870       }
00871       return *this;
00872     }
00873     
00874     /** \brief Deep copy from an array of ovectors
00875      */
00876     omatrix_tlate(size_t n,
00877                   ovector_base_tlate<data_t,vparent_t,block_t> ova[]) {
00878       if (n>0) {
00879         size_t n2=ova[0];
00880         if (n2>0) {
00881           allocate(n,n2);
00882           for(size_t i=0;i<n;i++) {
00883             for(size_t j=0;j<n2;j++) {
00884               (*this)[i][j]=ova[i][j];
00885             }
00886           }
00887         }
00888       }
00889     }
00890 
00891     /** \brief Deep copy from an array of uvectors
00892      */
00893     omatrix_tlate(size_t n, uvector_base_tlate<data_t> uva[]) {
00894       if (n>0) {
00895         size_t n2=uva[0];
00896         if (n2>0) {
00897           allocate(n,n2);
00898           for(size_t i=0;i<n;i++) {
00899             for(size_t j=0;j<n2;j++) {
00900               (*this)[i][j]=uva[i][j];
00901             }
00902           }
00903         }
00904       }
00905     }
00906 
00907     /** \brief Deep copy from a C-style 2-d array
00908      */
00909     omatrix_tlate(size_t n, size_t n2, data_t **csa) {
00910       if (n>0 && n2>0) {
00911         allocate(n,n2);
00912         for(size_t i=0;i<n;i++) {
00913           for(size_t j=0;j<n2;j++) {
00914             (*this)[i][j]=csa[i][j];
00915           }
00916         }
00917       }
00918     }
00919 
00920     //@}
00921     
00922     ~omatrix_tlate() {
00923       if (mparent_t::size1>0) {
00924         if (mparent_t::owner==1) {
00925           if (mparent_t::block->size>0) {
00926             std::free(mparent_t::block->data);
00927           }
00928           std::free(mparent_t::block);
00929           mparent_t::size1=0;
00930           mparent_t::size2=0;
00931         }
00932       }
00933     }
00934 
00935     /// \name Memory allocation
00936     //@{
00937     /** \brief Allocate memory after freeing any memory
00938         presently in use
00939     */
00940     int allocate(size_t nrows, size_t ncols) {
00941       if (mparent_t::size1>0 || mparent_t::size2>0) free();
00942       
00943       if (nrows>0 && ncols>0) {
00944         mparent_t::block=(block_t *)malloc(sizeof(block_t));
00945         if (mparent_t::block) {
00946           mparent_t::block->data=(data_t *)
00947             malloc(nrows*ncols*sizeof(data_t));
00948           if (mparent_t::block->data) {
00949             mparent_t::block->size=nrows*ncols;
00950             mparent_t::data=mparent_t::block->data;
00951             mparent_t::size1=nrows;
00952             mparent_t::size2=ncols;
00953             mparent_t::tda=ncols;
00954             mparent_t::owner=1;
00955           } else {
00956             std::free(mparent_t::block);
00957             O2SCL_ERR_RET("No memory for data in omatrix_tlate::allocate()",
00958                           gsl_enomem);
00959           }
00960         } else {
00961           O2SCL_ERR_RET("No memory for block in omatrix_tlate::allocate()",
00962                         gsl_enomem);
00963         }
00964       } else {
00965         O2SCL_ERR_RET("Zero size in omatrix::allocate()",gsl_einval);
00966       }
00967       return 0;
00968     }
00969 
00970     /** \brief Free the memory 
00971     
00972         This function will safely do nothing if used without first
00973         allocating memory or if called multiple times in succession.
00974     */
00975     int free() {
00976       if (mparent_t::size1>0) {
00977         if (mparent_t::owner==1) {
00978           if (mparent_t::block->size>0) {
00979             std::free(mparent_t::block->data);
00980           }
00981           std::free(mparent_t::block);
00982         }
00983         mparent_t::size1=0;
00984         mparent_t::size2=0;
00985         mparent_t::tda=0;
00986       }
00987       return 0;
00988     }
00989     //@}
00990 
00991     /// \name Other methods
00992     //@{
00993     /// \brief Compute the transpose (even if matrix is not square)
00994     omatrix_tlate<data_t,mparent_t,vparent_t,block_t> transpose() {
00995       omatrix_tlate<data_t,mparent_t,vparent_t,block_t> 
00996         result(mparent_t::size2,mparent_t::size1);
00997       for(size_t i=0;i<mparent_t::size1;i++) {
00998         for(size_t j=0;j<mparent_t::size2;j++) {
00999           result[j][i]=(*this)[i][j];
01000         }
01001       }
01002     }
01003     //@}
01004     
01005   };
01006 
01007 #ifdef O2SCL_NEVER_DEFINED
01008 }
01009 {
01010 #endif
01011   
01012   /** \brief Create a matrix from an array 
01013   */
01014   template<class data_t, class mparent_t, class block_t> 
01015     class omatrix_array_tlate : 
01016   public omatrix_view_tlate<data_t,mparent_t,block_t> {
01017 
01018   public:
01019 
01020     /** \brief Create a vector from \c dat with size \c n */
01021     omatrix_array_tlate(data_t *dat, size_t ltda,
01022                         size_t sz1, size_t sz2)  {
01023       if (sz1==0 || sz2==0) {
01024         O2SCL_ERR("Failed to create omatrix from array, insufficient size.",
01025                   gsl_einval);
01026         mparent_t::block=0;
01027         mparent_t::data=0;
01028         mparent_t::size1=0;
01029         mparent_t::size2=0;
01030         mparent_t::tda=0;
01031         mparent_t::owner=0;
01032       }
01033       mparent_t::block=0;
01034       mparent_t::data=dat;
01035       mparent_t::size1=sz1;
01036       mparent_t::size2=sz2;
01037       mparent_t::tda=ltda;
01038       mparent_t::owner=0;
01039     }
01040   };
01041   
01042   /** \brief Create a vector from a row of a matrix 
01043    */
01044   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01045     class omatrix_row_tlate : 
01046   public ovector_view_tlate<data_t,vparent_t,block_t> {
01047   public:
01048     /** \brief Create a vector from row \c i of matrix \c m */
01049     omatrix_row_tlate
01050       (omatrix_base_tlate<data_t,mparent_t,block_t> &m, 
01051        size_t i) {
01052       if (i<m.size1) {
01053         vparent_t::size=m.size2;
01054         vparent_t::stride=1;
01055         vparent_t::data=m.data+m.tda()*i;
01056         vparent_t::owner=0;
01057         vparent_t::block=0;
01058       } else {
01059         O2SCL_ERR("Invalid row in omatrix_row_tlate constructor.",
01060                   gsl_einval);
01061         vparent_t::size=0;
01062         vparent_t::stride=0;
01063         vparent_t::data=0;
01064         vparent_t::owner=0;
01065         vparent_t::block=0;
01066       }
01067     }
01068   };
01069     
01070   /** \brief Create a const vector from a row of a matrix 
01071    */
01072   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01073     class omatrix_const_row_tlate :
01074   public ovector_const_view_tlate<data_t,vparent_t,block_t> {
01075   public:
01076     /** \brief Create a vector from row \c i of matrix \c m */
01077     omatrix_const_row_tlate
01078       (const omatrix_base_tlate<data_t,mparent_t,block_t> &m, 
01079        size_t i) {
01080       if (i<m.size1) {
01081         vparent_t::size=m.size2;
01082         vparent_t::stride=1;
01083         vparent_t::data=m.data+m.tda*i;
01084         vparent_t::owner=0;
01085         vparent_t::block=0;
01086       } else {
01087         O2SCL_ERR("Invalid row in omatrix_const_row_tlate constructor.",
01088                   gsl_einval);
01089         vparent_t::size=0;
01090         vparent_t::stride=0;
01091         vparent_t::data=0;
01092         vparent_t::owner=0;
01093         vparent_t::block=0;
01094       }
01095     }
01096   };
01097     
01098   /** \brief Create a vector from a column of a matrix
01099 
01100       \future Also do a umatrix constructor since we 
01101       can't do that with uvectors
01102    */
01103   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01104     class omatrix_col_tlate :
01105   public ovector_view_tlate<data_t,vparent_t,block_t> {
01106   public:
01107     /** \brief Create a vector from col \c i of matrix \c m */
01108     omatrix_col_tlate(omatrix_base_tlate<data_t,mparent_t,block_t> &m, 
01109                       size_t i) {
01110       if (i<m.size2) {
01111         vparent_t::size=m.size1;
01112         vparent_t::stride=m.tda();
01113         vparent_t::data=m.data+i;
01114         vparent_t::owner=0;
01115         vparent_t::block=0;
01116       } else {
01117         O2SCL_ERR("Invalid column in omatrix_col_tlate constructor.",
01118                   gsl_einval);
01119         vparent_t::size=0;
01120         vparent_t::stride=0;
01121         vparent_t::data=0;
01122         vparent_t::owner=0;
01123         vparent_t::block=0;
01124       }
01125     }
01126   };
01127     
01128   /** \brief Create a const vector from a column of a matrix
01129    */
01130   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01131     class omatrix_const_col_tlate :
01132   public ovector_const_view_tlate<data_t,vparent_t,block_t> {
01133   public:
01134     /** \brief Create a vector from col \c i of matrix \c m */
01135     omatrix_const_col_tlate
01136       (const omatrix_base_tlate<data_t,mparent_t,block_t> &m, size_t i) {
01137       if (i<m.size2) {
01138         vparent_t::size=m.size1;
01139         vparent_t::stride=m.tda();
01140         vparent_t::data=m.data+i;
01141         vparent_t::owner=0;
01142         vparent_t::block=0;
01143       } else {
01144         O2SCL_ERR("Invalid column in omatrix_const_col_tlate constructor.",
01145                   gsl_einval);
01146         vparent_t::size=0;
01147         vparent_t::stride=0;
01148         vparent_t::data=0;
01149         vparent_t::owner=0;
01150         vparent_t::block=0;
01151       }
01152     }
01153   };
01154   
01155   /** \brief Create a vector from the main diagonal
01156    */
01157   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01158     class omatrix_diag_tlate :
01159   public ovector_view_tlate<data_t,vparent_t,block_t> {
01160   public:
01161     /** \brief Create a vector of the diagonal of matrix \c m */
01162     omatrix_diag_tlate(omatrix_view_tlate<data_t,mparent_t,block_t> &m) {
01163       
01164       if (m.size2<m.size1) vparent_t::size=m.size2;
01165       else vparent_t::size=m.size1;
01166       vparent_t::stride=m.tda()+1;
01167       vparent_t::data=m.data;
01168       vparent_t::owner=0;
01169       vparent_t::block=0;
01170     }
01171   };
01172   
01173   /** \brief Create a vector from the main diagonal
01174    */
01175   template<class data_t, class mparent_t, class vparent_t, class block_t> 
01176     class omatrix_const_diag_tlate :
01177   public ovector_const_view_tlate<data_t,vparent_t,block_t> {
01178   public:
01179     /** \brief Create a vector of the diagonal of matrix \c m */
01180     omatrix_const_diag_tlate
01181       (const omatrix_view_tlate<data_t,mparent_t,block_t> &m) {
01182       
01183       if (m.size2<m.size1) vparent_t::size=m.size2;
01184       else vparent_t::size=m.size1;
01185       vparent_t::stride=m.tda()+1;
01186       vparent_t::data=m.data;
01187       vparent_t::owner=0;
01188       vparent_t::block=0;
01189     }
01190   };
01191   
01192     
01193   /// omatrix typedef
01194   typedef omatrix_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> omatrix;
01195   /// omatrix_view typedef
01196   typedef omatrix_view_tlate<double,gsl_matrix,gsl_block> omatrix_view;
01197   /// omatrix_const_view typedef
01198   typedef omatrix_const_view_tlate<double,gsl_matrix,gsl_block> 
01199     omatrix_const_view;
01200   /// omatrix_base typedef
01201   typedef omatrix_base_tlate<double,gsl_matrix,gsl_block> omatrix_base;
01202   /// omatrix_row typedef
01203   typedef omatrix_row_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> 
01204     omatrix_row;
01205   /// omatrix_col typedef
01206   typedef omatrix_col_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> 
01207     omatrix_col;
01208   /// omatrix_const_row typedef
01209   typedef omatrix_const_row_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> 
01210     omatrix_const_row;
01211   /// omatrix_const_col typedef
01212   typedef omatrix_const_col_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> 
01213     omatrix_const_col;
01214   /// omatrix_diag typedef
01215   typedef omatrix_diag_tlate<double,gsl_matrix,gsl_vector_norm,gsl_block> 
01216     omatrix_diag;
01217   /// omatrix_const_diag typedef
01218   typedef omatrix_const_diag_tlate<double,gsl_matrix,gsl_vector_norm,
01219     gsl_block> omatrix_const_diag;
01220   /// omatrix_array typedef
01221   typedef omatrix_array_tlate<double,gsl_matrix,gsl_block> 
01222     omatrix_array;
01223 
01224   /// omatrix_int typedef
01225   typedef omatrix_tlate<int,gsl_matrix_int,gsl_vector_int,gsl_block_int> 
01226     omatrix_int;
01227   /// omatrix_int_view typedef
01228   typedef omatrix_view_tlate<int,gsl_matrix_int,gsl_block_int> 
01229     omatrix_int_view;
01230   /// omatrix_int_base typedef
01231   typedef omatrix_base_tlate<int,gsl_matrix_int,gsl_block_int> 
01232     omatrix_int_base;
01233   /// omatrix_int_const_view typedef
01234   typedef omatrix_const_view_tlate<int,gsl_matrix_int,gsl_block_int> 
01235     omatrix_int_const_view;
01236   /// omatrix_int_row typedef
01237   typedef omatrix_row_tlate<int,gsl_matrix_int,gsl_vector_int,
01238     gsl_block_int> omatrix_int_row;
01239   /// omatrix_int_col typedef
01240   typedef omatrix_col_tlate<int,gsl_matrix_int,gsl_vector_int,
01241     gsl_block_int> omatrix_int_col;
01242   /// omatrix_int_const_row typedef
01243   typedef omatrix_const_row_tlate<int,gsl_matrix_int,gsl_vector_int,
01244     gsl_block_int> omatrix_int_const_row;
01245   /// omatrix_int_const_col typedef
01246   typedef omatrix_const_col_tlate<int,gsl_matrix_int,gsl_vector_int,
01247     gsl_block_int> omatrix_int_const_col;
01248   /// omatrix_int_diag typedef
01249   typedef omatrix_diag_tlate<int,gsl_matrix_int,gsl_vector_int,
01250     gsl_block_int> omatrix_int_diag;
01251   /// omatrix_int_const_diag typedef
01252   typedef omatrix_const_diag_tlate<int,gsl_matrix_int,gsl_vector_int,
01253     gsl_block_int> omatrix_int_const_diag;
01254   /// omatrix_int_array typedef
01255   typedef omatrix_array_tlate<int,gsl_matrix_int,gsl_block_int> 
01256     omatrix_int_array;
01257 
01258   /** \brief A operator for output of omatrix objects
01259 
01260       This outputs all of the matrix elements. Each row is output with
01261       an endline character at the end of each row. Positive values are
01262       preceeded by an extra space. A 2x2 example:
01263       \verbatim
01264       -3.751935e-05 -6.785864e-04
01265       -6.785864e-04  1.631984e-02
01266       \endverbatim
01267 
01268       The function \c gsl_ieee_double_to_rep() is used to determine
01269       the sign of a number, so that "-0.0" as distinct from "+0.0" 
01270       is handled correctly.
01271 
01272       \comment
01273       I had originally thought about removing this function, since
01274       it's superceded by matrix_out, but it's simpler to be able
01275       to just use the << operator so I keep it for now.
01276       \endcomment
01277 
01278       \future This assumes that scientific mode is on and showpos 
01279       is off. It'd be nice to fix this.
01280 
01281   */
01282   template<class data_t, class parent_t, class block_t>
01283     std::ostream &operator<<
01284     (std::ostream &os, 
01285      const omatrix_const_view_tlate<data_t,parent_t,block_t> &v) {
01286     size_t i;
01287     gsl_ieee_double_rep r;
01288     for(i=0;i<v.rows()-1;i++) {
01289       for(size_t j=0;j<v.cols();j++) {
01290         gsl_ieee_double_to_rep(&(v[i][j]), &r);
01291         if (r.sign==1) os << v[i][j] << ' ';
01292         else os << ' ' << v[i][j] << ' ';
01293       }
01294       os << '\n';
01295     }
01296     i=v.rows()-1;
01297     if (i>0) {
01298       for(size_t j=0;j<v.cols();j++) {
01299         gsl_ieee_double_to_rep(&(v[i][j]), &r);
01300         if (r.sign==1) os << v[i][j] << ' ';
01301         else os << ' ' << v[i][j] << ' ';
01302       }
01303     }
01304     return os;
01305   }
01306   
01307   /** \brief A simple class to provide an \c allocate() function
01308       for \ref omatrix
01309       
01310   */
01311   class omatrix_alloc {
01312   public:
01313     /// Allocate \c v for \c i elements
01314     void allocate(omatrix &o, size_t i, size_t j) { o.allocate(i,j); }
01315     /// Free memory
01316     void free(omatrix &o, size_t i) { o.free(); }
01317   };
01318 
01319 #ifdef DOXGYENP2
01320 
01321   /** \brief A matrix where the memory allocation is performed in 
01322       the constructor
01323   */
01324   template<size_t N, size_t M> class ofmatrix : public omatrix_tlate {
01325 
01326   public:
01327 
01328     /// Create a matrix
01329     ofmatrix();
01330   };
01331 
01332 #else 
01333 
01334   template<size_t N, size_t M> class ofmatrix : 
01335   public omatrix_tlate<double,gsl_matrix,gsl_vector,gsl_block>
01336     {
01337     public:
01338     ofmatrix() : omatrix_tlate<double,gsl_matrix,gsl_vector,
01339         gsl_block>(N,M) {
01340       }
01341     };
01342   
01343 #endif
01344 
01345   /** \brief A version of \ref omatrix with better error checking
01346 
01347       This demonstrates how operator[] could return an ovector_array
01348       object and thus provide more bounds-checking. This would demand
01349       including a new parameter in omatrix_view_tlate which contains
01350       the vector type.
01351   */
01352   class xmatrix : public omatrix {
01353   public:
01354   xmatrix(size_t r=0, size_t c=0) : omatrix(r,c) {
01355     }
01356     
01357     /** \brief Array-like indexing 
01358     */
01359     ovector_array operator[](size_t i) {
01360 #if O2SCL_NO_RANGE_CHECK
01361 #else
01362       if (i>=gsl_matrix::size1) {
01363         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
01364                    +" in omatrix_view_tlate::operator[]. Size: "+
01365                    itos(gsl_matrix::size1)+
01366                    " (index should be less than size).").c_str(),gsl_eindex);
01367       }
01368 #endif
01369       return ovector_array(gsl_matrix::size2,gsl_matrix::data+
01370                            i*gsl_matrix::tda);
01371     }
01372 
01373     /** \brief Array-like indexing 
01374     */
01375     const ovector_const_array operator[](size_t i) const {
01376 #if O2SCL_NO_RANGE_CHECK
01377 #else
01378       if (i>=gsl_matrix::size1) {
01379         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
01380                    +" in omatrix_view_tlate::operator[]. Size: "+
01381                    itos(gsl_matrix::size1)+
01382                    " (index should be less than size).").c_str(),gsl_eindex);
01383       }
01384 #endif
01385       return ovector_const_array(gsl_matrix::size2,gsl_matrix::data+
01386                                  i*gsl_matrix::tda);
01387     }
01388   };
01389 
01390 #ifndef DOXYGENP
01391 }
01392 #endif
01393 
01394 #endif
01395 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.