//--------------------------------------------------
int fdct_wrapping_param_sepangle(double XL1, double XL2, int nbangle,
											vector<double>& sx, vector<double>& sy,
											vector<double>& fx, vector<double>& fy,
											vector<int>& nx, vector<int>& ny)
{
  fx.resize(nbangle);  fy.resize(nbangle);
  nx.resize(nbangle);  ny.resize(nbangle);
  sx.resize(nbangle);  sy.resize(nbangle);
 
  int nbquadrants = 4;
  int nd = nbangle / 4;  //int nbangles_perquad = nbangles[sc] / 4;
  int wcnt = 0;
  //backup
  double XL1b = XL1;  double XL2b = XL2;
  int qvec[] = {2,1,0,3};
  for(int qi=0; qi<nbquadrants; qi++) {
	 int q = qvec[qi];
	 fdct_wrapping_rotate_forward(q, XL1b, XL2b, XL1, XL2);	 XL1 = abs(XL1);	 XL2 = abs(XL2);
	 double XW1 = XL1/nd;	 double XW2 = XL2/nd;
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 for(int w=nd-1; w>=0; w--) {
		//get size
		double xs = XR1/4 - (XW1/2)/4;
		double xe = XR1;
		double ys = -XR2 + (w-0.5)*XW2;
		double ye = -XR2 + (w+1.5)*XW2; //x range
		int xn = int(ceil(xe-xs));			 int yn = int(ceil(ye-ys));
		//MAKE THEM ODD
		if(xn%2==0) xn++;		if(yn%2==0) yn++;
		
		double tx; double ty;
		//fx,fy
		tx = XR1/2;		ty = (-XR2 + (w+0.5)*XW2)/2; //center, NOTE: need /2
		fdct_wrapping_rotate_backward(q, tx, ty, fx[wcnt], fy[wcnt]);
		//sx, sy;
		tx = 1.0/xn;		ty = 1.0/yn;
		fdct_wrapping_rotate_backward(q, xn, yn, nx[wcnt], ny[wcnt]);		nx[wcnt] = abs(nx[wcnt]);		ny[wcnt] = abs(ny[wcnt]);
		fdct_wrapping_rotate_backward(q, tx, ty, sx[wcnt], sy[wcnt]);		sx[wcnt] = abs(sx[wcnt]);		sy[wcnt] = abs(sy[wcnt]);
		wcnt++;
	 }
  }
  
  return 0;
}
Example #2
0
//-----------------------------------------------------------------------
int fdct_wrapping_sepangle(double XL1, double XL2, int nbangle, CpxOffMat& Xhgh, vector<CpxNumMat>& csc)
{
  //WEDGE ORDERING: from -45 degree, counter-clockwise
  typedef pair<int,int> intpair;
  map<intpair, fftwnd_plan> planmap;
  
  int nbquadrants = 4;
  int nd = nbangle / 4;
  int wcnt = 0;
  
  //backup
  CpxOffMat Xhghb(Xhgh);
  double XL1b = XL1;  double XL2b = XL2;
  
  int qvec[] = {2,1,0,3};
  for(int qi=0; qi<nbquadrants; qi++) {
	 int q = qvec[qi];
	 //ROTATE data to its right position
	 fdct_wrapping_rotate_forward(q, XL1b, XL2b, XL1, XL2);	 XL1 = abs(XL1);	 XL2 = abs(XL2);
	 fdct_wrapping_rotate_forward(q, Xhghb, Xhgh);
	 //figure out XS, XF, XR
	 double XW1 = XL1/nd;	 double XW2 = XL2/nd;
	 int XS1, XS2;  int XF1, XF2;  double XR1, XR2;  fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2);
	 for(int w=nd-1; w>=0; w--) {
		double xs = XR1/4 - (XW1/2)/4;
		double xe = XR1;
		double ys = -XR2 + (w-0.5)*XW2;
		double ye = -XR2 + (w+1.5)*XW2; //x range
		int xn = int(ceil(xe-xs));			 int yn = int(ceil(ye-ys));
		//MAKE THEM ODD
		if(xn%2==0) xn++;		if(yn%2==0) yn++;
		int xf = int(ceil(xs));			 //int yf = int(ceil(ys));
		//theta
		double thts, thtm, thte; //y direction
		if(w==0) {
		  thts = atan2(-1.0, 1.0-1.0/nd);
		  thtm = atan2(-1.0+1.0/nd, 1.0);
		  thte = atan2(-1.0+3.0/nd, 1.0);
		} else if(w==nd-1) {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(1.0, 1.0-1.0/nd);
		} else {
		  thts = atan2(-1.0+(2.0*w-1.0)/nd, 1.0);
		  thtm = atan2(-1.0+(2.0*w+1.0)/nd, 1.0);
		  thte = atan2(-1.0+(2.0*w+3.0)/nd, 1.0);
		}
		//wrapping
		int xh = xn/2;		int yh = yn/2; //half length
		double R21 = XR2/XR1; //ratio
		CpxOffMat wpdata(xn,yn);
		for(int xcur=xf; xcur<xe; xcur++) { //for each layer
		  int yfm = (int)ceil( max(-XR2, R21*xcur*tan(thts)) );
		  int yto = (int)floor( min(XR2, R21*xcur*tan(thte)) );
		  for(int ycur=yfm; ycur<=yto; ycur++) {
			 int tmpx = xcur%xn;				  if(tmpx<-xh) tmpx+=xn;				  if(tmpx>=-xh+xn) tmpx-=xn;
			 int tmpy = ycur%yn;				  if(tmpy<-yh) tmpy+=yn;				  if(tmpy>=-yh+yn) tmpy-=yn;
			 wpdata(tmpx,tmpy) = Xhgh(xcur,ycur);
			 //partition of unity
			 double thtcur = atan2(ycur/XR2, xcur/XR1);
			 double wtht;
			 if(thtcur<thtm) {
				double l,r; fdct_wrapping_window((thtcur-thts)/(thtm-thts), l, r);
				wtht = l;
			 } else {
				double l,r; fdct_wrapping_window((thtcur-thtm)/(thte-thtm), l, r);
				wtht = r;
			 }
			 double pou = wtht;
			 wpdata(tmpx,tmpy) *= pou;
		  }
		}
		//IFFT
		{
		  //rotate backward
		  CpxOffMat rpdata;
		  fdct_wrapping_rotate_backward(q, wpdata, rpdata);
		  //ifftshift
		  int xn = rpdata.m();		int yn = rpdata.n(); //reset xn, yn
		  CpxNumMat tpdata(xn,yn);
		  fdct_wrapping_ifftshift(rpdata, tpdata);
		  //ifft
		  fftwnd_plan p = NULL;
		  map<intpair,fftwnd_plan>::iterator mit=planmap.find( intpair(xn,yn) );
		  if(mit!=planmap.end()) {
			 p = (*mit).second;
		  } else {
			 p = fftw2d_create_plan(yn, xn, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE);
			 planmap[ intpair(xn, yn) ] = p;
		  }
		  fftwnd_one(p, (fftw_complex*)tpdata.data(), NULL);
		  double sqrtprod = sqrt(double(xn*yn));
		  for(int j=0; j<yn; j++)		  for(int i=0; i<xn; i++)			 tpdata(i,j) /= sqrtprod;
		  //store
		  csc[wcnt] = tpdata;
		}
		
		//fdct_wrapping_fftshift(xn,yn,xh,yh,tpdata,wpdata);
		//ROTATION
		//fdct_wrapping_rotate_backward(q, wpdata, csc[wcnt]);
		
		wcnt++;
	 } //end of w loop
  } //end of q loop
  //PUT THE RIGHT DATA BACK
  Xhgh = Xhghb;
  XL1 = XL1b;  XL2 = XL2b;
  
  for(map<intpair, fftwnd_plan>::iterator mit=planmap.begin(); mit!=planmap.end(); mit++) {
	 fftwnd_plan p = (*mit).second;
	 fftwnd_destroy_plan(p);
  }
  return 0;
}