Object-oriented Scientific Computing Library: Version 0.910
umatrix_cx_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_CX_TLATE_H
00024 #define O2SCL_UMATRIX_CX_TLATE_H
00025 
00026 /** \file umatrix_cx_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 #include <o2scl/uvector_cx_tlate.h>
00042 
00043 #ifndef DOXYGENP
00044 namespace o2scl {
00045 #endif
00046 
00047   /** \brief A matrix view of complex numbers
00048   */
00049   template<class data_t, class complex_t> class umatrix_cx_view_tlate {
00050     
00051 #ifndef DOXYGEN_INTERNAL
00052 
00053     protected:
00054 
00055     /// The data
00056     data_t *data;
00057     /// The number of rows
00058     size_t size1;
00059     /// The number of columns
00060     size_t size2;
00061     /// Zero if memory is owned elsewhere, 1 otherwise
00062     int owner;
00063 
00064 #endif
00065 
00066   public:
00067     
00068     /// \name Copy constructors
00069     //@{
00070     /// So2scllow copy constructor - create a new view of the same matrix
00071     umatrix_cx_view_tlate(const umatrix_cx_view_tlate &v) {
00072       data=v.data;
00073       size1=v.size1;
00074       size2=v.size2;
00075       owner=0;      
00076     }
00077     
00078     /// So2scllow copy constructor - create a new view of the same matrix
00079     umatrix_cx_view_tlate& operator=(const umatrix_cx_view_tlate &v) {
00080       data=v.data;
00081       size1=v.size1;
00082       size2=v.size2;
00083       owner=0;      
00084 
00085       return *this;
00086     }
00087     //@}
00088 
00089     ~umatrix_cx_view_tlate() {};
00090     
00091     /// \name Get and set methods
00092     //@{
00093     /** \brief Array-like indexing 
00094     */
00095     complex_t *operator[](size_t i) {
00096 #if O2SCL_NO_RANGE_CHECK
00097 #else
00098       if (i>=size1) {
00099         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00100                  +" in umatrix_cx_view_tlate::operator[]. Size: "+
00101                  itos(size1)+
00102                  " (index should be less than size).").c_str(),gsl_eindex);
00103         return (complex_t *)data;
00104       }
00105 #endif
00106       return (complex_t *)(data+2*i*size2);
00107     }
00108     
00109     /** \brief Array-like indexing 
00110     */
00111     const complex_t *operator[](size_t i) const {
00112 #if O2SCL_NO_RANGE_CHECK
00113 #else
00114       if (i>=size1) {
00115         O2SCL_ERR((((std::string)"Array index ")+itos(i)+" out of bounds"
00116                  +" in umatrix_cx_view_tlate::operator[] const. Size: "+
00117                  itos(size1)+
00118                  " (index should be less than size).").c_str(),gsl_eindex);
00119         return (const complex_t *)data;
00120       }
00121 #endif
00122       return (const complex_t *)(data+2*i*size2);
00123     }
00124     
00125     /** \brief Array-like indexing 
00126     */
00127     complex_t &operator()(size_t i, size_t j) {
00128 #if O2SCL_NO_RANGE_CHECK
00129 #else
00130       if (i>=size1 || j>=size2) {
00131         O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+
00132                  ") out of bounds"
00133                  +" in umatrix_cx_view_tlate::operator(). Sizes: ("+
00134                  itos(size1)+","+itos(size2)+
00135                  ") (index should be less than size).").c_str(),gsl_eindex);
00136         return *(complex_t *)data;
00137       }
00138 #endif
00139       return *(complex_t *)(data+2*(i*size2+j));
00140     }
00141     
00142     /** \brief Array-like indexing 
00143     */
00144     const complex_t &operator()(size_t i, size_t j) const {
00145 #if O2SCL_NO_RANGE_CHECK
00146 #else
00147       if (i>=size1 || j>=size2) {
00148         O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+
00149                  ") out of bounds"
00150                  +" in umatrix_cx_view_tlate::operator() const. Sizes: ("+
00151                  itos(size1)+","+itos(size2)+
00152                  ") (index should be less than size).").c_str(),gsl_eindex);
00153         return *(const complex_t *)data;
00154       }
00155 #endif
00156       return *(const complex_t *)(data+2*(i*size2+j));
00157     }
00158     
00159     /** \brief Get (with optional range-checking) */
00160     complex_t get(size_t i, size_t j) const {
00161 #if O2SCL_NO_RANGE_CHECK
00162 #else
00163       if (i>=size1 || j>=size2) {
00164         O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+
00165                  ") out of bounds"
00166                  +" in umatrix_cx_view_tlate::get(). Sizes: ("+
00167                  itos(size1)+","+itos(size2)+
00168                  ") (index should be less than size).").c_str(),gsl_eindex);
00169         return *(complex_t *)data;
00170       }
00171 #endif
00172       return *(complex_t *)(data+2*(i*size2+j));
00173     }
00174     
00175     /** \brief Get pointer (with optional range-checking) */
00176     complex_t *get_ptr(size_t i, size_t j) {
00177 #if O2SCL_NO_RANGE_CHECK
00178 #else
00179       if (i>=size1 || j>=size2) {
00180         O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+
00181                  ") out of bounds"
00182                  +" in umatrix_cx_view_tlate::get_ptr(). Sizes: ("+
00183                  itos(size1)+","+itos(size2)+
00184                  ") (index should be less than size).").c_str(),gsl_eindex);
00185         return (complex_t *)data;
00186       }
00187 #endif
00188       return (complex_t *)(data+2*(i*size2+j));
00189     }
00190     
00191     /** \brief Get pointer (with optional range-checking) */
00192     const complex_t *get_const_ptr(size_t i, size_t j) const {
00193 #if O2SCL_NO_RANGE_CHECK
00194 #else
00195       if (i>=size1 || j>=size2) {
00196         O2SCL_ERR((((std::string)"Indices (")+itos(i)+","+itos(j)+
00197                  ") out of bounds"
00198                  +" in umatrix_cx_view_tlate::get_const_ptr(). Sizes: ("+
00199                  itos(size1)+","+itos(size2)+
00200                  ") (index should be less than size).").c_str(),gsl_eindex);
00201         return (const complex_t *)data;
00202       }
00203 #endif
00204       return (const complex_t *)(data+2*(i*size2+j));
00205     }
00206     
00207     /** \brief Set (with optional range-checking) */
00208     int set(size_t i, size_t j, complex_t val) {
00209 #if O2SCL_NO_RANGE_CHECK
00210 #else
00211       if (i>=size1 || j>=size2) {
00212         O2SCL_ERR_RET((((std::string)"Indices (")+itos(i)+","+itos(j)+
00213                      ") out of bounds"
00214                      +" in umatrix_cx_view_tlate::set(i,j,val). Sizes: ("+
00215                      itos(size1)+","+itos(size2)+
00216                      ") (index should be less than size).").c_str(),
00217                     gsl_eindex);
00218       }
00219 #endif
00220       *(data+2*(i*size2+j))=GSL_REAL(val);
00221       *(data+2*(i*size2+j)+1)=GSL_IMAG(val);
00222       return 0;
00223     }
00224 
00225     /** \brief Set (with optional range-checking) */
00226     int set(size_t i, size_t j, data_t re, data_t im) {
00227 #if O2SCL_NO_RANGE_CHECK
00228 #else
00229       if (i>=size1 || j>=size2) {
00230         O2SCL_ERR_RET((((std::string)"Indices (")+itos(i)+","+itos(j)+
00231                      ") out of bounds"
00232                      +" in umatrix_cx_view_tlate::set(i,j,re,im). Sizes: ("+
00233                      itos(size1)+","+itos(size2)+
00234                      ") (index should be less than size).").c_str(),
00235                     gsl_eindex);
00236       }
00237 #endif
00238       *(data+2*(i*size2+j))=re;
00239       *(data+2*(i*size2+j)+1)=im;
00240       return 0;
00241     }
00242 
00243     /** \brief Set all of the value to be the value \c val */
00244     int set_all(complex_t val) {
00245       for(size_t i=0;i<size1;i++) {
00246         for(size_t j=0;j<size2;j++) {
00247           *(data+2*(i*size2+j))=GSL_REAL(val);
00248           *(data+2*(i*size2+j)+1)=GSL_IMAG(val);
00249         }
00250       }
00251       return 0;
00252     }
00253 
00254     /** \brief Method to return number of rows
00255         
00256         If no memory has been allocated, this will quietly 
00257         return zero.
00258     */
00259     size_t rows() const {
00260       return size1;
00261     }
00262 
00263     /** \brief Method to return number of columns
00264         
00265         If no memory has been allocated, this will quietly 
00266         return zero.
00267     */
00268     size_t cols() const {
00269       return size2;
00270     }
00271     //@}
00272 
00273     /// \name Other methods
00274     //@{
00275     /// Return true if this object owns the data it refers to
00276     bool is_owner() const {
00277       if (owner==1) return true;
00278       return false;
00279     }
00280     //@}
00281 
00282     /// \name Arithmetic 
00283     //@{
00284     /** \brief operator+= */
00285     umatrix_cx_view_tlate<data_t,complex_t> &operator+=
00286       (const umatrix_cx_view_tlate<data_t,complex_t> &x) {
00287       size_t lsize=x.size1;
00288       if (lsize>size1) lsize=size1;
00289       size_t lsize2=x.size2;
00290       if (lsize2>size2) lsize2=size2;
00291       for(size_t i=0;i<lsize;i++) {
00292         for(size_t j=0;j<lsize2;j++) {
00293           (*this)[i][j]+=x[i][j];
00294         }
00295       }
00296       
00297       return *this;
00298     }
00299     
00300     /** \brief operator-= */
00301     umatrix_cx_view_tlate<data_t,complex_t> &operator-=
00302       (const umatrix_cx_view_tlate<data_t,complex_t> &x) {
00303       size_t lsize=x.size1;
00304       if (lsize>size1) lsize=size1;
00305       size_t lsize2=x.size2;
00306       if (lsize2>size2) lsize2=size2;
00307       for(size_t i=0;i<lsize;i++) {
00308         for(size_t j=0;j<lsize2;j++) {
00309           (*this)[i][j]+=x[i][j];
00310         }
00311       }
00312 
00313       return *this;
00314     }
00315     
00316     /** \brief operator+= */
00317     umatrix_cx_view_tlate<data_t,complex_t> &operator+=(const data_t &y) {
00318       for(size_t i=0;i<size1;i++) {
00319         for(size_t j=0;j<size2;j++) {
00320           (*this)[i][j]+=y;
00321         }
00322       }
00323       
00324       return *this;
00325     }
00326 
00327     /** \brief operator-= */
00328     umatrix_cx_view_tlate<data_t,complex_t> &operator-=(const data_t &y) {
00329       for(size_t i=0;i<size1;i++) {
00330         for(size_t j=0;j<size2;j++) {
00331           (*this)[i][j]-=y;
00332         }
00333       }
00334       
00335       return *this;
00336     }
00337 
00338     /** \brief operator*= */
00339     umatrix_cx_view_tlate<data_t,complex_t> &operator*=(const data_t &y) {
00340       for(size_t i=0;i<size1;i++) {
00341         for(size_t j=0;j<size2;j++) {
00342           (*this)[i][j]*=y;
00343         }
00344       }
00345       
00346       return *this;
00347     }
00348     //@}
00349 
00350 #ifndef DOXYGEN_INTERNAL
00351 
00352   protected:
00353 
00354     /** \brief Empty constructor provided for use by 
00355         umatrix_cx_tlate(const umatrix_cx_tlate &v)
00356     */
00357     umatrix_cx_view_tlate() {};
00358 
00359 #endif
00360     
00361   };
00362 
00363   /** \brief A matrix of double-precision numbers
00364   
00365   */
00366   template<class data_t, class complex_t> class umatrix_cx_tlate : 
00367   public umatrix_cx_view_tlate<data_t,complex_t> {
00368   public:
00369     
00370     /// \name Standard constructor
00371     //@{
00372     /** \brief Create an umatrix of size \c n with owner as 'true' 
00373      */
00374     umatrix_cx_tlate(size_t r=0, size_t c=0) {
00375 
00376       this->data=0;
00377       this->size1=0;
00378       this->size2=0;
00379 
00380       // This must be set to 1 even if n=0 so that future
00381       // calls to operator= work properly
00382       this->owner=1;
00383       
00384       if (r>0 && c>0) {
00385         this->data=(data_t *)malloc(2*r*c*sizeof(data_t));
00386         if (this->data) {
00387           this->size1=r;
00388           this->size2=c;
00389         } else {
00390           O2SCL_ERR("No memory for data in umatrix_cx_tlate constructor",
00391                   gsl_enomem);
00392         }
00393       }
00394     }
00395     //@}
00396     
00397     /// \name Copy constructors
00398     //@{
00399     /// Deep copy constructor, allocate new space and make a copy
00400     umatrix_cx_tlate(const umatrix_cx_tlate &v) : 
00401       umatrix_cx_view_tlate<data_t,complex_t>() {
00402       size_t n=v.size1;
00403       size_t n2=v.size2;
00404       if (n>0 && n2>0) {
00405         this->data=(data_t *)malloc(2*n*n2*sizeof(data_t));
00406         if (this->data) {
00407           this->size1=n;
00408           this->size2=n2;
00409           this->owner=1;
00410           for(size_t i=0;i<n;i++) {
00411             for(size_t j=0;j<n2;j++) {
00412               *(this->data+i*this->size2+j)=v[i][j];
00413             }
00414           }
00415         } else {
00416           O2SCL_ERR("No memory for data in umatrix_cx_tlate constructor",
00417                   gsl_enomem);
00418         }
00419       } else {
00420         this->size1=0;
00421         this->size2=0;
00422       }
00423     }
00424     
00425       /// Deep copy constructor, allocate new space and make a copy
00426       umatrix_cx_tlate
00427         (const umatrix_cx_view_tlate<data_t,complex_t> &v) : 
00428           umatrix_cx_view_tlate<data_t,complex_t>() {
00429           size_t r=v.rows();
00430           size_t c=v.cols();
00431           if (r>0 && c>0) {
00432             this->data=(data_t *)malloc(2*r*c*sizeof(data_t));
00433             if (this->data) {
00434               this->size1=v.size1;
00435               this->size2=v.size2;
00436               this->owner=1;
00437               for(size_t i=0;i<r;i++) {
00438                 for(size_t j=0;i<c;j++) {
00439                   *(this->data+i*this->size2+j)=v[i][j];
00440                 }
00441               }
00442             } else {
00443               O2SCL_ERR("No memory for data in umatrix_cx_tlate constructor",
00444                       gsl_enomem);
00445             }
00446           } else {
00447             this->size1=0;
00448             this->size2=0;
00449           }
00450         }
00451     
00452         /** \brief Deep copy constructor, if owner is true, allocate space and
00453             make a new copy, otherwise, just copy into the view
00454         */
00455         umatrix_cx_tlate& operator=(const umatrix_cx_tlate &v) {
00456 
00457       // Check for self-assignment
00458       if (this==&v) return *this;
00459 
00460           size_t sze=v.size1;
00461           size_t sze2=v.size2;
00462           if (this->owner) {
00463             allocate(sze,sze2);
00464           } else {
00465             if (this->size1!=sze || this->size2!=sze2) {
00466               O2SCL_ERR("Sizes don't match in umatrix_cx_tlate::operator=()",
00467                       gsl_ebadlen);
00468               return *this;
00469             }
00470           }
00471           for(size_t i=0;i<sze;i++) {
00472             for(size_t j=0;j<sze2;j++) {
00473               *(this->data+i*this->size2+j)=v[i][j];
00474             }
00475           }
00476           return *this;
00477         }
00478 
00479         /** \brief Deep copy constructor, if owner is true, allocate space and
00480             make a new copy, otherwise, just copy into the view
00481         */
00482         umatrix_cx_tlate& operator=
00483           (const umatrix_cx_view_tlate<data_t,complex_t> &v) {
00484 
00485       // Check for self-assignment
00486       if (this==&v) return *this;
00487 
00488           size_t sze=v.rows();
00489           size_t sze2=v.cols();
00490           if (this->owner) {
00491             allocate(sze,sze2);
00492           } else {
00493             if (this->size1!=sze || this->size2!=sze2) {
00494               O2SCL_ERR("Sizes don't match in umatrix_cx_tlate::operator=()",
00495                       gsl_ebadlen);
00496               return *this;
00497             }
00498           }
00499           for(size_t i=0;i<sze;i++) {
00500             for(size_t j=0;j<sze2;j++) {
00501               *(this->data+i*this->size2+j)=v[i][j];
00502             }
00503           }
00504           return *this;
00505         }
00506     
00507         /** \brief Deep copy from an array of uvectors
00508          */
00509         umatrix_cx_tlate(size_t n, 
00510                          uvector_cx_view_tlate<data_t,complex_t> uva[]) {
00511           if (n>0) {
00512             size_t n2=uva[0];
00513             if (n2>0) {
00514               allocate(n,n2);
00515               for(size_t i=0;i<n;i++) {
00516                 for(size_t j=0;j<n2;j++) {
00517                   (*this)[i][j]=uva[i][j];
00518                 }
00519               }
00520             }
00521           }
00522         }
00523 
00524         /** \brief Deep copy from a C-style 2-d array
00525          */
00526         umatrix_cx_tlate(size_t n, size_t n2, data_t **csa) {
00527           if (n>0 && n2>0) {
00528             allocate(n,n2);
00529             for(size_t i=0;i<n;i++) {
00530               for(size_t j=0;j<n2;j++) {
00531                 (*this)[i][j]=csa[i][j];
00532               }
00533             }
00534           }
00535         }
00536 
00537         //@}
00538     
00539         ~umatrix_cx_tlate() {
00540           if (this->size1>0) {
00541             if (this->owner==1) {
00542               std::free(this->data);
00543               this->size1=0;
00544               this->size2=0;
00545             }
00546           }
00547         }
00548 
00549         /// \name Memory allocation
00550         //@{
00551         /** \brief Allocate memory after freeing any memory presently in use
00552         */
00553         int allocate(size_t nrows, size_t ncols) {
00554           if (this->size1>0 || this->size2>0) free();
00555       
00556           if (nrows>0 && ncols>0) {
00557             this->data=(data_t *)malloc(2*nrows*ncols*sizeof(data_t));
00558             if (this->data) {
00559               this->size1=nrows;
00560               this->size2=ncols;
00561               this->owner=1;
00562             } else {
00563               O2SCL_ERR2_RET("No memory for data in ",
00564                              "umatrix_cx_tlate::allocate()",
00565                              gsl_enomem);
00566             }
00567           } else {
00568             O2SCL_ERR_RET("Zero size in umatrix::allocate()",gsl_einval);
00569           }
00570           return 0;
00571         }
00572 
00573         /** \brief Free the memory 
00574     
00575             This function will safely do nothing if used without first
00576             allocating memory or if called multiple times in succession.
00577         */
00578         int free() {
00579           if (this->size1>0) {
00580             if (this->owner==1) {
00581               std::free(this->data);
00582             }
00583             this->size1=0;
00584             this->size2=0;
00585           }
00586           return 0;
00587         }
00588         //@}
00589 
00590         /// \name Other methods
00591         //@{
00592         /** \brief Compute the transpose (even if matrix is not square)
00593          */
00594         umatrix_cx_tlate<data_t,complex_t> transpose() {
00595           umatrix_cx_tlate<data_t,complex_t> result(this->size2,this->size1);
00596           for(size_t i=0;i<this->size1;i++) {
00597             for(size_t j=0;j<this->size2;j++) {
00598               result[j][i]=(*this)[i][j];
00599             }
00600           }
00601         }
00602         //@}
00603     
00604   };
00605 
00606   /** \brief Create a vector from a row of a matrix 
00607    */
00608   template<class data_t, class complex_t> class umatrix_cx_row_tlate : 
00609   public uvector_cx_view_tlate<data_t,complex_t> {
00610   public:
00611     /** \brief Create a vector from row \c i of matrix \c m */
00612     umatrix_cx_row_tlate(umatrix_cx_view_tlate<data_t,complex_t> &m, 
00613                          size_t i) {
00614       if (i<m.rows()) {
00615         this->sz=m.cols();
00616         this->data=m[0]+m.cols()*i;
00617         this->owner=0;
00618       }
00619     }
00620   };
00621     
00622   /** \brief Create a const vector from a row of a matrix 
00623    */
00624   template<class data_t, class complex_t> class umatrix_cx_const_row_tlate :
00625   public uvector_cx_view_tlate<data_t,complex_t> {
00626   public:
00627     /** \brief Create a vector from row \c i of matrix \c m */
00628     umatrix_cx_const_row_tlate
00629       (const umatrix_cx_view_tlate<data_t,complex_t> &m, 
00630        size_t i) {
00631       if (i<m.size1) {
00632         this->sz=m.cols();
00633         this->data=m[0]+m.cols()*i;
00634         this->owner=0;
00635       }
00636     }
00637   };
00638     
00639   /// umatrix_cx typedef
00640   typedef umatrix_cx_tlate<double,gsl_complex> umatrix_cx;
00641   /// umatrix_cx_view typedef
00642   typedef umatrix_cx_view_tlate<double,gsl_complex> umatrix_cx_view;
00643   /// umatrix_cx_row typedef
00644   typedef umatrix_cx_row_tlate<double,gsl_complex> umatrix_cx_row;
00645   /// umatrix_cx_const_row typedef
00646   typedef umatrix_cx_const_row_tlate<double,gsl_complex> 
00647     umatrix_cx_const_row;
00648 
00649   /** \brief A operator for naive matrix output
00650       
00651       This outputs all of the matrix elements. Each row is output with
00652       an endline character at the end of each row. Positive values are
00653       preceeded by an extra space. A 2x2 example:
00654       \verbatim
00655       -3.751935e-05 -6.785864e-04
00656       -6.785864e-04  1.631984e-02
00657       \endverbatim
00658 
00659       The function \c gsl_ieee_double_to_rep() is used to determine
00660       the sign of a number, so that "-0.0" as distinct from "+0.0" 
00661       is handled correctly.
00662 
00663       \note At the moment, this function assumes that scientific
00664       mode is on and showpos is off. 
00665 
00666       \future Make this function work even when scientific mode is
00667       not on, either by converting to scientific mode and converting
00668       back, or by leaving scientific mode off and padding with spaces
00669   */
00670   template<class data_t, class complex_t> std::ostream &operator<<
00671     (std::ostream &os, const umatrix_cx_view_tlate<data_t,complex_t> &v) {
00672     size_t i;
00673     gsl_ieee_double_rep r;
00674     for(i=0;i<v.rows()-1;i++) {
00675       for(size_t j=0;j<v.cols();j++) {
00676         gsl_ieee_double_to_rep(&(v[i][j]), &r);
00677         if (r.sign==1) os << v[i][j] << ' ';
00678         else os << ' ' << v[i][j] << ' ';
00679       }
00680       os << '\n';
00681     }
00682     i=v.rows()-1;
00683     if (i>0) {
00684       for(size_t j=0;j<v.cols();j++) {
00685         gsl_ieee_double_to_rep(&(v[i][j]), &r);
00686         if (r.sign==1) os << v[i][j] << ' ';
00687         else os << ' ' << v[i][j] << ' ';
00688       }
00689     }
00690     return os;
00691   }
00692   
00693   /** \brief A simple class to provide an \c allocate() function
00694       for \ref umatrix_cx
00695   */
00696   class umatrix_cx_alloc {
00697   public:
00698     /// Allocate \c v for \c i elements
00699     void allocate(umatrix_cx &o, int i, int j) { o.allocate(i,j); }
00700     /// Free memory
00701     void free(umatrix_cx &o) { o.free(); }
00702   };
00703 
00704   /** \brief A matrix where the memory allocation is performed in 
00705       the constructor
00706   */
00707 #ifdef DOXYGENP
00708   template<size_t N, size_t M> class ufmatrix_cx : 
00709   public umatrix_cx_tlate<data_t,complex_t>
00710 #else  
00711     template<size_t N, size_t M> class ufmatrix_cx :   
00712   public umatrix_cx_tlate<double,gsl_complex>
00713 #endif
00714   {
00715   public:
00716     ufmatrix_cx() : umatrix_cx_tlate<double,gsl_complex>(N,M) {
00717     }
00718   };
00719   
00720   
00721 #ifndef DOXYGENP
00722 }
00723 #endif
00724 
00725 #endif
00726 
00727 
00728 
 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.