umatrix_cx_tlate.h

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

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