/* Copyright (C) 2004 Caltech Written by Lexing Ying */ #include "fdct_usfft.hpp" #include "fdct_usfft_inline.hpp" using namespace std; FDCT_USFFT_NS_BEGIN_NAMESPACE //------------------------------------ extern int fdct_usfft_adjfftL(int N1, int N2, CpxOffMat& T, CpxNumMat& x); extern int fdct_usfft_adjsepscale(int N1, int N2, int nbscales, int ac, vector& Xhghs, CpxOffMat& O); extern int fdct_usfft_adjsepangle(double XL1, double XL2, int nbangles, vector& msc, CpxOffMat& Xhgh); extern int fdct_usfft_adjifftS(vector& csc, vector& msc); extern int fdct_usfft_adjwavelet(vector& csc, CpxOffMat& Xhgh); extern int fdct_usfft_sepangle(double XL1, double XL2, int nbangles, CpxOffMat& Xhgh, vector& msc); int fdct_usfft_invsepangle(double XL1, double XL2, int nbangles, vector& msc, CpxOffMat& Xhgh); int fdct_usfft_makeToeplitz(double XL1, double XL2, int nbangles, vector< vector >& Lambda, map& f1map, map& b1map); int fdct_usfft_multToeplitz(double XL1, double XL2, int nbangles, vector< vector >& Lambda, CpxOffMat& d, CpxOffMat& p, map& f1map, map& b1map); //------------------------------------ int ifdct_usfft(int N1, int N2, int nbscales, int nbangles_coarse, int ac, vector< vector >& c, CpxNumMat& x) { assert(nbscales==c.size() && nbangles_coarse==c[1].size()); //1. vector Xhghs; Xhghs.resize(nbscales); if(ac==1) { vector nbangles(nbscales); nbangles[0] = 1; for(int sc=1; sc0; sc--) { vector msc(nbangles[sc]); fdct_usfft_adjifftS(c[sc], msc); fdct_usfft_invsepangle(XL1, XL2, nbangles[sc], msc, Xhghs[sc]); XL1 = XL1/2; XL2 = XL2/2; } fdct_usfft_adjwavelet(c[0], Xhghs[0]); } else { vector nbangles(nbscales); nbangles[0] = 1; for(int sc=1; sc0; sc--) { vector msc(nbangles[sc]); fdct_usfft_adjifftS(c[sc], msc); fdct_usfft_invsepangle(XL1, XL2, nbangles[sc], msc, Xhghs[sc]); XL1 = XL1/2; XL2 = XL2/2; } fdct_usfft_adjwavelet(c[0], Xhghs[0]); } //2. CpxOffMat O; fdct_usfft_adjsepscale(N1, N2, nbscales, ac, Xhghs, O); //3. fdct_usfft_adjfftL(N1, N2, O, x); return 0; } //-------------------------------------------- int fdct_usfft_invsepangle(double XL1, double XL2, int nbangles, vector& msc, CpxOffMat& x) { int XS1, XS2; int XF1, XF2; double XR1, XR2; fdct_usfft_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2); map f1map; //forward 1d map, IN_PLACE map b1map; //backward 1d map, IN_PLACE //Toeplitz preparation vector< vector > Lambda; fdct_usfft_makeToeplitz(XL1, XL2, nbangles, Lambda, f1map, b1map); //0. allocate space for x and set x = 0; x.resize(XS1, XS2); clear(x); //1. call adjoint first, put into b CpxOffMat b(XS1, XS2); fdct_usfft_adjsepangle(XL1, XL2, nbangles, msc, b); //2. solve for MX = B, where M = (A^t A) CpxOffMat r(b); CpxOffMat d(r); CpxOffMat q(XS1, XS2); //empty cpx* rdata = r.data(); //cpx* xdata = x.data(); cpx* ddata = d.data(); cpx* qdata = q.data(); int m = x.m(); int n = x.n(); double v0=0; for(int i=0; i1e-8 && it<25) { //q = Ad fdct_usfft_multToeplitz(XL1, XL2, nbangles, Lambda, d, q, f1map, b1map); cpx* rdata = r.data(); cpx* xdata = x.data(); cpx* ddata = d.data(); cpx* qdata = q.data(); //tmp = d' q = d' A d cpx tz(0,0); for(int i=0; i >& Lambda, map& f1map, map& b1map) { int XS1, XS2; int XF1, XF2; double XR1, XR2; fdct_usfft_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2); Lambda.resize(4); //4 quadrant int nd = nbangles / 4; int nbquadrants = 4; int wcnt = 0; double XL1b = XL1; double XL2b = XL2; int qvec[] = {2,1,0,3}; for(int qi=0; qi& curLambda = Lambda[q]; curLambda.resize( xn ); //xn columns for(int xcur=xf; xcur::iterator fit = f1map.find(N); if(fit!=f1map.end()) { fp = (*fit).second; } else { fp = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); f1map[N] = fp; } CpxNumVec sum(N); CpxOffVec vvv(N); CpxNumVec feq(N); CpxNumVec tmp(N); for(int w=0; wF)? k-N : k; vvv(rk) = wgt(k,w); } fdct_usfft_ifftshift(vvv, tmp); fftw_one(fp, (fftw_complex*)tmp.data(), NULL); double scale = sqrt(double(N)); for(int k=0; k::iterator bit = b1map.find(2*N-1); if(bit!=b1map.end()) { bp = (*bit).second; } else { bp = fftw_create_plan(2*N-1, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); b1map[2*N-1] = bp; } fftw_one(bp, (fftw_complex*)tt.data(), NULL); scale = sqrt(double(2*N-1)); for(int k=0; k<2*N-1; k++) tt(k) /= scale; //scaling } //each line wcnt += nd; } //quadrant assert(wcnt==nbangles); return 0; } int fdct_usfft_multToeplitz(double XL1, double XL2, int nbangles, vector< vector >& Lambda, CpxOffMat& d, CpxOffMat& z, map& f1map, map& b1map) { int XS1, XS2; int XF1, XF2; double XR1, XR2; fdct_usfft_rangecompute(XL1, XL2, XS1, XS2, XF1, XF2, XR1, XR2); int nd = nbangles / 4; int nbquadrants = 4; int wcnt = 0; //clear space clear(z); CpxOffMat db(d); CpxOffMat zb(z); double XL1b = XL1; double XL2b = XL2; int qvec[] = {2,1,0,3}; for(int qi=0; qi& curLambda = Lambda[q]; //for each line for(int xcur=xf; xcur::iterator fit; fftw_plan sfp = NULL; fit=f1map.find(N); if(fit!=f1map.end()) { sfp = (*fit).second; } else { sfp = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); f1map[N] = sfp; } fftw_plan lfp = NULL; fit=f1map.find(2*N-1); if(fit!=f1map.end()) { lfp = (*fit).second; } else { lfp = fftw_create_plan(2*N-1, FFTW_FORWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); f1map[2*N-1] = lfp; } map::iterator bit; fftw_plan sbp = NULL; bit=b1map.find(N); if(bit!=b1map.end()) { sbp = (*bit).second; } else { sbp = fftw_create_plan(N, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); b1map[N] = sbp; } fftw_plan lbp = NULL; bit=b1map.find(2*N-1); if(bit!=b1map.end()) { lbp = (*bit).second; } else { lbp = fftw_create_plan(2*N-1, FFTW_BACKWARD, FFTW_ESTIMATE | FFTW_IN_PLACE); b1map[2*N-1] = lbp; } CpxOffVec val(XS2); CpxNumVec tmp(N); CpxOffVec feq(N); CpxNumVec feqext(2*N-1); CpxNumVec newext(2*N-1); //1. get value and padding 0 for(int i=-XF2; i<-XF2+XS2; i++) { val(i) = d(xcur,i); } //2. fft to get feq fdct_usfft_ifftshift(val, tmp); //shift fftw_one(sfp, (fftw_complex*)tmp.data(), NULL); double scale = sqrt(double(N)); for(int k=0; k