umatrix_cx_tlate.h

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

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

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