⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shiftgabormp.cc

📁 小波分析程序
💻 CC
字号:
#include "ShiftGaborMP.h"#include <math.h>real RunShiftGaborMP(int max_iter, // maximal number of iterations 		     real epsilon, // desired precision | Rf | < epsilon		     const Interval &f, // signal to be approximated		     // assumption : f sampled on integers starting with 0		     // i.e.  f.beg must be 0. No constraints on f.length.		     const Partition &Part, // partiton which defining		     //dictionary		     Interval &f_approx, // MP approximation of f		     // f_approx is a linear combination of Gabors		     Interval &Rf, // final residual: Rf = f - f_approx		     // error which is returned equals | Rf |		     vector <RealGabor> &G, // vector of Gabors chosen for		     // f_approx		     vector <real> & Gcoef // coeficinets in the linear		     // combination, corresponding to Gabors in G		     // f_approx = sum( Gcoef[i] * G[i] ), where number of i's		     // depends on epsilon and max_iter		    ){  integer dim = f.length;  assert( f.beg == 0 && dim > 0);  Interval I(0, dim-1);  for(int i=0; i<dim; i++) I.origin[i] = i;    //declare some temporary objects to receive outputs from getOptimalShiftGabor  real coef=0.0, error=0.0;  RealGabor Gtemp;    // Initialize Rf and f_approx  f_approx.Set(0, dim-1);  Rf = f;      real *Gptr, *fptr, *Rfptr;  for(int iter=0; iter < max_iter; iter++)	{	  getOptimalShiftGabor(Rf, Part, Gtemp, coef);	  Gtemp.createSample(I); 	  G.push_back(Gtemp); 	  Gcoef.push_back(coef);	  Gptr = Gtemp.Sample.origin;  fptr = f_approx.origin; 	  Rfptr = Rf.origin;	  error = 0;	  for(integer t=0; t<dim; t++)	    {	      *fptr += (*Gptr) * coef;	      (*Rfptr) -= (*Gptr) * coef;	      error += (*Rfptr) * (*Rfptr);	      ++Gptr;  ++fptr;  ++Rfptr;	    }	  error = sqrt(error);	  if( error < epsilon )	    {/*	      cout << "Desired precision achieved in " << iter+1 	      << " iterations. " << endl;  */	      break;	    }	}  return error;}//////////////////////////////////////////////////////////////////void getOptimalShiftGabor(const Interval &f,  // signal			  const Partition &Part,			  RealGabor &G, // optimal Gabor, the one closest to f			  real &coef   // <f, G>		 		     ){  integer dim = f.length;  integer c = dim / 2;  // midpoint or left midpoint of the interval [0, dim-1]                        // depending on whether dim is odd or even  integer t, ddu;  // ddu will hold (integer)du[j]  real ddv;        // ddv will hold dv[j]  integer lmshift = Part.lmu - c, rmshift = Part.rmu - c; // leftmost and rightmost  // shifts with respect to the central position c  real codv, sidv, covshift, sivshift; // codv will hold cos( ddv )                                       // covshift will hold cos( v * shift )  Interval CO, SI; // CO[t] will hold cos( t * v )  integer  beg, end;  Interval P, Q;  real a, b, phase, Pnorm2, Qnorm2, PprodQ, a1, b1, product;  real atemp, btemp, Pnorm2temp, Qnorm2temp, PprodQtemp;  real *Pptr, *Qptr, *fptr, *COptr, *SIptr;   real covlms, sivlms, covdu, sivdu, codvlms, sidvlms, codvdu, sidvdu, temp;  // covlms will hold cos(v * lmshift), codvlms will hold cos(ddv * lmshift)  // covdu will hold cos( v * ddu ), codvdu will hold cos(ddv * ddu)  coef = 0;  for( integer j = Part.s.beg; j <= Part.s.end; j++ )    {      // set up      ddv = Part.dv.origin[j];        ddu = (integer)(Part.du.origin[j]); // effectively floor           beg = maximum(c - 4 * (integer)(Part.s.origin[j]), c - dim);        end = minimum(c + 4 * (integer)(Part.s.origin[j]), c + dim);      P.Set(beg, end);      Q.Set(beg, end);      CO.Set(beg, end);         SI.Set(beg, end);      codv = cos( ddv );  sidv = sin( ddv ); // used for uodating CO, SI      Pptr = P.origin + beg;       COptr = CO.origin + beg;  SIptr = SI.origin + beg;      // do first elements separately      *Pptr++ = g((real)(beg - c) / Part.s.origin[j]);      *COptr++ = cos( beg * ddv );    *SIptr++ = sin( beg * ddv );      for(t = beg + 1; t <= end; t++) 	{	  *Pptr++ = g((real)(t - c)/Part.s.origin[j]);	  *COptr = *(COptr - 1) * codv - *(SIptr - 1) * sidv;	  *SIptr = *(COptr - 1) * sidv + *(SIptr - 1) * codv;	  COptr++;  SIptr++;	}           codvlms = cos( ddv * lmshift ) ;  sidvlms = sin( ddv * lmshift );      codvdu = cos( ddv * ddu );   sidvdu = sin( ddv * ddu );      covlms = covdu = 1;  sivlms = sivdu = 0;       // by now everything is set up for v=0      // Now do v=0 separately       for(integer shift = lmshift; shift <= rmshift; shift += ddu)	{	  // covshift = cos(v*shift);  sivshift = sin(v*shift)	  beg = maximum(0, P.beg + shift);  	  end = minimum(dim-1, P.end + shift);	  // calculate just a and norm P	  a = Pnorm2 = 0;	  Pptr = P.origin + beg - shift;  	  fptr = f.origin + beg;	  for( t=beg; t<=end; t++)	    {	      Pnorm2 += (*Pptr) * (*Pptr);	      a += (*fptr++) * (*Pptr++);	    }	  product = a / sqrt(Pnorm2);	  phase = 0;	  if ( absval(product) > absval(coef)  )	    {	      coef = product;	      G.Set( Part.s.origin[j], c + shift, 0, phase );	    }	} // end of shift loop for case v = 0      // Now do the rest of v's      for(real v=ddv; v < Part.rmv; v += ddv)	{ 	  // update P, Q for this new value of v	  for( t = P.beg; t <= P.end; t++)	    {	      temp = P.origin[t];	      P.origin[t] = temp * CO.origin[t] - Q.origin[t] * SI.origin[t];	      Q.origin[t] = temp * SI.origin[t] + Q.origin[t] * CO.origin[t];	    }	  // update covlms, sivlms , covdu, sivdu for this new value of v	  temp = covlms;	  covlms = temp * codvlms - sivlms * sidvlms;	  sivlms = temp * sidvlms + sivlms * codvlms;	  temp = covdu;	  covdu = temp * codvdu - sivdu * sidvdu;	  sivdu = temp * sidvdu + sivdu * codvdu;	  // initialize covshift with cos( v * lmshift )   	  covshift = covlms;  sivshift = sivlms;		  for(integer shift = lmshift; shift <= rmshift; shift += ddu)	    {	      // covshift = cos(v*shift);  sivshift = sin(v*shift)	      beg = maximum(0, P.beg + shift);  	      end = minimum(dim-1, P.end + shift);	      // calculate a, b, a1, b1	      atemp = btemp = PprodQtemp = Pnorm2temp = Qnorm2temp = 0;	      Pptr = P.origin + beg - shift;  Qptr = Q.origin + beg - shift;	      fptr = f.origin + beg;	      for( t=beg; t<=end; t++)		{		  Pnorm2temp += (*Pptr) * (*Pptr);		  Qnorm2temp += (*Qptr) * (*Qptr);		  PprodQtemp += (*Pptr) * (*Qptr);		  atemp += (*fptr) * (*Pptr++);		  btemp += (*fptr++) * (*Qptr++);		}	      Pnorm2 = Pnorm2temp * covshift * covshift                    + Qnorm2temp * sivshift * sivshift	           - 2.0 * PprodQtemp * covshift * sivshift;	      Qnorm2 = Pnorm2temp * sivshift * sivshift 	              + Qnorm2temp * covshift * covshift		      + 2.0 * PprodQtemp * covshift * sivshift;	      PprodQ = (Pnorm2temp - Qnorm2temp) * covshift * sivshift 	           + PprodQtemp * (covshift * covshift - sivshift * sivshift);	      a = atemp * covshift - btemp * sivshift;	      b = atemp * sivshift + btemp * covshift;	      a1 = a * Qnorm2 - b * PprodQ;	      b1 = b * Pnorm2 - a * PprodQ;	      if( Pnorm2 > 1.0e-16  && Qnorm2 > 1.0e-16 		  && absval(a1) > 1.0e-16 ) 		{	  		  product= (a*a1 + b*b1)/		    sqrt(a1*a1*Pnorm2 + b1*b1*Qnorm2 + 2*a1*b1*PprodQ);		  phase = atan2(-b1, a1);		}	      else    // deal specialy with cases P=0 and Q=0		{		  if( Qnorm2 <= 1.0e-16 ) // Q = 0		    {  product = a / sqrt(Pnorm2);  phase = 0.0;   }		  else // P = 0 or a1 = 0		    {  product = -b / sqrt(Qnorm2) ;   phase = M_PI * 0.5;  }		}	      // cout  << "product " << product << endl;	      if ( absval(product) > absval(coef)  )		{		  coef = product;		  G.Set( Part.s.origin[j], c + shift, v, phase );		}	      // update covshift and sivshift for next value of shift	      temp = covshift;	      covshift = temp * covdu - sivshift * sivdu;	      sivshift = temp * sivdu + sivshift * covdu;	    } // end of shift loop	} // end of v loop    } // end of s loop}//////////////////////////////////////////////////////////      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -