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  

UniformData.hpp

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   // Compatibility Check for multi-array operations like A+B,A+B+C and so on
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   // Linear operators
00156   void   ApplyOp(UniformData<DIM> *X,int dir,unsigned int op) ;
00210   void   ApplyOp(int *BCT , UniformData<DIM> *X,int dir,unsigned int op) ;
00211   
00212   void   SwitchToNoBoundaryConditions(UniformData<DIM> *X) ; // result has in any case [-1,-1] BCs
00213   // void    RestrictPressure() ;
00215   void   MRATransform       (UniformData<DIM> *X) ;
00217   void   MRAInverseTransform(UniformData<DIM> *X) ;
00218  
00219 
00222   void   FourierCoefficient(double *re, double *im, int *k) ;
00223   
00224   // FourierSpectrum, reliable for 0\le k < Kmin, 
00225   // nonzero                   for 0\le k \le Kmax
00226   void   FourierSpectrum(double *sp, int *Kmin, int *Kmax) ;
00227 
00228   
00229   // Calculate mean and variance of slices along the <dir> coordinate direction  
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   // special functions
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   //internal data
00258   Matrix<double , DIM> *ba ;
00259   Extensions<DIM> Ext      ;
00260 } ;
00261 
00262 
00264 //                              //
00265 // UniformData: Implementations //
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 // Check
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 // BoundaryConditions
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 // Set
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  // test/set valid boundary conditions
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 // Linear Algebra
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  // patch grid extensions
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 // Norms
00547 template<int DIM>
00548 double UniformData<DIM>::LpNorm(UniformData<DIM> *Tmp, double p) {
00549  int i,GBC[2] ;
00550  for (i=0; i<DIM; i++) {
00551    GetGeneralBoundaryConditions(BC[i],GBC) ;
00552    Tmp->ApplyOp(GBC, (i==0) ? this : Tmp , i , PROJECTION) ;
00553  }
00554 
00555  for (i=0; i<DIM; i++) Tmp->ApplyOp(GBC, Tmp , i , INVERSETRANSFORM) ;
00556  Tmp->Abs(Tmp) ;
00557 
00558  // Maximum Norm
00559  if (p==HUGE_VAL) return Tmp->Max() ;
00560 
00561  Tmp->Pow(Tmp,p) ;
00562  for (i=0; i<DIM; i++) Tmp->ApplyOp(GBC, Tmp , i , TRANSFORM) ;
00563 
00564  return pow(Tmp->Integrate(),1/p) ;
00565 }
00566 
00567 template<int DIM>
00568 double UniformData<DIM>::LmaxNorm(UniformData<DIM> *Tmp) { return LpNorm(Tmp,HUGE_VAL) ; }
00569 
00570 template<int DIM>
00571 double UniformData<DIM>::L2Norm(UniformData<DIM> *Tmp)   { return LpNorm(Tmp,2.0) ; }
00572 
00573 template<int DIM>
00574 double UniformData<DIM>::L1Norm(UniformData<DIM> *Tmp)   { return LpNorm(Tmp,1.0) ; }
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 // linear Operators
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  // the fully consistent AFD2 algorithms coincide with standard algorithms in the non-adaptive case.
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  // main loop along coordinate <dir>
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: { // all other operations 
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  // clean up
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  // Integrate of multi / single scale function ?
00950  int i,J[DIM] ;
00951  bool ms=Ext.ismultiscale[0] ;
00952   
00953  // only complete multi- or single scale allowed
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) { // multiscale
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      } // s
00975    } // l
00976 
00977  } else {  // single scale
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 // Norms
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  // Maximum Norm
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 //  isotropic transforms
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       } // it
01061     } // dir
01062   } // l 
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       } // it
01099     } // dir
01100   } // l 
01101 }
01102 
01103 
01104 
01105 // 
01106 //  IO & UDF
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) { // transform to nodal values whenever necessary
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 //  FOURIER STUFF
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   // dimensions, number of elements, size of domain, aspect ratio 
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   // find smallest reliable wave number
01165   j=10000 ;
01166   for (i=0; i<DIM; i++) j=min(j,(int)(N[i]/ar[i])) ;
01167   *Kmin=j ;
01168 
01169   // now the FourierSpectrum 
01170   int a[DIM],e[DIM] ;
01171   double mxf=0 ;
01172   for (i=0; i<DIM; i++) {
01173     a[i] =-(N[i]/2 -1) ; // lowest  frequency
01174     e[i] =  N[i]/2     ; // highesy frq
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     // wavenumber
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   // remove wrong scaling
01192   for (i=0; i<=*Kmax; i++) {
01193    sp[i] *= vol/((double)anz*anz) ;
01194   }
01195 }
01196 
01197 
01198 //
01199 // access to Fouriercoefficients is a little bit complicated, due to
01200 // the special storage scheme of the real->complex FFT of the fftw
01201 //
01202 // since real an imaginary parts are stored separately from each other and
01203 // then are seperately transformed with respect to the other directions
01204 // one has to collect the real an imaginary parts from all 2^D qudrants
01205 // plus: one has to care about different signs with wich these 
01206 // terms contribute to the final value
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   // determine quadrant and index for quadrant 0 
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   // collect all entries from the various subquadrants
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   // delete spurious entries
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   // sum the different entries 
01240   *re=*im=0 ;
01241   for (rjq=0; rjq<d2; rjq++) {
01242 
01243     // nj = number of active bits in rjq == power of sqrt(-1) -> if nj is even: rj[rjq] is real
01244     //                                                           if nj is odd : rj[rjq] is imaginary
01245     // nj/2 gives the power of (-1) with wich rj[rjq] contributes to the real/imaginary part
01246     //   
01247     // number of coinciding bits in rjq and q == number of multiplys by -1 
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     // get signs    
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) { // nj odd -> rj[rjq] contributes to imaginary part
01262        *im -= rj[rjq]*sg*sq ;
01263     } else {  // nj even -> rj[rjq] contributes to real part 
01264        *re += rj[rjq]*sg*sq ;
01265     }
01266   }
01267 }
01268 
01269 
01270 
01271 //
01272 //  MEAN and VARIANCE
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     // calculate mean values along a x-z plane
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

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