//------------------------------------------------------------------------- //just the transpose, int ztran(const CpxNumMat& A, CpxNumMat& B) { B.resize(A.n(), A.m()); for(int i=0; i<B.m(); i++) for(int j=0; j<B.n(); j++) B(i,j) = A(j,i); return 0; }
//Y <- a M X + b Y // ---------------------------------------------------------------------- int zgemv(cpx alpha, const CpxNumMat& A, const CpxNumVec& X, cpx beta, CpxNumVec& Y) { assert(Y.m() == A.m()); assert(A.n() == X.m()); char trans = 'N'; int m = A.m(); int n = A.n(); int incx = 1; int incy = 1; zgemv_(&trans, &m, &n, &alpha, A.data(), &m, X.data(), &incx, &beta, Y.data(), &incy); return 0; }
// ---------------------------------------------------------------------- int zgemm(cpx alpha, const CpxNumMat& A, const CpxNumMat& B, cpx beta, CpxNumMat& C) { assert( A.m() == C.m() ); assert( A.n() == B.m() ); assert( B.n() == C.n() ); char transa = 'N'; char transb = 'N'; int m = C.m(); int n = C.n(); int k = A.n(); zgemm_(&transa, &transb, &m, &n, &k, &alpha, A.data(), &m, B.data(), &k, &beta, C.data(), &m); return 0; }
inline float energy(CpxNumMat& m) { float val=0; cpx* data = m.data(); for(int i=0; i<m.m()*m.n(); i++) { //val += data[i].re*data[i].re + data[i].im*data[i].im; val += norm(data[i]); } return val; }
//------------------------------------------------------------------- int fdct_wrapping(int N1, int N2, int nbscales, int nbangles_coarse, int allcurvelets, CpxNumMat& x, vector< vector<CpxNumMat> >& c) { //--------------------------------------------- assert(N1==x.m() && N2==x.n()); int F1 = N1/2; int F2 = N2/2; // ifft original data CpxNumMat T(x); fftwnd_plan p = fftw2d_create_plan(N2, N1, FFTW_FORWARD, 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; CpxOffMat O(N1, N2); fdct_wrapping_fftshift(T, O); //----------------------------------------------------------------------------- vector<CpxOffMat> Xhghs; Xhghs.resize(nbscales); CpxOffMat X; //unfold or not if(allcurvelets==1) { //-------------------------- double XL1 = 4.0*N1/3.0; double XL2 = 4.0*N2/3.0; //range int XS1, XS2; int XF1, XF2; double XR1, XR2; fdct_wrapping_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2); IntOffVec t1(XS1); for(int i=-XF1; i<-XF1+XS1; i++) if( i<-N1/2) t1(i) = i+int(N1); else if(i>(N1-1)/2) t1(i) = i-int(N1); else t1(i) = i; IntOffVec t2(XS2); for(int i=-XF2; i<-XF2+XS2; i++) if( i<-N2/2) t2(i) = i+int(N2); else if(i>(N2-1)/2) t2(i) = i-int(N2); else t2(i) = i; X.resize(XS1, XS2); for(int j=-XF2; j<-XF2+XS2; j++) for(int i=-XF1; i<-XF1+XS1; i++) X(i,j) = O(t1(i), t2(j)); DblOffMat lowpass(XS1,XS2); fdct_wrapping_lowpasscompute(XL1, XL2, lowpass); //compute the low pass filter for(int j=-XF2; j<-XF2+XS2; j++) for(int i=-XF1; i<-XF1+XS1; i++) X(i,j) *= lowpass(i,j); } else { //-------------------------- X = O; } //separate double XL1 = 4.0*N1/3.0; double XL2 = 4.0*N2/3.0; //range for(int sc=nbscales-1; sc>0; sc--) { double XL1n = XL1/2; double XL2n = XL2/2; int XS1n, XS2n; int XF1n, XF2n; double XR1n, XR2n; fdct_wrapping_rangecompute(XL1n, XL2n, XS1n, XS2n, XF1n, XF2n, XR1n, XR2n); //computer filter DblOffMat lowpass(XS1n, XS2n); fdct_wrapping_lowpasscompute(XL1n, XL2n, lowpass); DblOffMat hghpass(XS1n, XS2n); for(int j=-XF2n; j<-XF2n+XS2n; j++) for(int i=-XF1n; i<-XF1n+XS1n; i++) hghpass(i,j) = sqrt(1-lowpass(i,j)*lowpass(i,j)); //separate CpxOffMat Xhgh(X); for(int j=-XF2n; j<-XF2n+XS2n; j++) for(int i=-XF1n; i<-XF1n+XS1n; i++) Xhgh(i,j) *= hghpass(i,j); CpxOffMat Xlow(XS1n, XS2n); for(int j=-XF2n; j<-XF2n+XS2n; j++) for(int i=-XF1n; i<-XF1n+XS1n; i++) Xlow(i,j) = X(i,j) * lowpass(i,j); //store and prepare for next level Xhghs[sc] = Xhgh; X = Xlow; XL1 = XL1/2; XL2 = XL2/2; } Xhghs[0] = X; //----------------------------------------------------------------------------- vector<int> nbangles(nbscales); if(allcurvelets==1) { //nbangles nbangles[0] = 1; for(int sc=1; sc<nbscales; sc++) nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) ); //c c.resize(nbscales); for(int sc=0; sc<nbscales; sc++) c[sc].resize( nbangles[sc] ); double XL1 = 4.0*N1/3.0; double XL2 = 4.0*N2/3.0; //range for(int sc=nbscales-1; sc>0; sc--) { fdct_wrapping_sepangle(XL1, XL2, nbangles[sc], Xhghs[sc], c[sc]); XL1 /= 2; XL2 /= 2; } fdct_wrapping_wavelet(Xhghs[0], c[0]); } else { //nbangles nbangles[0] = 1; for(int sc=1; sc<nbscales-1; sc++) nbangles[sc] = nbangles_coarse * pow2( int(ceil(double(sc-1)/2)) ); nbangles[nbscales-1] = 1; //c c.resize(nbscales); for(int sc=0; sc<nbscales; sc++) c[sc].resize( nbangles[sc] ); fdct_wrapping_wavelet(Xhghs[nbscales-1], c[nbscales-1]); double XL1 = 2.0*N1/3.0; double XL2 = 2.0*N2/3.0; //range for(int sc=nbscales-2; sc>0; sc--) { fdct_wrapping_sepangle(XL1, XL2, nbangles[sc], Xhghs[sc], c[sc]); XL1 /= 2; XL2 /= 2; } fdct_wrapping_wavelet(Xhghs[0], c[0]); } return 0; }