00001 #ifndef _DATAMATRIX_
00002 # define _DATAMATRIX_
00003
00004 #include "Matrix.hpp"
00005 #include "NonAdaptive.hpp"
00006 #include "Extensions.hpp"
00007
00008 #ifdef _FFTW_
00009 #include <rfftw.h>
00010 #endif
00011
00012 struct Function ;
00013
00014 #define LMAXDATAARRAY 12
00015
00016 double _DATAMATRIX_BUFFER_s[(1<<LMAXDATAARRAY)+1],
00017 _DATAMATRIX_BUFFER_t[(1<<LMAXDATAARRAY)+1],
00018 _DATAMATRIX_BUFFER_q[(1<<LMAXDATAARRAY)+1] ;
00019
00022 template<int DIM>
00023 struct UniformData {
00024
00025 public:
00027 UniformData() ;
00029 UniformData(int *begin,int *end , Wavelets *W,double *XA=NULL, double *XE=NULL) ;
00032 void Init (int *begin,int *end , Wavelets *W,double *XA=NULL, double *XE=NULL) ;
00033
00034 ~UniformData() ;
00035 void Clear () ;
00036
00038 void SetBoundaryConditions(UniformData<DIM> *X) ;
00040 void SetBoundaryConditions(int BC[DIM][2]) ;
00042 void SetBoundaryConditions(int dir,int *bc) ;
00044 void SetBoundaryConditions(int dir,int bc0,int bc1) ;
00046 bool SameBoundaryConditions(UniformData<DIM> *X) ;
00047
00048
00049 void CheckBC(UniformData<DIM> *X) ;
00050 void CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y) ;
00051 void CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z) ;
00052 void CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z , UniformData<DIM> *Q) ;
00053 void CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z , UniformData<DIM> *Q , UniformData<DIM> *R) ;
00054
00055
00056 void Compatible(UniformData<DIM> *X) ;
00057 void Compatible(UniformData<DIM> *X, UniformData<DIM> *Y) ;
00058 void Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z) ;
00059 void Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z, UniformData<DIM> *Q) ;
00060 void Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z, UniformData<DIM> *Q, UniformData<DIM> *R) ;
00061
00063 void CopyExtensions(UniformData<DIM> *X) ;
00064
00073 void SetFunction(Function *F, bool boundaryonly=false, bool notransform=false) ;
00074
00076 double Max() ;
00078 double Min() ;
00080 double MaxAbs() ;
00082 double Sum() ;
00084 double SumAbs() ;
00086 double SumSqr() ;
00087
00092 double LpNorm (UniformData<DIM> *Tmp, double p) ;
00094 double LmaxNorm(UniformData<DIM> *Tmp) ;
00096 double L2Norm (UniformData<DIM> *Tmp) ;
00098 double L1Norm (UniformData<DIM> *Tmp) ;
00100 double Integrate() ;
00102 double InnerProd(UniformData<DIM> *X) ;
00103
00105 void Set(const double a) ;
00107 void Copy(UniformData<DIM> *X) ;
00109 void Set(UniformData<DIM> *X) ;
00111 void Abs(UniformData<DIM> *X) ;
00113 void Pow(UniformData<DIM> *X, double p) ;
00115 void Sqr(UniformData<DIM> *X) ;
00116
00118 void PPlus(UniformData<DIM> *X) ;
00120 void PPlus(const double a , UniformData<DIM> *X) ;
00122 void Add(UniformData<DIM> *X , UniformData<DIM> *Y) ;
00124 void Add(const double a , UniformData<DIM> *X , const double b , UniformData<DIM> *Y) ;
00126 void Add(const double a , UniformData<DIM> *X , const double b , UniformData<DIM> *Y ,
00127 const double c , UniformData<DIM> *Z) ;
00129 void Add(const double a , UniformData<DIM> *X , const double b , UniformData<DIM> *Y ,
00130 const double c , UniformData<DIM> *Z , const double d , UniformData<DIM> *Q) ;
00132 void Add(const double a , UniformData<DIM> *X , const double b , UniformData<DIM> *Y ,
00133 const double c , UniformData<DIM> *Z , const double d , UniformData<DIM> *Q ,
00134 const double f , UniformData<DIM> *R) ;
00135
00137 void MMinus(UniformData<DIM> *X) ;
00139 void MMinus(const double a, UniformData<DIM> *X) ;
00141 void Sub(UniformData<DIM> *X , UniformData<DIM> *Y) ;
00142
00144 void Mul(UniformData<DIM> *X , UniformData<DIM> *Y) ;
00146 void Mul(UniformData<DIM> *X , UniformData<DIM> *Y , double f) ;
00148 void Mul(UniformData<DIM> *X , double f) ;
00150 void Mul(double f) ;
00151 void XplusYmalZ (UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z) ;
00152 void XminusYmalZ(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z) ;
00153
00154
00156
00210
00211
00212 void SwitchToNoBoundaryConditions(UniformData<DIM> *X) ;
00213
00215
00217
00218
00219
00222 void FourierCoefficient(double *re, double *im, int *k) ;
00223
00224
00225
00226 void FourierSpectrum(double *sp, int *Kmin, int *Kmax) ;
00227
00228
00229
00230 void MeanVariance (double *mean, double *variance, int dir) ;
00231
00232
00238 void WriteUDF(const char *filename, UniformData<DIM> *Tmp=NULL, bool CastToFloat=false) ;
00242 void ReadUDF (const char *name) ;
00244 void ReadSparse (const char *name, int which=0) ;
00246 void WriteSparse(const char *filename, UniformData<DIM> **M=NULL, int N=0, bool CastToFloat=false) ;
00247
00248
00249 typedef double (*BoundFunction)(double *x,int d) ;
00250 void SetBoundaryFunction(BoundFunction f) ;
00251
00253 inline double& operator[](const class Matrix<double,DIM>::iterator &it) { return (*(*this).ba)[it] ;} ;
00255 inline double& operator[](const int *in ) { return (*(*this).ba)[in] ;} ;
00256
00257
00258 Matrix<double , DIM> *ba ;
00259 Extensions<DIM> Ext ;
00260 } ;
00261
00262
00264
00265
00266
00268
00269 template<int DIM>
00270 UniformData<DIM>::UniformData() {
00271 ba=new Matrix<double , DIM> ;
00272 }
00273
00274 template<int DIM>
00275 UniformData<DIM>::UniformData(int *A , int *E , Wavelets *W,double *XA, double *XE) {
00276 ba=new Matrix<double , DIM>(A,E) ;
00277 Ext.Init(W,XA,XE) ;
00278 }
00279
00280
00281 template<int DIM>
00282 UniformData<DIM>::~UniformData() {
00283 delete ba ;
00284 }
00285
00286 template<int DIM>
00287 void UniformData<DIM>::Init(int *A , int *E , Wavelets *W,double *XA, double *XE) {
00288 ba->Init(A,E) ;
00289 Ext.Init(W,XA,XE) ;
00290 }
00291
00292 template<int DIM>
00293 void UniformData<DIM>::Clear() {
00294 ba->Clear() ;
00295 Ext.WC=NULL ;
00296 }
00297
00298
00299
00300 template<int DIM>
00301 void UniformData<DIM>::CopyExtensions(UniformData<DIM> *X) {
00302 Ext.CopyFlags(&X->Ext) ;
00303 }
00304
00305
00306
00307 template<int DIM>
00308 void UniformData<DIM>::Compatible(UniformData<DIM> *X) {
00309 if (!Ext.IsSame(&X->Ext)) {
00310 Ext.Print() ;
00311 X->Ext.Print() ;
00312 assert(0) ;
00313 }
00314 }
00315
00316 template<int DIM>
00317 void UniformData<DIM>::Compatible(UniformData<DIM> *X, UniformData<DIM> *Y) {
00318 Compatible(X) ;
00319 Compatible(Y) ;
00320 }
00321
00322 template<int DIM>
00323 void UniformData<DIM>::Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z) {
00324 Compatible(X) ;
00325 Compatible(Y) ;
00326 Compatible(Z) ;
00327 }
00328
00329 template<int DIM>
00330 void UniformData<DIM>::Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z, UniformData<DIM> *Q) {
00331 Compatible(X) ;
00332 Compatible(Y) ;
00333 Compatible(Z) ;
00334 Compatible(Q) ;
00335 }
00336
00337 template<int DIM>
00338 void UniformData<DIM>::Compatible(UniformData<DIM> *X, UniformData<DIM> *Y, UniformData<DIM> *Z, UniformData<DIM> *Q, UniformData<DIM> *R) {
00339 Compatible(X) ;
00340 Compatible(Y) ;
00341 Compatible(Z) ;
00342 Compatible(Q) ;
00343 Compatible(R) ;
00344 }
00345
00346
00347
00348 template<int DIM>
00349 void UniformData<DIM>::CheckBC(UniformData<DIM> *X) {
00350 assert (Ext.SameBoundaryConditions(&X->Ext)) ;
00351 }
00352
00353 template<int DIM>
00354 void UniformData<DIM>::CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y)
00355 { CheckBC(X) ; CheckBC(Y) ; }
00356
00357 template<int DIM>
00358 void UniformData<DIM>::CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z)
00359 { CheckBC(X) ; CheckBC(Y) ; CheckBC(Z) ; }
00360
00361 template<int DIM>
00362 void UniformData<DIM>::CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z , UniformData<DIM> *Q)
00363 { CheckBC(X) ; CheckBC(Y) ; CheckBC(Z) ; CheckBC(Q) ; }
00364
00365 template<int DIM>
00366 void UniformData<DIM>::CheckBC(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z , UniformData<DIM> *Q , UniformData<DIM> *R)
00367 { CheckBC(X) ; CheckBC(Y) ; CheckBC(Z) ; CheckBC(Q) ; CheckBC(R) ; }
00368
00369
00370
00371
00372 template<int DIM>
00373 void UniformData<DIM>::SetBoundaryConditions(UniformData<DIM> *X) {
00374 Ext.SetBoundaryConditions(X->Ext.BC) ;
00375 }
00376 template<int DIM>
00377 void UniformData<DIM>::SetBoundaryConditions(int bc[DIM][2]) {
00378 Ext.SetBoundaryConditions(bc) ;
00379 }
00380 template<int DIM>
00381 void UniformData<DIM>::SetBoundaryConditions(int d,int *bc) {
00382 Ext.SetBoundaryConditions(d,bc) ;
00383 }
00384 template<int DIM>
00385 void UniformData<DIM>::SetBoundaryConditions(int d,int bc0,int bc1) {
00386 Ext.SetBoundaryConditions(d, bc0,bc1) ;
00387 }
00388 template<int DIM>
00389 bool UniformData<DIM>::SameBoundaryConditions(UniformData<DIM> *X) {
00390 return Ext.SameBoundaryConditions(&X->Ext) ;
00391 }
00392
00393
00394
00395
00396 template<int DIM>
00397 void UniformData<DIM>::Set(const double a) {
00398 ba->Set(a) ;
00399 Ext.Set(0) ; ;
00400 }
00401
00402 template<int DIM>
00403 void UniformData<DIM>::SetFunction(Function *F, bool boundaryonly, bool notransform) {
00404 int i,ii ;
00405
00406
00407 for (i=0; i<DIM; i++) {
00408 for (int k=0; k<2; k++)
00409 if ( (Ext.BC[i][k]!=-1) && (Ext.BC[i][k]!=0) && (Ext.BC[i][k]!=1) && (Ext.BC[i][k]!=PERIODIC) ) {
00410 std::cout<< "UniformData<"<<DIM<<">::SetFunction():: you must set valid boundary conditions first, to define the periodic directions\n" ;
00411 assert(0) ;
00412 }
00413 Ext.BC[i][0]=-1 ;
00414 if (Ext.BC[i][1]!=PERIODIC) Ext.BC[i][1]=-1 ;
00415 }
00416
00417 Matrix<double,DIM>::iterator s(ba) ;
00418
00419 for (s.Set(ba->b); s<=ba->e; ++s) {
00420 double x[DIM] ;
00421 for (i=0; i<DIM ;i++) {
00422 ii=s.i[i] - ba->b[i] ;
00423 x[i]=Ext.XA[i]+((Ext.XE[i]-Ext.XA[i])*ii) / (ba->e[i]-ba->b[i]) ;
00424 }
00425 (*ba)[s]=F->Eval(x) ;
00426 }
00427
00428 Ext.Set(0) ;
00429 for (i=0; i<DIM; i++) Ext.ismultiscale[i]=Ext.islifting[i]=false ;
00430 if (!notransform) for (i=0; i<DIM; i++) ApplyOp(Ext.BC[i], this, i, TRANSFORM) ;
00431 else {
00432 if(boundaryonly) { std::cout<< "UniformData<"<<DIM<<">::SetFunction boundaryonly==true && notransform==true not supported yet\n"; assert(0) ;}
00433 }
00434
00435 if (boundaryonly) {
00436 int L[DIM],l ;
00437 unsigned long t ;
00438 ba->CalcLevel(L) ;
00439
00440 for (s.Set(ba->b); s<=ba->e; ++s) {
00441 bool boundary=false ;
00442 for (i=0; i<DIM; i++) {
00443 decode(&l,&t,s.i[i],L[i],Ext.WC->Level0) ;
00444 if ( (l==Ext.WC->Level0) && ((t==0)||(t==(unsigned long)(1<<Ext.WC->Level0))) && (Ext.BC[i][1]!=PERIODIC)) boundary=true ;
00445 }
00446
00447 if (!boundary) (*ba)[s]=0 ;
00448 }
00449 }
00450 }
00451
00452
00453
00454
00455
00456 template<int DIM>
00457 void UniformData<DIM>::Copy(UniformData<DIM> *X) {
00458 SetBoundaryConditions(X) ;
00459 ba->Copy(X->ba) ;
00460 Ext.CopyFlags(&X->Ext) ;
00461 }
00462
00463 template<int DIM>
00464 void UniformData<DIM>::Set(UniformData<DIM> *X) {
00465 SetBoundaryConditions(X) ;
00466 ba->Set(X->ba) ;
00467 Ext.CopyFlags(&X->Ext) ;
00468
00469
00470 double *XA=X->Ext.XA, *Xa=Ext.XA ,
00471 *XE=X->Ext.XE, *Xe=Ext.XE ;
00472 int *A=X->ba->b, *a=ba->b ,
00473 *E=X->ba->e, *e=ba->e ;
00474 assert(XA!=Xa) ;
00475 assert(XE!=Xe) ;
00476
00477 for (int i=0; i<DIM; i++) {
00478 Xa[i]=XA[i]+((a[i] - A[i])*(XE[i]-XA[i]))/(E[i]-A[i]) ;
00479 Xe[i]=XA[i]+((e[i] - A[i])*(XE[i]-XA[i]))/(E[i]-A[i]) ;
00480 }
00481 }
00482
00483 template<int DIM>
00484 void UniformData<DIM>::Abs(UniformData<DIM> *X) {
00485 SetBoundaryConditions(X) ;
00486 ba->Abs(X->ba) ;
00487 Ext.CopyFlags(&X->Ext) ;
00488 Ext.Abs(&X->Ext) ;
00489 }
00490
00491 template<int DIM>
00492 void UniformData<DIM>::Pow(UniformData<DIM> *X, double p) {
00493 SetBoundaryConditions(X) ;
00494 ba->Pow(X->ba,p) ;
00495 Ext.CopyFlags(&X->Ext) ;
00496 Ext.Pow(&X->Ext,p) ;
00497 }
00498
00499 template<int DIM>
00500 void UniformData<DIM>::Sqr(UniformData<DIM> *X) {
00501 SetBoundaryConditions(X) ;
00502 ba->Sqr(X->ba) ;
00503 Ext.CopyFlags(&X->Ext) ;
00504 Ext.Sqr (&X->Ext) ;
00505 }
00506
00507
00508 template<int DIM>
00509 double UniformData<DIM>::Max() {
00510 return max(ba->Max() , Ext.Max()) ;
00511 }
00512
00513 template<int DIM>
00514 double UniformData<DIM>::Min() {
00515 return min(ba->Min() , Ext.Min()) ;
00516 }
00517
00518 template<int DIM>
00519 double UniformData<DIM>::MaxAbs() {
00520 return max(ba->MaxAbs() , Ext.MaxAbs()) ;
00521 }
00522
00523 template<int DIM>
00524 double UniformData<DIM>::Sum() {
00525 return ba->Sum() + Ext.Sum() ;
00526 }
00527
00528 template<int DIM>
00529 double UniformData<DIM>::SumAbs() {
00530 return ba->SumAbs() + Ext.SumAbs() ;
00531 }
00532
00533 template<int DIM>
00534 double UniformData<DIM>::SumSqr() {
00535 return ba->SumSqr() + Ext.SumSqr() ;
00536 }
00537
00538 template<int DIM>
00539 double UniformData<DIM>::InnerProd(UniformData<DIM> *X) {
00540 Compatible(X) ;
00541 return ba->InnerProd(X->ba) + Ext.InnerProd(&X->Ext) ;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 template<int DIM>
00579 void UniformData<DIM>::PPlus(UniformData<DIM> *X) {
00580 Compatible(X) ;
00581 ba->PPlus( X->ba) ;
00582 Ext.PPlus(&X->Ext) ;
00583 }
00584
00585 template<int DIM>
00586 void UniformData<DIM>::PPlus(const double a,UniformData<DIM> *X) {
00587 Compatible(X) ;
00588 ba->PPlus(a, X->ba ) ;
00589 Ext.PPlus(a,&X->Ext) ;
00590 }
00591
00592 template<int DIM>
00593 void UniformData<DIM>::Add(UniformData<DIM> *X,UniformData<DIM> *Y) {
00594 X->Compatible(Y) ;
00595 CopyExtensions(X) ;
00596 ba->Add( X->ba , Y->ba) ;
00597 Ext.Add(&X->Ext , &Y->Ext) ;
00598 }
00599
00600 template<int DIM>
00601 void UniformData<DIM>::Add(const double a,UniformData<DIM> *X,const double b,UniformData<DIM> *Y) {
00602 X->Compatible(Y) ;
00603 CopyExtensions(X) ;
00604 ba->Add(a, X->ba , b, Y->ba) ;
00605 Ext.Add(a,&X->Ext , b,&Y->Ext) ;
00606 }
00607
00608 template<int DIM>
00609 void UniformData<DIM>::Add(const double a,UniformData<DIM> *X,const double b,UniformData<DIM> *Y,
00610 const double c,UniformData<DIM> *Z)
00611 {
00612 X->Compatible(Y,Z) ;
00613 CopyExtensions(X) ;
00614 ba->Add(a, X->ba , b, Y->ba , c, Z->ba) ;
00615 Ext.Add(a,&X->Ext , b,&Y->Ext , c,&Z->Ext) ;
00616 }
00617
00618 template<int DIM>
00619 void UniformData<DIM>::Add(const double a,UniformData<DIM> *X,const double b,UniformData<DIM> *Y,
00620 const double c,UniformData<DIM> *Z,const double d,UniformData<DIM> *Q)
00621 {
00622 X->Compatible(Y,Z,Q) ;
00623 CopyExtensions(X) ;
00624 ba->Add(a, X->ba , b, Y->ba , c, Z->ba , d, Q->ba) ;
00625 Ext.Add(a,&X->Ext , b,&Y->Ext , c,&Z->Ext, d,&Q->Ext) ;
00626 }
00627
00628 template<int DIM>
00629 void UniformData<DIM>::Add(const double a,UniformData<DIM> *X,const double b,UniformData<DIM> *Y,
00630 const double c,UniformData<DIM> *Z,const double d,UniformData<DIM> *Q,
00631 const double e,UniformData<DIM> *R)
00632 {
00633 X->Compatible(Y,Z,Q,R) ;
00634 CopyExtensions(X) ;
00635 ba->Add(a,X->ba,b,Y->ba,c,Z->ba,d,Q->ba,e,R->ba) ;
00636 Ext.Add(a,&X->Ext , b,&Y->Ext , c,&Z->Ext, d,&Q->Ext , e,&R->Ext) ;
00637 }
00638
00639 template<int DIM>
00640 void UniformData<DIM>::MMinus(UniformData<DIM> *X) {
00641 Compatible(X) ;
00642 ba->MMinus( X->ba) ;
00643 Ext.MMinus(&X->Ext) ;
00644 }
00645
00646 template<int DIM>
00647 void UniformData<DIM>::MMinus(const double a,UniformData<DIM> *X) {
00648 Compatible(X) ;
00649 ba->MMinus(a,X->ba) ;
00650 Ext.MMinus(a,&X->Ext) ;
00651 }
00652
00653 template<int DIM>
00654 void UniformData<DIM>::Sub(UniformData<DIM> *X,UniformData<DIM> *Y) {
00655 X->Compatible(Y) ;
00656 CopyExtensions(X) ;
00657 ba->Sub( X->ba , Y->ba) ;
00658 Ext.Sub(&X->Ext , &Y->Ext) ;
00659 }
00660
00661 template<int DIM>
00662 void UniformData<DIM>::Mul(UniformData<DIM> *X ,UniformData<DIM> *Y) {
00663 X->Compatible(Y) ;
00664 CopyExtensions(X) ;
00665 ba->Mul( X->ba , Y->ba) ;
00666 Ext.Mul(&X->Ext , &Y->Ext) ;
00667 }
00668
00669 template<int DIM>
00670 void UniformData<DIM>::Mul(UniformData<DIM> *X ,UniformData<DIM> *Y , double f) {
00671 X->Compatible(Y) ;
00672 CopyExtensions(X) ;
00673 ba->Mul( X->ba , Y->ba , f) ;
00674 Ext.Mul(&X->Ext , &Y->Ext, f) ;
00675 }
00676
00677 template<int DIM>
00678 void UniformData<DIM>::Mul(UniformData<DIM> *X , double f) {
00679 CopyExtensions(X) ;
00680 ba->Mul( X->ba , f) ;
00681 Ext.Mul(&X->Ext, f) ;
00682 }
00683
00684 template<int DIM>
00685 void UniformData<DIM>::Mul(double f) {
00686 ba->Mul(f) ;
00687 Ext.Mul(f) ;
00688 }
00689
00690 template<int DIM>
00691 void UniformData<DIM>::XplusYmalZ (UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z) {
00692 X->Compatible(Y,Z) ;
00693 CopyExtensions(X) ;
00694 ba->XplusYmalZ(X->ba,Y->ba,Z->ba) ;
00695 Ext.XplusYmalZ(&X->Ext,&Y->Ext,&Z->Ext) ;
00696 }
00697
00698 template<int DIM>
00699 void UniformData<DIM>::XminusYmalZ(UniformData<DIM> *X , UniformData<DIM> *Y , UniformData<DIM> *Z) {
00700 X->Compatible(Y,Z) ;
00701 CopyExtensions(X) ;
00702 ba->XminusYmalZ(X->ba,Y->ba,Z->ba) ;
00703 Ext.XminusYmalZ(&X->Ext,&Y->Ext,&Z->Ext) ;
00704 }
00705
00706
00707
00708
00709
00710 template<int DIM>
00711 void UniformData<DIM>::ApplyOp(UniformData<DIM> *X,int dir,unsigned int op) {
00712 ApplyOp(Ext.BC[dir] , X , dir , op) ;
00713 }
00714
00715 template<int DIM>
00716 void UniformData<DIM>::ApplyOp(int *BCTo , UniformData<DIM> *X,int dir,unsigned int operation) {
00717 int op,res,J[DIM],dmy ;
00718 Matrix<double,DIM>::UniDirOperation uniop=NULL ;
00719 bool Trafo=false ;
00720
00721 op=NOOPERATION ;
00722 ba->CalcLevel(J) ;
00723 ba->SameSize(X->ba) ;
00724
00725 #ifdef _FFTW_
00726 int fftN=1<<J[dir] ;
00727 fftw_real *fftIn = (fftw_real *)malloc(sizeof(fftw_real)*fftN);
00728 fftw_real *fftOut= (fftw_real *)malloc(sizeof(fftw_real)*fftN);
00729 rfftw_plan fftp=NULL ;
00730 #endif
00731
00732 CopyExtensions(X) ;
00733 double DX=Ext.XE[dir]-Ext.XA[dir] ;
00734
00735
00736 if (operation==FD14II) operation=FD14 ;
00737 if (operation==FD24II) operation=FD24 ;
00738
00739 switch (operation) {
00740 case FIRSTDERIVATIVE: case STIFFNESS: case DIV: case GRAD: case FD12: case FD14: case FD22: case FD24:
00741 case DIVGRADFD4NOSTAB: case DIVGRAD: {
00742 assert(!Ext.islifting[dir]) ;
00743 uniop=applyOp ;
00744 op =operation ;
00745 Trafo=Ext.ismultiscale[dir] ;
00746 }
00747 break ;
00748 case PROJECTION: {
00749 uniop=Projection ;
00750 op =PROJECTION ;
00751 Trafo=Ext.ismultiscale[dir] ;
00752 }
00753 break ;
00754 case TRANSFORM: {
00755 assert(!Ext.ismultiscale[dir]) ;
00756 Ext.ismultiscale[dir]=true ;
00757 uniop=bwt ;
00758 op =J[dir]-Ext.WC->Level0 ;
00759 }
00760 break ;
00761 case INVERSETRANSFORM: {
00762 assert(Ext.ismultiscale[dir]) ;
00763 Ext.ismultiscale[dir]=false ;
00764 uniop=ibwt ;
00765 op =J[dir]-Ext.WC->Level0 ;
00766 }
00767 break ;
00768 case INTERPOLET2LIFTING: {
00769 assert(!Ext.islifting[dir]) ;
00770 assert(Ext.WC->InterpoletFlag) ;
00771 if (!Ext.ismultiscale[dir]) { Copy(X); Ext.islifting[dir]=true; return; }
00772 }
00773 break ;
00774 case LIFTING2INTERPOLET: {
00775 assert(Ext.islifting[dir]) ;
00776 assert(Ext.WC->InterpoletFlag) ;
00777 if (!Ext.ismultiscale[dir]) { Copy(X); Ext.islifting[dir]=false; return; }
00778 }
00779 break ;
00780 case POLYQUAD: case INVERSEPOLYQUAD: case NODALQUAD: case INVERSENODALQUAD: case ONEPOINTQUAD: case INVERSEONEPOINTQUAD: case SHORTQUAD: case INVERSESHORTQUAD: {
00781 assert(!Ext.ismultiscale[dir]) ;
00782 uniop=Quadrature ;
00783 op =operation ;
00784 }
00785 break ;
00786 case SMOOTH0: case SMOOTH1: case SMOOTH2: {
00787 assert(!Ext.ismultiscale[dir]) ;
00788 uniop=applyOp ;
00789 op =operation ;
00790 }
00791 break ;
00792 case SORTHB: {
00793 uniop=SortHB ;
00794 op =Ext.WC->Level0 ;
00795 }
00796 break ;
00797 case FFT: {
00798 assert(!Ext.ismultiscale[dir]) ;
00799 assert(Ext.BC[dir][1]==PERIODIC) ;
00800 Ext.ismultiscale[dir]=true ;
00801 #ifdef _FFTW_
00802 fftp = rfftw_create_plan(fftN, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
00803 #endif
00804 }
00805 break ;
00806 case IFFT: {
00807 assert(Ext.ismultiscale[dir]) ;
00808 assert(Ext.BC[dir][1]==PERIODIC) ;
00809 Ext.ismultiscale[dir]=false ;
00810 #ifdef _FFTW_
00811 fftp = rfftw_create_plan(fftN, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
00812 #endif
00813 }
00814 break ;
00815 default: { std::cout<< "UniformData<"<<DIM<<">::ApplyOp(): unsupported operation "<<operation<<"\n"; assert (0) ;}
00816 }
00817
00818
00819
00820
00821 Matrix<double,DIM>::iterator it,Xend=(*ba).end() ;
00822 int b=ba->b[dir] , e=ba->e[dir] ;
00823 double *s=_DATAMATRIX_BUFFER_s, *t=_DATAMATRIX_BUFFER_t, *q=_DATAMATRIX_BUFFER_q ;
00824
00825 for (it=(*ba).begin(dir) ; it<=Xend ; ++it) {
00826
00827 int *i=&it.i[dir] ;
00828 for ((*i)=b; (*i)<=e; (*i)++) s[(*i)-b]=(*X->ba)[it] ;
00829
00830 switch (operation) {
00831 case FFT: case IFFT: {
00832 #ifdef _FFTW_
00833 for (int j=0; j<fftN; j++) fftIn[j]=s[j] ;
00834 rfftw_one(fftp, fftIn, fftOut);
00835 for (int j=0; j<fftN; j++) t[j]=fftOut[j] ;
00836 #endif
00837 }
00838 break ;
00839 case INTERPOLET2LIFTING: case LIFTING2INTERPOLET: {
00840 Ext.WC->LiftingFlag=Ext.islifting[dir] ;
00841 ibwt (q,X->Ext.BC[dir], NULL , s,X->Ext.BC[dir] , Ext.WC, J[dir] , J[dir]-Ext.WC->Level0, DX) ;
00842 Ext.WC->LiftingFlag = !Ext.WC->LiftingFlag ;
00843 bwt (t,BCTo , &dmy , q,BCTo , Ext.WC, J[dir] , J[dir]-Ext.WC->Level0, DX) ;
00844 }
00845 break ;
00846 default: {
00847 Ext.WC->LiftingFlag=Ext.islifting[dir] ;
00848 if (!Trafo) {
00849 uniop(t,BCTo , &res , s,X->Ext.BC[dir] , Ext.WC, J[dir] , op , DX) ;
00850 } else {
00851 ibwt (t,X->Ext.BC[dir], NULL , s,X->Ext.BC[dir] , Ext.WC, J[dir] , J[dir]-Ext.WC->Level0, DX) ;
00852 if (op==DIVGRADFD4NOSTAB) {
00853 applyOp(q,BCTo , &res , t,X->Ext.BC[dir] , Ext.WC, J[dir] , FD14, DX) ;
00854 applyOp(s,BCTo , &res , q,X->Ext.BC[dir] , Ext.WC, J[dir] , FD14, DX) ;
00855 }
00856 else {
00857 uniop(s,BCTo , &res , t,X->Ext.BC[dir] , Ext.WC, J[dir] , op, DX) ;
00858 }
00859 bwt (t,BCTo , &dmy , s,BCTo , Ext.WC, J[dir] , J[dir]-Ext.WC->Level0, DX) ;
00860 }
00861 }
00862 break ;
00863 }
00864
00865 for ((*i)=b; (*i)<=e; (*i)++) (*ba)[it]=t[(*i)-b] ;
00866 }
00867
00868 Ext.SetBoundaryConditions(dir, BCTo) ;
00869
00870
00871
00872
00873 switch (operation) {
00874 case FFT: case IFFT: {
00875 Ext.ismultiscale[dir] = (operation==FFT);
00876 #ifdef _FFTW_
00877 free(fftIn) ;
00878 free(fftOut) ;
00879 rfftw_destroy_plan(fftp);
00880 #endif
00881 }
00882 break ;
00883 case INTERPOLET2LIFTING: case LIFTING2INTERPOLET: {
00884 Ext.islifting[dir] = !Ext.islifting[dir] ;
00885 }
00886 break ;
00887 default: ;
00888 }
00889
00890 }
00891
00892 template<int DIM>
00893 void UniformData<DIM>::SwitchToNoBoundaryConditions(UniformData<DIM> *X) {
00894 int dir,i,s1[DIM],s2[DIM] ;
00895 if (this != X) Copy(X) ;
00896
00897 for (dir=0; dir<DIM; dir++) {
00898 Matrix<double,DIM>::iterator s(ba , dir) ;
00899 if (Ext.BC[dir][0]==0) {
00900 for (s=(*ba).begin(); s<=(*ba).end(); ++s) {
00901 for (i=0; i<DIM; i++) s1[i]=s.i[i] ;
00902 s1[dir]=0 ;
00903 (*ba)[s1]=0 ;
00904 }
00905 }
00906
00907 if (Ext.BC[dir][0]==1) {
00908 for (s=(*ba).begin(); s<=(*ba).end(); ++s) {
00909 for(i=0; i<DIM; i++) s1[i]=s2[i]=s.i[i] ;
00910 s1[dir]=1 ;
00911 s2[dir]=0 ;
00912 (*ba)[s1]=(*ba)[s2] ;
00913 }
00914 }
00915
00916 if (Ext.BC[dir][1]==0) {
00917 for (s=(*ba).begin(); s<=(*ba).end(); ++s) {
00918 for (i=0; i<DIM; i++) s1[i]=s.i[i] ;
00919 s1[dir]=ba->e[dir] ;
00920 (*ba)[s1]=0 ;
00921 }
00922 }
00923
00924 if (Ext.BC[dir][1]==1) {
00925 for (s=(*ba).begin(); s<=(*ba).end(); ++s) {
00926 for(i=0; i<DIM; i++) s1[i]=s2[i]=s.i[i] ;
00927 s1[dir]=ba->e[dir]-1 ;
00928 s2[dir]=ba->e[dir] ;
00929 (*ba)[s1]=(*ba)[s2] ;
00930 }
00931 }
00932
00933 if (Ext.BC[dir][1]==PERIODIC) {
00934 for (s=(*ba).begin(); s<=(*ba).end(); ++s) {
00935 for(i=0; i<DIM; i++) s1[i]=s2[i]=s.i[i] ;
00936 s1[dir]=ba->e[dir]; s2[dir]=0 ;
00937 (*ba)[s1]=(*ba)[s2] ;
00938 }
00939 }
00940
00941 Ext.BC[dir][0]=Ext.BC[dir][1]=-1 ;
00942 }
00943 }
00944
00945
00946
00947 template<int DIM>
00948 double UniformData<DIM>::Integrate() {
00949
00950 int i,J[DIM] ;
00951 bool ms=Ext.ismultiscale[0] ;
00952
00953
00954 for (i=1; i<DIM; i++) assert (ms==Ext.ismultiscale[i]) ;
00955
00956 ba->CalcLevel(J) ;
00957 double r=0.0 ;
00958 if (ms) {
00959
00960 int A[DIM],a[DIM],e[DIM] ;
00961 for (i=0; i<DIM; i++) A[i]=Ext.WC->Level0 ;
00962
00963 Matrix<int,DIM>::iterator l(A,J) ;
00964 for (l.Set(A); l<=J; ++l) {
00965 for (i=0; i<DIM; i++) {
00966 a[i] = (l.i[i]==Ext.WC->Level0) ? 0 : (1<<(l.i[i]-1))+1 ;
00967 e[i] = 1<<l.i[i] ;
00968 }
00969 Matrix<double,DIM>::iterator s(a,e) ;
00970 for (s.Set(a); s<=e; ++s) {
00971 double t=1.0 ;
00972 for (i=0; i<DIM; i++) t *=Ext.WC->WaveletIntegral(l.i[i],s.i[i]-a[i],Ext.BC[i]) ;
00973 r +=(*ba)[s]*t ;
00974 }
00975 }
00976
00977 } else {
00978
00979 Matrix<double,DIM>::iterator s(ba) ;
00980 for (s=(*ba).begin(); s<= (*ba).end(); ++s) {
00981 double t=1.0 ;
00982 for (i=0; i<DIM; i++) t *=Ext.WC->ScalingFunctionIntegral(J[i],s.i[i],Ext.BC[i]) ;
00983
00984 r +=(*ba)[s]*t ;
00985 }
00986 }
00987
00988 return r ;
00989 }
00990
00991
00992
00993
00994 template<int DIM>
00995 double UniformData<DIM>::LpNorm(UniformData<DIM> *Tmp, double p) {
00996 int i,GBC[2] ;
00997 for (i=0; i<DIM; i++) {
00998 GetGeneralBoundaryConditions(Ext.BC[i],GBC) ;
00999 Tmp->ApplyOp(GBC, (i==0) ? this : Tmp , i , PROJECTION) ;
01000 }
01001
01002 for (i=0; i<DIM; i++)
01003 if (Tmp->Ext.islifting[i]) Tmp->ApplyOp(GBC, Tmp , i , LIFTING2INTERPOLET) ;
01004
01005 for (i=0; i<DIM; i++) Tmp->ApplyOp(GBC, Tmp , i , INVERSETRANSFORM) ;
01006 Tmp->Abs(Tmp) ;
01007
01008
01009 if (p==HUGE_VAL) return Tmp->Max() ;
01010
01011 Tmp->Pow(Tmp,p) ;
01012 return pow(Tmp->Integrate(),1/p) ;
01013 }
01014
01015 template<int DIM>
01016 double UniformData<DIM>::LmaxNorm(UniformData<DIM> *Tmp) { return LpNorm(Tmp,HUGE_VAL) ; }
01017
01018 template<int DIM>
01019 double UniformData<DIM>::L2Norm(UniformData<DIM> *Tmp) { return LpNorm(Tmp,2.0) ; }
01020
01021 template<int DIM>
01022 double UniformData<DIM>::L1Norm(UniformData<DIM> *Tmp) { return LpNorm(Tmp,1.0) ; }
01023
01024
01025
01026
01027
01028 template<int DIM>
01029 void UniformData<DIM>::MRATransform(UniformData<DIM> *X) {
01030 int L[DIM],l,dir,dmy ;
01031
01032 ba->SameSize (X->ba) ;
01033 for (dir=0; dir<DIM; dir++) assert(!X->Ext.ismultiscale[dir]) ;
01034
01035 ba->CalcLevel(L) ;
01036 CopyExtensions(X) ;
01037 for (dir=0; dir<DIM; dir++) Ext.ismultiscale[dir] = true ;
01038 Ext.SetBoundaryConditions(X->Ext.BC) ;
01039
01040 for (l=L[0]; l>=Ext.WC->Level0+1; l--) {
01041 int e[DIM] ;
01042 for (dir=0; dir<DIM; dir++) e[dir]=1<<l ;
01043
01044 for (dir=0; dir<DIM; dir++) {
01045 double DX=Ext.XE[dir]-Ext.XA[dir] ;
01046 Ext.WC->LiftingFlag=Ext.islifting[dir] ;
01047
01048 Matrix<double,DIM>::iterator it ;
01049 int b=ba->b[dir] ;
01050
01051 UniformData<DIM> *Y = ((l==L[0])&&(dir==0)) ? X : this ;
01052
01053 for (it=(*ba).begin(dir); it<=e; ++it) {
01054 double *s=_DATAMATRIX_BUFFER_s, *t=_DATAMATRIX_BUFFER_t ;
01055
01056 int *i=&it.i[dir] ;
01057 for ((*i)=b; (*i)<=e[dir]; (*i)++) s[(*i)-b]=(*Y->ba)[it] ;
01058 bwt (t,Ext.BC[dir], &dmy , s,Ext.BC[dir], Ext.WC, l , 1 , DX) ;
01059 for ((*i)=b; (*i)<=e[dir]; (*i)++) (*ba)[it]=t[(*i)-b] ;
01060 }
01061 }
01062 }
01063 }
01064
01065
01066 template<int DIM>
01067 void UniformData<DIM>::MRAInverseTransform(UniformData<DIM> *X) {
01068 int L[DIM],l,dir,dmy ;
01069
01070 ba->SameSize (X->ba) ;
01071 for (dir=0; dir<DIM; dir++) assert(X->Ext.ismultiscale[dir]) ;
01072
01073 ba->CalcLevel(L) ;
01074 CopyExtensions(X) ;
01075 for (dir=0; dir<DIM; dir++) Ext.ismultiscale[dir] = false ;
01076 Ext.SetBoundaryConditions(X->Ext.BC) ;
01077
01078 for (l=Ext.WC->Level0+1; l<=L[0]; l++) {
01079 int e[DIM] ;
01080 for (dir=0; dir<DIM; dir++) e[dir]=1<<l ;
01081
01082 for (dir=0; dir<DIM; dir++) {
01083 double DX=Ext.XE[dir]-Ext.XA[dir] ;
01084 Ext.WC->LiftingFlag=Ext.islifting[dir] ;
01085
01086 Matrix<double,DIM>::iterator it ;
01087 int b=ba->b[dir] ;
01088
01089 UniformData<DIM> *Y = ((l==L[0])&&(dir==0)) ? X : this ;
01090
01091 for (it=(*ba).begin(dir); it<=e; ++it) {
01092 double *s=_DATAMATRIX_BUFFER_s, *t=_DATAMATRIX_BUFFER_t ;
01093
01094 int *i=&it.i[dir] ;
01095 for ((*i)=b; (*i)<=e[dir]; (*i)++) s[(*i)-b]=(*Y->ba)[it] ;
01096 ibwt (t,Ext.BC[dir], &dmy , s,Ext.BC[dir], Ext.WC, l , 1 , DX) ;
01097 for ((*i)=b; (*i)<=e[dir]; (*i)++) (*ba)[it]=t[(*i)-b] ;
01098 }
01099 }
01100 }
01101 }
01102
01103
01104
01105
01106
01107
01108
01109 template<int DIM>
01110 void UniformData<DIM>::ReadSparse(const char *filename, int which) {
01111 ba->ReadSparse(filename,which,Ext.XA,Ext.XE,Ext.WC->Level0) ;
01112 }
01113
01114 template<int DIM>
01115 void UniformData<DIM>::WriteSparse(const char *filename, UniformData<DIM> **M, int N, bool CastToFloat) {
01116 int i ;
01117 Matrix<double,DIM> *MM[100] ;
01118 for (i=0; i<N ; i++) MM[i]=M[i]->ba ;
01119
01120 ba->WriteSparse(filename,Ext.XA, Ext.XE , Ext.WC->Level0, MM, N, CastToFloat) ;
01121 }
01122
01123
01124 template<int DIM>
01125 void UniformData<DIM>::WriteUDF(const char *name, UniformData<DIM> *Tmp, bool Cast2Float) {
01126 UniformData<DIM> *A=this ;
01127 if (Tmp!=NULL) {
01128 for (int i=0; i<DIM; i++)
01129 if (Ext.ismultiscale[i]) {
01130 Tmp->ApplyOp(Ext.BC[i] , A , i , INVERSETRANSFORM) ;
01131 A=Tmp ;
01132 }
01133 }
01134 A->ba->WriteUDF(name,&A->Ext, "scalar" , NULL , 1, Cast2Float, false) ;
01135 }
01136
01137 template<int DIM>
01138 void UniformData<DIM>::ReadUDF(const char *name) {
01139 ba->ReadUDF(name,&Ext, "scalar") ;
01140 }
01141
01142
01143
01144
01145
01146
01147 template<int DIM>
01148 void UniformData<DIM>::FourierSpectrum(double *sp, int *Kmin,int *Kmax) {
01149 int i,j,N[DIM],anz=1 ;
01150
01151
01152 double ar[DIM],mdx=1e+100,DX[DIM],vol=1.0 ;
01153 for (i=0; i<DIM; i++) {
01154 N[i] =(ba->e[i] - ba->b[i]) ;
01155 anz *=N[i] ;
01156
01157 DX[i]=Ext.XE[i]-Ext.XA[i] ;
01158 vol *=DX[i] ;
01159 mdx =min(mdx,DX[i]) ;
01160 }
01161
01162 for (i=0; i<DIM; i++) ar[i]=DX[i]/mdx ;
01163
01164
01165 j=10000 ;
01166 for (i=0; i<DIM; i++) j=min(j,(int)(N[i]/ar[i])) ;
01167 *Kmin=j ;
01168
01169
01170 int a[DIM],e[DIM] ;
01171 double mxf=0 ;
01172 for (i=0; i<DIM; i++) {
01173 a[i] =-(N[i]/2 -1) ;
01174 e[i] = N[i]/2 ;
01175 mxf += sqr(e[i]/ar[i]) ;
01176 }
01177 mxf=sqrt(mxf) ;
01178 *Kmax=(int)mxf ;
01179 for (i=0; i<=*Kmax; i++) sp[i]=0 ;
01180
01181 Matrix<double,DIM>::iterator s(a,e) ;
01182 for (s.Set(a); s<=e; ++s) {
01183
01184 double k=0,re,im ;
01185 for (i=0; i<DIM; i++) k += sqr(s.i[i]/ar[i]) ;
01186
01187 FourierCoefficient(&re,&im,s.i) ;
01188 sp[(int)sqrt(k)] += (re*re + im*im) ;
01189 }
01190
01191
01192 for (i=0; i<=*Kmax; i++) {
01193 sp[i] *= vol/((double)anz*anz) ;
01194 }
01195 }
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 template<int DIM>
01210 void UniformData<DIM>::FourierCoefficient(double *re, double *im, int *k) {
01211 int kk[DIM],N[DIM],q=0,i,d2=1<<DIM ;
01212
01213
01214 for (i=0; i<DIM; i++) {
01215 N[i]=(ba->e[i] - ba->b[i]) ;
01216 if (k[i] < 0) { kk[i]= -k[i], q |= (1<<i) ;}
01217 else { kk[i]= k[i] ; }
01218 }
01219
01220
01221 double rj[1<<DIM] ;
01222 int rjq ;
01223 for (rjq=0; rjq<d2; rjq++) {
01224 int kq[DIM] ;
01225 for (i=0; i<DIM; i++) {
01226 if (rjq & (1<<i) ) kq[i]=N[i]-kk[i] ;
01227 else kq[i]= kk[i] ;
01228 }
01229 rj[rjq]=(*ba)[kq] ;
01230 }
01231
01232
01233 for (i=0 ; i< DIM; i++) {
01234 if ((kk[i]==0)||(kk[i]==N[i]/2))
01235 for (rjq=0; rjq<d2; rjq++)
01236 if (rjq & (1<<i)) rj[rjq]=0 ;
01237 }
01238
01239
01240 *re=*im=0 ;
01241 for (rjq=0; rjq<d2; rjq++) {
01242
01243
01244
01245
01246
01247
01248
01249 int nj=0,nq=0 ;
01250 for (i=0; i<DIM; i++) {
01251 if ( rjq & (1<<i)) nj++ ;
01252 if ((rjq & q) & (1<<i)) nq++ ;
01253 }
01254
01255
01256 double sg,sq ;
01257 i=nj/2 ;
01258 sg = (i & 1) ? -1 : 1 ;
01259 sq = (nq & 1) ? -1 : 1 ;
01260
01261 if (nj&1) {
01262 *im -= rj[rjq]*sg*sq ;
01263 } else {
01264 *re += rj[rjq]*sg*sq ;
01265 }
01266 }
01267 }
01268
01269
01270
01271
01272
01273
01274 template<int DIM>
01275 void UniformData<DIM>::MeanVariance(double *mean, double *variance, int dir) {
01276 int i,j,e=(*ba).size(dir),size ;
01277
01278 for (j=0; j<e; j++) {
01279 double u=0,u2=0,x;
01280
01281 Matrix<double,DIM>::iterator s(ba , dir) ;
01282 size=0 ;
01283 for (s=(*ba).begin(dir); s<=(*ba).end(); ++s) {
01284 int t[DIM] ;
01285 for (i=0; i<DIM; i++) t[i]=s.i[i] ;
01286 t[dir]=j ;
01287 x = (*this)[t] ;
01288 u += x ;
01289 u2 += x*x ;
01290 size++ ;
01291 }
01292 u /= size ;
01293 u2 /= size ;
01294 mean [j] = u ;
01295 variance[j] = u2 - u*u ;
01296 }
01297 }
01298
01299 #endif