00001
00002
00003
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
00061
00063
00064
00065 friend class Matrix<I,DIM> ;
00066
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) ;
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
00171
00172
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
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
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
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
00372
00373
00374
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
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
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
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
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 }
00536 if (!ascii) fprintf(fid,"\n");
00537 }
00538
00539
00540
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 }
00577 }
00578 }
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
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
00605 fscanf(fid,"%s %s",st,st1) ;
00606 fscanf(fid,"%s %s %s",st,st1,fd) ;
00607 fscanf(fid,"%s %s",st,st1) ;
00608 fscanf(fid,"%c",&c) ;
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 }
00628
00629 }
00630 fclose(fid) ;
00631 }
00632
00633
00634
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
00659 ReadMATLABSparseHeader(fid,DIM, header, &anz, &jm1, &N,XA,XE,&CastToFloat,&do_swap) ;
00660
00661
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
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
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 }
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
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 ;
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
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
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 }
00785 fclose(fid) ;
00786
00787 }
00788
00789
00790
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
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
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
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