//----------------------------------------------------------------------- int fdct_wrapping_wavelet(CpxOffMat& Xhgh, vector<CpxNumMat>& csc) { int N1 = Xhgh.m(); int N2 = Xhgh.n(); int F1 = -Xhgh.s(); int F2 = -Xhgh.t(); CpxNumMat T(N1, N2); fdct_wrapping_ifftshift(Xhgh, T); fftwnd_plan p = fftw2d_create_plan(N2, N1, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); fftwnd_one(p, (fftw_complex*)T.data(), NULL); fftwnd_destroy_plan(p); double sqrtprod = sqrt(double(N1*N2)); for(int j=0; j<N2; j++) for(int i=0; i<N1; i++) T(i,j) /= sqrtprod; csc[0] = T; //csc[0].resize(N1, N2); //fdct_wrapping_fftshift(T, csc[0]); return 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; }