Department of Scientific Computing   
Institute for Numerical Simulation   
University of Bonn   
Documentation
Download
Programming References
Bug Reports / Suggestions
FAQ
Authors
Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Matrix.hpp

00001 //
00002 //
00003 //  Templates for  D-dimensional arrays  
00004 //
00005 //
00006 
00007 #ifndef _DARRAY_
00008 # define _DARRAY_
00009 
00010 #include "Math.hpp"
00011 #include "UDF.h"
00012 #include "Wavelet.hpp"
00013 
00014 #include "Function.hpp"
00015 #include "SparseMatrixIO.hpp"
00016 #include "UDFInformation.hpp"
00017 
00021 template<class I,int DIM>
00022 class Matrix {
00023 public:
00025                  Matrix() ;
00027                  Matrix(int *begin,int *end) ;
00029         void     Init  (int *begin,int *end) ;
00030                 ~Matrix() ;
00031         void     Clear () ;
00032 
00034 struct iterator {
00035 public:
00036         int      i[DIM] ;
00038                  iterator() ;
00040                  iterator(Matrix<I,DIM> *d) ;
00042                  iterator(Matrix<I,DIM> *d,int constcoordinate) ;
00044                  iterator(const int *begin,const int *end) ;
00046                  iterator(const int *begin,const int *end , int constcoordinate) ;
00048        iterator& operator++() ;
00050         bool     operator!=(const  Matrix<I,DIM>::iterator& x) const ;
00052         bool     operator<=(const  Matrix<I,DIM>::iterator& x) const ;
00054         bool     operator<=(const  int b[DIM]) const ;
00056         bool     operator>=(const  int b[DIM]) const ;
00058         void     Set      (const int *j) ;
00059 //        void     Set      (const int *j , const int drop  ) ;
00061         void     SetBounds(const int *b,const int *e) ;
00063         void     Print() ;
00064 
00065 friend class Matrix<I,DIM> ;
00066   // private:
00067    int b[DIM],e[DIM],a[DIM],dim ;
00068 } ;
00069 
00071   inline I&       operator[](const iterator &it) ;
00073   inline I&       operator[](const int *in) ;
00074   inline I&       operator[](const unsigned int  *in) ;
00075   inline I&       operator[](const unsigned char *in) ;
00077   inline iterator begin()         const ;
00079   inline iterator begin(int constcoordinate) const ; 
00081   inline iterator end  ()         const ;
00083   inline int      size (const int i) const ;
00084 
00085   void            CalcLevel(int *J) ;
00086   void            SameSize (Matrix<I,DIM> *X) ;
00088   void            Print(int l=0) ;
00090   void            Set  (const I& i)  ;
00093   void            Set  (Function *F) ;
00095   void            Copy (Matrix<I,DIM> *X) ;
00097   void            Set  (Matrix<I,DIM> *X) ;
00098 
00101   void            Abs  (Matrix<I,DIM> *X) ;
00103   void            Pow  (Matrix<I,DIM> *X, double p) ;
00105   void            Sqr  (Matrix<I,DIM> *X) ;
00107   void            PPlus(Matrix<I,DIM> *X) ;
00109   void            PPlus(const double a , Matrix<I,DIM> *X) ;
00111   void            Add  (Matrix<I,DIM> *X , Matrix<I,DIM> *Y) ;
00113   void            Add  (const double a , Matrix<I,DIM> *X , const double b , Matrix<I,DIM> *Y) ;
00115   void            Add  (const double a , Matrix<I,DIM> *X , const double b , Matrix<I,DIM> *Y , const double c , Matrix<I,DIM> *Z) ;
00117   void            Add  (const double a , Matrix<I,DIM> *X , const double b , Matrix<I,DIM> *Y , const double c , Matrix<I,DIM> *Z , const double d , Matrix<I,DIM> *Q) ;
00119   void            Add  (const double a , Matrix<I,DIM> *X , const double b , Matrix<I,DIM> *Y , const double c , Matrix<I,DIM> *Z , const double d , Matrix<I,DIM> *Q , const double f , Matrix<I,DIM> *R) ;
00121   void            MMinus(Matrix<I,DIM> *X) ;
00123   void            MMinus(const double a, Matrix<I,DIM> *X) ;
00125   void            Sub(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) ;
00127   double          InnerProd(Matrix<I,DIM> *X) ;
00129   void            Mul  (Matrix<I,DIM> *X , Matrix<I,DIM> *Y) ;
00131   void            Mul  (Matrix<I,DIM> *X , Matrix<I,DIM> *Y , const double f) ;
00133   void            Mul  (Matrix<I,DIM> *X , const double f) ;
00135   void            Mul  (const double f) ;
00136 
00138   void            Multiply(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) ;
00139 
00140         void     XplusYmalZ (Matrix<I,DIM>*X , Matrix<I,DIM>*Y , Matrix<I,DIM>*Z) ;
00141         void     XminusYmalZ(Matrix<I,DIM>*X , Matrix<I,DIM>*Y , Matrix<I,DIM>*Z) ;
00142 
00144   double          Min() ;
00146   double          Max() ;
00148   double          MaxAbs() ;
00150   double          Sum()    ;
00152   double          SumAbs() ;
00154   double          SumSqr() ;
00156   void            Transpose(Matrix<I,DIM> *X) ;// DIM must be 2
00157 
00158   void            Smooth(Matrix<I,DIM> *X, int type=0) ;
00159 
00160   typedef void (*UniDirOperation)(double *d,int *BCd, int *dec, double *c,int *BCc, Wavelets *From,int J,int lev , double DX) ;
00161  
00164   void            WriteUDF(const char *filename, Extensions<DIM> *E, const char *ScalarOrVectorName,
00165                            Matrix<I,DIM> **M,int NM, bool castfloat=false, bool ascii=false) ;
00168   void            ReadUDF (const char *filename, Extensions<DIM> *E, const char *ScalarOrVectorComponentName) ;
00169 
00170   // writes a sparse matrix of all elements |Aij|>=eps
00171   // file can be read by ReadSparse.m
00172   //void           WriteMATLABSparse(const char *filename, double eps) ;
00173   void            ReadSparse (const char *filename, double *XA, double *XE , int Level0, int which) ;
00174   void            WriteSparse(const char *filename, double *XA, double *XE , int Level0, 
00175                               Matrix<I,DIM> **M=NULL, int N=0, bool CastToFloat=false) ;
00176 
00177   void           ReadMATLAB(const char *filename) ;
00178 
00179 friend struct iterator ;
00180 
00181 public:
00182  int b[DIM],e[DIM],o[DIM],o1 ;
00183  I*  s              ;
00184 } ;
00185 
00186 
00187 //
00188 // iterator
00189 //
00190 
00191 //template<class I,int DIM>
00192 //struct Matrix<I,DIM>::iterator 
00193 
00194 /*****************************************/
00195 /*                                       */
00196 /*           Implementierungen           */
00197 /*                                       */
00198 /*****************************************/
00199 
00200 //
00201 // Matrix 
00202 template<class I,int DIM>
00203 Matrix<I,DIM>::Matrix()  
00204 { 
00205  for (int k=0;k<DIM;k++) { b[k]=0 , e[k]=-1 ;} 
00206  s=NULL ;
00207 }
00208 
00209 template<class I,int DIM>
00210 Matrix<I,DIM>::Matrix(int *bb,int *ee) { s=NULL ; Init(bb,ee) ;}
00211 
00212 template<class I,int DIM>
00213 void Matrix<I,DIM>::Init(int *bb,int *ee) {
00214   int   c=1,k ; 
00215 
00216   if (s!=NULL) {
00217     bool resize=false ;
00218     for (k=0;k<DIM;k++) if ((ee[k]-bb[k])!=(e[k]-b[k])) resize=true ;
00219     if (resize) {
00220       std::cout<<"Matrix Resize!\n" ;
00221       Clear() ;
00222     }
00223   }
00224 
00225   for (k=0;k<DIM;k++) { b[k]=bb[k] , e[k]=ee[k] , c*=(e[k]-b[k]+1) ; assert (c>0) ;}
00226   c*=sizeof(I) ;
00227 
00228   if (s==0) s=(I *)malloc(c) ;
00229   if (s==NULL) {
00230     std::cout<<"Matrix<"<<DIM<<">::Init could not allocate "<<c<<" bytes \n" ;
00231     exit(-1) ;
00232   }
00233 
00234   o1=0 ;
00235   c=1  ;
00236   for (k=DIM-1;k>=0;k--) { o[k]=c , c*=(e[k]-b[k]+1) ; o1 +=o[k]*b[k] ;}  
00237 }
00238 
00239 
00240 template<class I,int DIM>
00241 void Matrix<I,DIM>::Clear()  { free(s) ; for (int k=0;k<DIM;k++) b[k]=0 , e[k]=-1 ; s=NULL ; }
00242 
00243 template<class I,int DIM>
00244 Matrix<I,DIM>::~Matrix()  { 
00245   Clear() ;
00246 }
00247 
00248 template<class I,int DIM>
00249 inline I& Matrix<I,DIM>::operator[](const Matrix<I,DIM>::iterator &it) { return (*this)[&it.i[0]] ;}
00250 
00251 template<class I,int DIM>
00252 inline I& Matrix<I,DIM>::operator[](const int *in) {
00253   int i=in[DIM-1]-o1 ;
00254   for (int k=DIM-2 ;k>=0;k--) i+= in[k]*o[k] ;
00255   return s[i] ;
00256 }
00257 
00258 template<class I,int DIM>
00259 inline I& Matrix<I,DIM>::operator[](const unsigned int *in) {
00260   int i=in[DIM-1]-o1 ;
00261   for (int k=DIM-2 ;k>=0;k--) i+= in[k]*o[k] ;
00262   return s[i] ;
00263 }
00264 
00265 template<class I,int DIM>
00266 inline I& Matrix<I,DIM>::operator[](const unsigned char *in) {
00267   int i=in[DIM-1]-o1 ;
00268   for (int k=DIM-2 ;k>=0;k--) i+= in[k]*o[k] ;
00269   return s[i] ;
00270 }
00271 
00272 
00273 template<class I,int DIM>
00274 Matrix<I,DIM>::iterator Matrix<I,DIM>::begin() const { return begin(-1) ; } 
00275 
00276 template<class I,int DIM>
00277 Matrix<I,DIM>::iterator Matrix<I,DIM>::begin(int drop) const {
00278  iterator tmp ;
00279  tmp.dim=0 ;
00280  for (int k=0;k<DIM;k++) { tmp.b[k]=tmp.i[k]=b[k] ; tmp.e[k]=e[k] ; if(k!=drop) tmp.a[tmp.dim++]=k ;}
00281  return tmp ;
00282 } 
00283 
00284 
00285 template<class I,int DIM>
00286 Matrix<I,DIM>::iterator Matrix<I,DIM>::end()   const {
00287  iterator tmp    ;
00288  for (int i=0;i<DIM;i++) tmp.i[i]=e[i] ;
00289  return tmp ;
00290 } 
00291 
00292 template<class I,int DIM>
00293 int Matrix<I,DIM>::size(const int i) const {
00294   if ((0<=i) && (i<DIM)) return e[i]-b[i]+1 ;
00295   else                   return 0 ;
00296 }
00297 
00298 template<class I,int DIM>
00299 void Matrix<I,DIM>::Print(int level) 
00300 {int i ;
00301  if (level>=0) {
00302    std::cout << "Dimensionen :" ;
00303    for (i=0;i<DIM;i++) if (i<DIM-1) std::cout<<'['<<b[i]<<','<<e[i]<<"]x"; else std::cout<<'['<<b[i]<<','<<e[i]<<"]\n";
00304  }
00305  if ((level>=1) && (DIM==2)) {
00306    int i,j ; 
00307    for (i=b[0]; i<=e[0]; i++) {
00308    for (j=b[1]; j<=e[1]; j++) {
00309      int ij[2]={i,j} ;
00310      std::cout<<(*this)[ij]<<"  " ;    
00311     }
00312    std::cout<<'\n';
00313   }
00314  }
00315 }
00316 
00318 //                              //
00319 //       Matrix::iterator       //
00320 //                              // 
00322 
00323 
00324 template<class I,int DIM>
00325 Matrix<I,DIM>::iterator::iterator() { 
00326   dim=DIM ;
00327   for (int k=0;k<DIM;k++) {i[k]=b[k]=e[k]=0 , a[k]=k ;} 
00328   i[0]=-1 ;
00329 }
00330 
00331 template<class I,int DIM>
00332 Matrix<I,DIM>::iterator::iterator(const int *bb,const int *ee) {
00333   SetBounds(bb,ee) ;
00334   dim=DIM ;
00335   for (int k=0;k<DIM;k++) a[k]=k ;
00336 }
00337 
00338 template<class I,int DIM>
00339 Matrix<I,DIM>::iterator::iterator(Matrix<I,DIM> *d) {
00340   SetBounds(d->b,d->e) ;
00341   dim=DIM ;
00342   for (int k=0;k<DIM;k++) a[k]=k ;  
00343 }
00344 
00345 template<class I,int DIM>
00346 Matrix<I,DIM>::iterator::iterator(Matrix<I,DIM> *d,int drop) { 
00347   SetBounds(d->b,d->e) ;
00348   dim=0 ;
00349   for (int k=0;k<DIM;k++) { if(k!=drop) a[dim++]=k ;} 
00350 }
00351 
00352 template<class I,int DIM>
00353 Matrix<I,DIM>::iterator::iterator(const int *bb,const int *ee , int drop) { 
00354   SetBounds(bb,ee) ;
00355   dim=0 ;
00356   for (int k=0;k<DIM;k++) { if(k!=drop) a[dim++]=k ;} 
00357 }
00358 
00359 
00360 template<class I,int DIM>
00361 void Matrix<I,DIM>::iterator::SetBounds(const int *bb,const int *ee) { 
00362   for (int k=0;k<DIM;k++) {i[k]=b[k]=bb[k] , e[k]=ee[k] ;} 
00363 }
00364 
00365 template<class I,int DIM>
00366 void Matrix<I,DIM>::iterator::Set(const int *j) {
00367   for (int k=0;k<DIM;k++) i[k]=j[k] ; 
00368 }
00369 
00370 /*
00371 template<class I,int DIM>
00372 void Matrix<I,DIM>::iterator::Set(const int *j , const int drop) {
00373   // dim=0 ;
00374   for (int k=0;k<DIM;k++) { i[k]=j[k] }
00375 }
00376 */
00377 
00378 
00379 template<class I,int DIM>
00380 Matrix<I,DIM>::iterator& Matrix<I,DIM>::iterator::operator++() 
00381 { int k=0,c ;
00382   if (dim==0) { i[0]=e[0]+1 ; return *this ;} 
00383   do { i[a[k]]++ ;
00384     if(c=(i[a[k]]>e[a[k]])) {i[a[k]]=b[a[k]] , k++;}
00385   } while (c && (k<dim)) ;
00386   if (k==dim) i[a[0]]=e[a[0]]+1 ; 
00387   return *this ; 
00388 } 
00389 
00390 
00391 template<class I,int DIM> 
00392 bool Matrix<I,DIM>::iterator::operator!=(const  Matrix<I,DIM>::iterator& x) const {
00393   for (int k=0;k<dim;k++) if (i[a[k]] != x.i[a[k]]) return true ;
00394   return false ; 
00395 }
00396 
00397 
00398 template<class I,int DIM>
00399 bool Matrix<I,DIM>::iterator::operator<=(const  Matrix<I,DIM>::iterator& x) const {
00400   return (*this)<=x.i ;
00401 }
00402 
00403 template<class I,int DIM>
00404 bool Matrix<I,DIM>::iterator::operator<=(const  int b[DIM]) const {
00405   for (int k=0;k<dim;k++) if (i[a[k]]>b[a[k]]) return false ;
00406   if (dim==0) return i[0]<=b[0] ;
00407   return true ;  
00408 }
00409 
00410 template<class I,int DIM>
00411 bool Matrix<I,DIM>::iterator::operator>=(const  int b[DIM]) const {
00412   for (int k=0;k<dim;k++) if (i[a[k]]<b[a[k]]) return false ;
00413   return true ;  
00414 }
00415 
00416 template<class I,int DIM>
00417 void Matrix<I,DIM>::iterator::Print() {
00418   int j ;
00419   std::cout<<"Dim: "<<dim ;
00420   std::cout<<"\nb: "; for (j=0;j<D;j++) std::cout<<b[j]<<"  " ;
00421   std::cout<<"\ne: "; for (j=0;j<D;j++) std::cout<<e[j]<<"  " ;
00422   std::cout<<"\na: "; for (j=0;j<D;j++) std::cout<<a[j]<<"  " ;
00423   std::cout<<"\ni: "; for (j=0;j<D;j++) std::cout<<i[j]<<"  " ;
00424   std::cout<<'\n' ;
00425 }
00426 
00427 
00428 
00430 //                              //
00431 //       Matrix::E/A            //
00432 //                              // 
00434 
00435 
00436 template<class I,int DIM>
00437 void Matrix<I,DIM>::Set(const I &x) {  
00438  Matrix<I,DIM>::iterator it,tend=(*this).end() ;
00439  for (it=(*this).begin();it<=tend;++it) (*this)[it]=x ;
00440 }
00441 
00442 
00443 template<class I,int DIM>
00444 void Matrix<I,DIM>::Set(Function *F) {
00445  int i ;
00446  Matrix<I,DIM>::iterator it(this) ;
00447 
00448  for (it=(*this).begin(); it<=(*this).end(); ++it) {
00449    double x[DIM] ;
00450    for (i=0; i<DIM ;i++) x[i]=((double)it.i[i] - b[i])/(e[i]-b[i]) ;
00451    (*this)[it]=(I)F->Eval(x) ;
00452  }
00453 }
00454 
00455 
00456 template<class I,int DIM>
00457 void Matrix<I,DIM>::WriteUDF(const char *filename, Extensions<DIM> *Ext, const char *ScalarOrVectorName,
00458                              Matrix<I,DIM> **M,int NM, bool castfloat, bool ascii)
00459 {
00460  // scalars or vector ?
00461  Matrix<I,DIM> *MM[3] ;
00462  bool vec   =false ;
00463  UDFInformation<DIM> UDF ;
00464 
00465  int i,j ;
00466  if (M!=NULL) {
00467    vec=true ;
00468    assert(NM >0) ;
00469    assert(NM<=3) ;
00470    for (i=1; i<NM; i++) {
00471      for (j=0; j<DIM; j++) assert( (M[0]->e[j]==M[i]->e[j]) && (M[0]->b[j]==M[i]->b[j]) ) ;
00472      MM[i]=M[i] ;
00473    }
00474  } else {
00475    MM[0]=this ;
00476    NM=1 ;
00477  }
00478 
00479  // dimensions
00480  int eb[DIM+3]={0},count=1 ;
00481  for (i=0; i<DIM; i++) { eb[i]=MM[0]->e[i]-MM[0]->b[i]+1 ; count *=eb[i] ;}
00482  eb[i]=1; eb[i+1]=1 ;
00483 
00484  // write VTK header
00485  FILE *fid=fopen(filename,"w") ;
00486  if (fid==NULL) std::cout<<"could not open for write "<<filename<<'\n' ;
00487  assert(fid) ;
00488 
00489  const char *dataType = (castfloat) ? "float" : "double" ;
00490 
00491  fprintf(fid,"# vtk DataFile Version 2.0\n") ;
00492  fprintf(fid,"UDF-DataSetEXT00")             ;
00493  Ext->WriteUDF(fid) ;
00494 
00495  if (ascii) fprintf(fid,"ASCII\n")           ;
00496      else   fprintf(fid,"BINARY\n")          ;
00497 
00498  fprintf(fid,"DATASET RECTILINEAR_GRID\n")   ;
00499  fprintf(fid,"DIMENSIONS ") ;
00500  for (i=0; i<DIM; i++) fprintf(fid,"%d ",eb[i]) ;
00501  for (i=DIM; i<3; i++) { fprintf(fid,"%d ",1) ; eb[i]=1; }
00502  fprintf(fid,"\n") ;
00503 
00504  double x  ;
00505  float  fx ;
00506  for (i=0; i<max(DIM,3); i++) {
00507    switch (i) {
00508    case 0: fprintf(fid,"X_COORDINATES %d %s\n",eb[i],dataType) ;
00509    break ;
00510    case 1: fprintf(fid,"Y_COORDINATES %d %s\n",eb[i],dataType) ;
00511    break ;
00512    case 2: fprintf(fid,"Z_COORDINATES %d %s\n",eb[i],dataType) ;
00513    break ;
00514    default:fprintf(fid,"X%d_COORDINATES %d %s\n",i,eb[i],dataType) ;
00515    break ; 
00516   }
00517   
00518   double dx ;
00519   if (i<DIM) dx=(Ext->XE[i] - Ext->XA[i]) / (eb[i]-1) ;  else dx=1.0 ;
00520   for (j=0; j<eb[i]; j++) {
00521     if (i<DIM) x=Ext->XA[i] + j*dx ; else x=j*dx ;
00522     if (ascii) {
00523       if (castfloat) fprintf(fid,"%e\n",x) ;
00524           else       fprintf(fid,"%18.16e\n",x) ;
00525     } else {
00526       if (castfloat) { 
00527         fx=x ;
00528         if (UDF.do_swap) UDF_swap(&fx,sizeof(float),1) ;
00529         fwrite(&fx,sizeof(float),1,fid) ;
00530       } else {
00531         if (UDF.do_swap) UDF_swap(&x,sizeof(double),1) ;
00532         fwrite(&x,sizeof(double),1,fid) ;
00533       }
00534     }
00535   } // j
00536   if (!ascii) fprintf(fid,"\n");
00537  } // i 
00538 
00539  //
00540  // Write Data
00541  //
00542  fprintf (fid,"POINT_DATA %d\n",count) ;
00543  
00544  if (!vec) {
00545     fprintf (fid,"SCALARS %s %s\n",ScalarOrVectorName,dataType) ;
00546     fprintf (fid,"LOOKUP_TABLE default\n") ;
00547  } else {
00548     fprintf (fid,"VECTORS %s %s\n",ScalarOrVectorName,dataType) ;
00549  }
00550 
00551  Matrix<I,DIM>::iterator it(MM[0]), tend=(*MM[0]).end() ;
00552 
00553  float mi=1e+20,ma=-mi ;
00554  for (it=(*MM[0]).begin(); it<=tend; ++it) 
00555   {
00556     int je = (vec) ? max(NM,3) : NM;
00557     for (j=0; j<je; j++) {
00558       if (vec && (j>=NM)) x=0.0 ;
00559           else            x=(double)(*MM[j])[it] ;
00560 
00561       mi=x<mi ? x : mi ;
00562       ma=x>ma ? x : ma ;
00563 
00564       if (ascii) {
00565         if (castfloat) fprintf(fid,"%e\n",x) ;
00566             else       fprintf(fid,"%18.16e\n",x) ;
00567       } else {
00568         if (castfloat) { 
00569           fx=(float)x ;
00570           if (UDF.do_swap) UDF_swap(&fx,sizeof(float),1) ;
00571           fwrite(&fx,sizeof(float),1,fid) ;
00572         } else {
00573           if (UDF.do_swap) UDF_swap(&x,sizeof(double),1) ;
00574           fwrite(&x,sizeof(double),1,fid) ;
00575         }
00576       } // binary
00577     } // j
00578   } // it
00579  std::cout<< "WriteUDF Min= "<<scientific<<mi<<' '<<"Max= "<<scientific<<ma<<'\n' ;
00580  fclose(fid) ;
00581 }
00582 
00583 
00584 template<class I,int DIM>
00585 void Matrix<I,DIM>::ReadUDF(const char *filename, Extensions<DIM> *Ext,
00586                             const char *) 
00587 {
00588  int i ;
00589  char st[1000],fd[100],c,st1[1000] ;
00590  double x  ;
00591  float  fx ;
00592 
00593  UDFInformation<DIM> UDF ;
00594 
00595  FILE *fid=fopen(filename,"r") ;
00596  assert(fid) ;
00597  
00598  UDF.ReadHeader(fid, Ext) ;
00599  // Dimensions
00600  int A[DIM]={0},E[DIM] ;
00601  for (i=0; i<DIM; i++) E[i]=UDF.size[i]-1 ;
00602  Init(A,E) ;
00603  
00604  // Read Data
00605  fscanf(fid,"%s %s",st,st1)       ; // POINT_DATA xx
00606  fscanf(fid,"%s %s %s",st,st1,fd) ; // SCALARS bla
00607  fscanf(fid,"%s %s",st,st1)       ; // LOOKUP_TABLE default
00608  fscanf(fid,"%c",&c)              ; // EOL 
00609   
00610  Matrix<I,DIM>::iterator it(this) ;
00611  
00612  for (it=(*this).begin(); it<=(*this).end(); ++it) {
00613 
00614    if (UDF.ascii) {
00615      fscanf(fid,"%le",&x) ;
00616      (*this)[it]=(I)x ;
00617     } else {
00618      if (strcmp(fd,"float")==0) { 
00619        fread(&fx,sizeof(float),1,fid) ;
00620        if (UDF.do_swap) UDF_swap(&fx,sizeof(float),1) ; 
00621        (*this)[it]=(I)fx ;
00622      } else {
00623        fread(&x,sizeof(double),1,fid) ;
00624        if (UDF.do_swap) UDF_swap(&x,sizeof(double),1) ; 
00625        (*this)[it]=(I)x ;
00626      }
00627     } // binary
00628 
00629  } // it
00630  fclose(fid) ;
00631 }
00632 
00633 
00634 // SparseMatrix -> Matrix
00635 template<class I,int DIM>
00636 void Matrix<I,DIM>::ReadSparse(const char *name, double *XA, double *XE, int Level0, int which) {
00637 
00638  int           i,l[DIM],J[DIM],N ;
00639  unsigned long x [DIM],s[DIM]    ;
00640  long          j ;
00641  double        wd[100] ;
00642  float         wf[100] ;
00643  bool          insert  ;
00644 
00645  int header[200]={0},anz,jm1 ;
00646 
00647  bool CastToFloat, do_swap ;
00648 
00649  Set(0.0) ;
00650  CalcLevel(J) ;
00651 
00652  FILE *fid=fopen(name,"r") ;
00653  if (fid==NULL) {
00654    std::cout<<"Matrix<"<<DIM<<">::ReadSparse::Could not open "<<name<<'\n';
00655    exit(-1) ;
00656  }
00657 
00658  // read header
00659  ReadMATLABSparseHeader(fid,DIM, header, &anz, &jm1, &N,XA,XE,&CastToFloat,&do_swap) ;
00660 
00661  // read all entries
00662  for (i=0; i<anz; i++) {
00663    fread( x,sizeof(x[0]),DIM,fid) ;
00664    if (do_swap) UDF_swap( x,sizeof(x[0]),DIM) ;
00665 
00666    if (CastToFloat) {
00667      fread(wf,sizeof(float),N,fid) ;
00668      if (do_swap) UDF_swap(wf,sizeof(float),DIM) ;
00669      for (j=0; j<N; j++) wd[j]=(double)wf[j] ; 
00670    } else {
00671      fread(wd,sizeof(double),N,fid) ;
00672      if (do_swap) UDF_swap(wd,sizeof(double),DIM) ;
00673    }
00674    
00675    insert=true ;
00676    // level l ,index s decodieren
00677    for (j=0; j<DIM; j++) { 
00678      decode(&l[j],&s[j] , x[j] , jm1,Level0) ;
00679      if (l[j]>J[j]) insert=false ;
00680     }
00681 
00682    // insert (l,s)
00683    if (insert) {
00684      int t[DIM] ;
00685      for (j=0; j<DIM; j++) 
00686        t[j] = s[j] + ( (l[j]==Level0) ? 0 : 1<<(l[j]-1) ) ;
00687      
00688      (*this)[t]=(I)wd[which] ;
00689    }
00690 
00691  } // i 
00692  fclose(fid) ;
00693 }
00694 
00695 template<class I,int DIM>
00696 void Matrix<I,DIM>::WriteSparse(const char *filename, double *XA, double *XE , int Level0, 
00697                                       Matrix<I,DIM> **MM, int N, bool CastToFloat) {
00698 
00699   int  i,header[100]={0},anz, hs,J[DIM],JM ;
00700   bool do_swap = UDF_CPUisBigEndian() > 0 ;
00701 
00702   Matrix<I,DIM> *M[100] ;
00703   if (MM==NULL) { M[0]=this; N=1 ;}
00704   else {
00705     for (i=0; i<N; i++) {
00706       assert(MM[i]) ;
00707       M[i]=MM[i] ;
00708     }
00709   }
00710   
00711   FILE *fid=fopen(filename,"w") ;
00712   if (fid==NULL) {
00713     std::cout<<"WriteSparse::Could not open "<<filename<<'\n' ;
00714     exit(-1) ;
00715   }
00716 
00717   // number of elements
00718   CalcLevel(J) ;
00719   JM =0 ;
00720   anz=1 ;
00721   for (i=0; i<DIM; i++) {
00722     anz *=size(i) ;
00723     JM=max(JM,J[i]) ;
00724   }
00725 
00726   hs=header[0]=sizeof(header)/sizeof(header[0]) ;
00727   header[1]=DIM ;
00728   header[2]=anz ;
00729   header[3]=JM  ;
00730  
00731   float *p=(float *)(&(header[4])) ;
00732   assert(sizeof(int)==sizeof(float)) ;
00733 
00734   for (i=0; i<DIM; i++) {
00735     *p=(float)XA[i]; p++ ;
00736     *p=(float)XE[i]; p++ ;
00737   }
00738   
00739   header[4+2*DIM] = N ; // number of components
00740   header[5+2*DIM] = (CastToFloat ? 1 : 0) ;
00741   
00742   if (do_swap) UDF_swap(header,sizeof(int),hs) ;
00743   fwrite(header,sizeof(int) , hs , fid) ;
00744 
00745 
00746   //
00747   // write actual data
00748   // 
00749 
00750   int      s=0,l=0,j ;
00751   unsigned long x[DIM] ;
00752     
00753   Matrix<I,DIM>::iterator t(this) ;
00754   for (t=begin(); t<=end(); ++t) {
00755     // calc level & index  and code
00756     for (i=0; i<DIM; i++) {
00757       if (t.i[i]<=(1<<Level0)) { l=Level0; s=t.i[i]; }
00758       else 
00759         for (j=Level0+1; j<=JM; j++) 
00760           if (t.i[i]<=(1<<j))  { l=j     ; s=t.i[i]-(1<<(j-1)) -1 ; break ; }
00761 
00762       code(l,s,&x[i],JM,Level0) ;
00763     }
00764 
00765     if (do_swap) UDF_swap( x,sizeof(x[0]),DIM) ;
00766     fwrite( x,sizeof(x[0]),DIM,fid) ;
00767 
00768     if (CastToFloat) {
00769       float  w[100] ;
00770       for (i=0; i<N; i++) w[i]=(float)(*M[i])[t] ; 
00771 
00772       if (do_swap) UDF_swap(w,sizeof(float),DIM) ;
00773       fwrite(w,sizeof(float),N,fid) ;
00774 
00775     } else {
00776 
00777       double  w[100] ;
00778       for (i=0; i<N; i++) w[i]=(double)(*M[i])[t] ; 
00779 
00780       if (do_swap) UDF_swap(w,sizeof(double),DIM) ;
00781       fwrite(w,sizeof(double),N,fid) ;
00782     }
00783     
00784   } // i 
00785   fclose(fid) ;
00786   
00787 }
00788 
00789 
00790 // read file in outdated MATLAB format, maintained for compatibility reasons only
00791 template<class I,int DIM>
00792 void Matrix<I,DIM>::ReadMATLAB(const char *filename)
00793 {
00794  FILE *fid=fopen(filename,"r") ;
00795  if (fid==NULL) { std::cout<<"Matrix<"<<DIM<<">::ReadMATLAB: could not not open file: "<<filename<<'\n'; exit(-1) ; }
00796   
00797  int dim,begin[DIM],end[DIM] ;
00798 
00799  // read dimensions
00800  fread(&dim,sizeof(int),1,fid) ; 
00801  assert(dim==DIM)              ;
00802 
00803  fread(begin,sizeof(int),dim,fid) ; 
00804  fread(end  ,sizeof(int),dim,fid) ;
00805   
00806  Init(begin,end) ;
00807 
00808  iterator it(this),tend=(*this).end() ;
00809 
00810  for (it=(*this).begin();it<=tend;++it) 
00811   { double x ; 
00812     fread(&x,sizeof(double),1,fid) ;
00813     (*this)[it]=(I)x ;
00814   } 
00815  fclose(fid) ;
00816 }
00817 
00818 
00819 
00820 //
00821 //
00822 //
00823 
00824 template<class I,int DIM>
00825 void Matrix<I,DIM>::CalcLevel(int *J) {
00826  int h,d ;
00827  for (d=0; d<DIM; d++) {
00828     h=e[d]-b[d]+2 ;
00829     J[d]=0 ; while(h=(h>>1)) J[d]++ ; 
00830   }
00831 }
00832 
00833 //
00834 // Linear Algebra
00835 //
00836 template<class I,int DIM>
00837 void Matrix<I,DIM>::SameSize(Matrix<I,DIM> *X) {
00838   for (int i=0;i<DIM;i++) assert((b[i]==X->b[i])&&(e[i]==X->e[i])) ;
00839 }
00840 
00841 template<class I,int DIM>
00842 double Matrix<I,DIM>::Min() {
00843   double mx=1e+200,x ;
00844   Matrix<I,DIM>::iterator it(this) ;
00845   for (it=begin(); it<=end(); ++it) { 
00846     x =(double)(*this)[it] ;
00847     mx= (mx<x) ? mx : x ;
00848   }
00849  return mx ;
00850 }
00851 
00852 template<class I,int DIM>
00853 double Matrix<I,DIM>::Max() {
00854   double mx=-1e+200,x ;
00855   Matrix<I,DIM>::iterator it(this) ;
00856   for (it=begin(); it<=end(); ++it) { 
00857     x =(double)(*this)[it] ;
00858     mx= (mx>x) ? mx : x ;  
00859   }
00860  return mx ;
00861 }
00862 
00863 template<class I,int DIM>
00864 double Matrix<I,DIM>::MaxAbs() {
00865   double mx=0.0 ,x  ;
00866   Matrix<I,DIM>::iterator it(this) ;
00867   for (it=begin(); it<=end(); ++it) { 
00868     x =fabs((double)(*this)[it]) ;
00869     mx= (mx>x) ? mx : x ;  
00870   }
00871  return mx ;
00872 }
00873 
00874 template<class I,int DIM>
00875 double Matrix<I,DIM>::Sum() {
00876   double mx=0.0 ;
00877   Matrix<I,DIM>::iterator it(this) ;
00878   for (it=begin(); it<=end(); ++it) mx +=(double)(*this)[it] ;
00879   return mx ;
00880 }
00881 
00882 template<class I,int DIM>
00883 double Matrix<I,DIM>::SumAbs() {
00884   double mx=0.0 ;
00885   Matrix<I,DIM>::iterator it(this) ;
00886   for (it=begin(); it<=end(); ++it) mx +=fabs((double)(*this)[it]) ;
00887   return mx ;
00888 }
00889 
00890 template<class I,int DIM>
00891 double Matrix<I,DIM>::SumSqr() {
00892   double mx=0.0 ;
00893   Matrix<I,DIM>::iterator it(this) ;
00894   for (it=begin(); it<=end(); ++it) mx +=((double)(*this)[it])*((double)(*this)[it]) ;
00895   return mx ;
00896 }
00897 
00898 template<class I,int DIM>
00899 void Matrix<I,DIM>::Copy(Matrix<I,DIM> *X) {
00900   SameSize(X) ;
00901   Matrix<I,DIM>::iterator it(this) ;
00902   for (it=begin(); it<=end(); ++it) (*this)[it]=(*X)[it] ;
00903 }
00904 
00905 
00906 template<class I,int DIM>
00907 void Matrix<I,DIM>::Set(Matrix<I,DIM> *X) {
00908   assert(X!=this) ;
00909   Set((I)0) ;
00910   int aa[DIM],ee[DIM],i ;
00911   for (i=0; i<DIM; i++) {
00912     aa[i]=max(X->b[i], b[i]) ;
00913     ee[i]=min(X->e[i], e[i]) ;
00914   }
00915 
00916   Matrix<I,DIM>::iterator it(aa,ee) ;
00917   for (it.Set(aa); it<=ee; ++it) (*this)[it.i]=(*X)[it.i] ;
00918 }
00919 
00920 template<class I,int DIM>
00921 void Matrix<I,DIM>::Abs(Matrix<I,DIM> *X) {
00922   SameSize(X) ;
00923   Matrix<I,DIM>::iterator it(this) ;
00924   for (it=begin(); it<=end(); ++it) (*this)[it]=fabs((*X)[it]) ;
00925 }
00926 
00927 template<class I,int DIM>
00928 void Matrix<I,DIM>::Pow(Matrix<I,DIM> *X, double p) {
00929   SameSize(X) ;
00930   Matrix<I,DIM>::iterator it(this) ;
00931   for (it=begin(); it<=end(); ++it) (*this)[it]=pow((*X)[it],p) ;
00932 }
00933 
00934 template<class I,int DIM>
00935 void Matrix<I,DIM>::Sqr(Matrix<I,DIM> *X) {
00936   SameSize(X) ;
00937   Matrix<I,DIM>::iterator it(this) ;
00938   for (it=begin(); it<=end(); ++it) (*this)[it]=(*X)[it]*(*X)[it] ;
00939 }
00940 
00941 template<class I,int DIM>
00942 void Matrix<I,DIM>::PPlus(Matrix<I,DIM> *X) {
00943   SameSize(X) ;
00944   Matrix<I,DIM>::iterator it(this) ;
00945   for (it=begin(); it<=end(); ++it) (*this)[it] +=(*X)[it] ;
00946 }
00947 
00948 template<class I,int DIM>
00949 void Matrix<I,DIM>::PPlus(const double a , Matrix<I,DIM> *X) {
00950   SameSize(X) ;
00951   Matrix<I,DIM>::iterator it(this) ;
00952   for (it=begin(); it<=end(); ++it) (*this)[it] +=a*(*X)[it] ;
00953 }
00954 
00955 template<class I,int DIM>
00956 void Matrix<I,DIM>::Add(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) {
00957   SameSize(X) ;
00958   SameSize(Y) ;
00959   Matrix<I,DIM>::iterator it(this) ;
00960   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] + (*Y)[it] ;
00961 }
00962 
00963 
00964 template<class I,int DIM>
00965 void Matrix<I,DIM>::Add(const double a, Matrix<I,DIM> *X ,const double b, Matrix<I,DIM> *Y) {
00966   SameSize(X) ;
00967   SameSize(Y) ;
00968   Matrix<I,DIM>::iterator it(this) ;
00969   for (it=begin(); it<=end(); ++it) (*this)[it] =a*(*X)[it] + b*(*Y)[it] ;
00970 }
00971 
00972 template<class I,int DIM>
00973 void Matrix<I,DIM>::Add(const double a, Matrix<I,DIM> *X ,const double b, Matrix<I,DIM> *Y , const double c, Matrix<I,DIM> *Z) {
00974   SameSize(X) ;
00975   SameSize(Y) ;
00976   SameSize(Z) ;
00977 
00978   Matrix<I,DIM>::iterator it(this) ;
00979   for (it=begin(); it<=end(); ++it) (*this)[it] =a*(*X)[it] + b*(*Y)[it] +c*(*Z)[it] ;
00980 }
00981 
00982 template<class I,int DIM>
00983 void Matrix<I,DIM>::Add(const double a, Matrix<I,DIM> *X ,const double b, Matrix<I,DIM> *Y , const double c, Matrix<I,DIM> *Z , const double d, Matrix<I,DIM> *Q ) {
00984   SameSize(X) ;
00985   SameSize(Y) ;
00986   SameSize(Z) ;
00987   SameSize(Q) ;
00988 
00989   Matrix<I,DIM>::iterator it(this) ;
00990   for (it=begin(); it<=end(); ++it) (*this)[it] =a*(*X)[it] + b*(*Y)[it] +c*(*Z)[it] +d*(*Q)[it];
00991 }
00992 
00993 template<class I,int DIM>
00994 void Matrix<I,DIM>::Add(const double a, Matrix<I,DIM> *X ,const double b, Matrix<I,DIM> *Y , const double c, Matrix<I,DIM> *Z , const double d, Matrix<I,DIM> *Q , const double e, Matrix<I,DIM> *R ) {
00995   SameSize(X) ;
00996   SameSize(Y) ;
00997   SameSize(Z) ;
00998   SameSize(Q) ;
00999   SameSize(R) ;
01000 
01001   Matrix<I,DIM>::iterator it(this) ;
01002   for (it=begin(); it<=end(); ++it) (*this)[it] =a*(*X)[it] + b*(*Y)[it] +c*(*Z)[it] +d*(*Q)[it] +e*(*R)[it]  ;
01003 }
01004 
01005 template<class I,int DIM>
01006 void Matrix<I,DIM>::MMinus(Matrix<I,DIM> *X) {
01007   SameSize(X) ;
01008   Matrix<I,DIM>::iterator it(this) ;
01009   for (it=begin(); it<=end(); ++it) (*this)[it] -=(*X)[it] ;
01010 }
01011 
01012 template<class I,int DIM>
01013 void Matrix<I,DIM>::MMinus(const double a,Matrix<I,DIM> *X) {
01014   SameSize(X) ;
01015   Matrix<I,DIM>::iterator it(this) ;
01016   for (it=begin(); it<=end(); ++it) (*this)[it] -=a*(*X)[it] ;
01017 }
01018 
01019 template<class I,int DIM>
01020 void Matrix<I,DIM>::Sub(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) {
01021   SameSize(X) ;
01022   SameSize(Y) ;
01023   Matrix<I,DIM>::iterator it(this) ;
01024   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] - (*Y)[it] ;
01025 }
01026 
01027 template<class I,int DIM>
01028 void Matrix<I,DIM>::Mul(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) {
01029   SameSize(X) ;
01030   SameSize(Y) ;
01031   Matrix<I,DIM>::iterator it(this) ;
01032   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] * (*Y)[it] ;
01033 }
01034 
01035 template<class I,int DIM>
01036 void Matrix<I,DIM>::Mul(Matrix<I,DIM> *X , Matrix<I,DIM> *Y , const double f) {
01037   SameSize(X) ;
01038   SameSize(Y) ;
01039   Matrix<I,DIM>::iterator it(this) ;
01040   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] * (*Y)[it] *f ;
01041 }
01042 
01043 template<class I,int DIM>
01044 void Matrix<I,DIM>::Mul(Matrix<I,DIM> *X , const double f) {
01045   SameSize(X) ;
01046   Matrix<I,DIM>::iterator it(this) ;
01047   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] *f ;
01048 }
01049 
01050 template<class I,int DIM>
01051 void Matrix<I,DIM>::Mul(const double f) {
01052   Matrix<I,DIM>::iterator it(this) ;
01053   for (it=begin(); it<=end(); ++it) (*this)[it] =(*this)[it] *f ;
01054 }
01055 
01056 
01057 template<class I,int DIM>
01058 double Matrix<I,DIM>::InnerProd(Matrix<I,DIM> *X) {
01059   SameSize(X) ;
01060   double s=0.0 ;
01061   Matrix<I,DIM>::iterator it(this) ;
01062   for (it=begin(); it<=end(); ++it) s +=(*this)[it]*(*X)[it] ;
01063   return s;
01064 }
01065 
01066 template<class I,int DIM>
01067 void Matrix<I,DIM>::XplusYmalZ(Matrix<I,DIM> *X , Matrix<I,DIM> *Y , Matrix<I,DIM> *Z) {
01068   SameSize(X) ;
01069   SameSize(Y) ;
01070   SameSize(Z) ;
01071 
01072   Matrix<I,DIM>::iterator it(this) ;
01073   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] + (*Y)[it]*(*Z)[it] ;
01074 }
01075 
01076 template<class I,int DIM>
01077 void Matrix<I,DIM>::XminusYmalZ(Matrix<I,DIM> *X , Matrix<I,DIM> *Y , Matrix<I,DIM> *Z) {
01078   SameSize(X) ;
01079   SameSize(Y) ;
01080   SameSize(Z) ;
01081 
01082   Matrix<I,DIM>::iterator it(this) ;
01083   for (it=begin(); it<=end(); ++it) (*this)[it] =(*X)[it] + (*Y)[it]*(*Z)[it] ;
01084 }
01085 
01086 // usual product of two 2D compatible matrices 
01087 template<class I,int DIM>
01088 void Matrix<I,DIM>::Multiply(Matrix<I,DIM> *X , Matrix<I,DIM> *Y) {
01089   assert(DIM==2) ;
01090   assert(b[0]==X->b[0]) ; assert(e[0]==X->e[0]) ; 
01091   assert(b[1]==Y->b[1]) ; assert(e[1]==Y->e[1]) ; 
01092   assert(X->b[1]==Y->b[0]) ; assert(X->e[1]==Y->e[0]) ; 
01093 
01094   double s;
01095   int i,j,k,ij[2],ik[2],kj[2] ;
01096   for (i=b[0]; i<=e[0]; i++)
01097     for (j=b[1]; j<=e[1]; j++) {
01098       ij[0]=i,ij[1]=j ;
01099       s=0 ;
01100       for (k=X->b[1]; k<=X->e[1]; k++) {
01101         ik[0]=i,ik[1]=k ;
01102         kj[0]=k,kj[1]=j ;
01103         s += (*X)[ik]*(*Y)[kj] ;
01104        }
01105       (*this)[ij]=s ;
01106     }
01107 }
01108 
01109 template<class I,int DIM>
01110 void Matrix<I,DIM>::Transpose(Matrix<I,DIM> *X) {
01111   assert(DIM==2) ;
01112   assert(b[0]==X->b[0]) ; 
01113   assert(e[1]==X->e[1]) ; 
01114 
01115   Matrix<I,DIM> *Y=X ;
01116   if (this==X) {
01117     Y=new Matrix<I,DIM>(X->b, X->e) ;
01118     Y.Copy(X) ;
01119   }
01120  
01121   int i,j ;
01122   for (i=b[0]; i<=e[0]; i++)
01123     for (j=b[1]; j<=e[1]; j++) {
01124       int ij[2]={i,j}, ji[2]={j,i} ; 
01125       (*this)[ij]=(*Y)[ji] ;
01126     }
01127 
01128   if (this==C) delete Y ;
01129 }
01130 #endif
01131 
01132 
01133 

Generated at Mon Aug 19 10:02:31 2002 for AWFD by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001