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