static inline void ifft8 (complex_t * buf) { sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; ifft4 (buf); ifft2 (buf + 4); ifft2 (buf + 6); BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]); BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots16[1]); }
static typename std::enable_if< std::is_same<Border, FullConvolution>::value, void>::type Convolution(const arma::Mat<eT>& input, const arma::Mat<eT>& filter, arma::Mat<eT>& output) { // In case of the full convolution outputRows and outputCols doesn't // represent the true output size when the padLastDim parameter is set, // instead it's the working size. const size_t outputRows = input.n_rows + 2 * (filter.n_rows - 1); size_t outputCols = input.n_cols + 2 * (filter.n_cols - 1); if (padLastDim) outputCols++; // Pad filter and input to the working output shape. arma::Mat<eT> inputPadded = arma::zeros<arma::Mat<eT> >(outputRows, outputCols); inputPadded.submat(filter.n_rows - 1, filter.n_cols - 1, filter.n_rows - 1 + input.n_rows - 1, filter.n_cols - 1 + input.n_cols - 1) = input; arma::Mat<eT> filterPadded = filter; filterPadded.resize(outputRows, outputCols); // Perform FFT and IFFT output = arma::real(ifft2(arma::fft2(inputPadded) % arma::fft2( filterPadded))); // Extract the region of interest. We don't need to handle the padLastDim // parameter in a special way we just cut it out from the output matrix. output = output.submat(filter.n_rows - 1, filter.n_cols - 1, 2 * (filter.n_rows - 1) + input.n_rows - 1, 2 * (filter.n_cols - 1) + input.n_cols - 1); }
inline typename enable_if2 < (is_arma_type<T1>::value && is_complex_strict<typename T1::elem_type>::value), Mat< std::complex<typename T1::pod_type> > >::result ifft2(const T1& A, const uword n_rows, const uword n_cols) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const unwrap<T1> tmp(A); const Mat<eT>& B = tmp.M; const bool do_resize = (B.n_rows != n_rows) || (B.n_cols != n_cols); return ifft2( do_resize ? resize(B,n_rows,n_cols) : B ); }
static typename std::enable_if< std::is_same<Border, ValidConvolution>::value, void>::type Convolution(const arma::Mat<eT>& input, const arma::Mat<eT>& filter, arma::Mat<eT>& output) { arma::Mat<eT> inputPadded = input; arma::Mat<eT> filterPadded = filter; if (padLastDim) inputPadded.resize(inputPadded.n_rows, inputPadded.n_cols + 1); // Pad filter and input to the output shape. filterPadded.resize(inputPadded.n_rows, inputPadded.n_cols); output = arma::real(ifft2(arma::fft2(inputPadded) % arma::fft2( filterPadded))); // Extract the region of interest. We don't need to handle the padLastDim in // a special way we just cut it out from the output matrix. output = output.submat(filter.n_rows - 1, filter.n_cols - 1, input.n_rows - 1, input.n_cols - 1); }
int main(int argc, char* argv[]) { clock_t tstart, tend; double duration; /*Flag*/ bool verb, cmplx; /*I/O*/ sf_file Fsrc,Fo,Frec; /* I/O files */ sf_file left, right; /*left/right matrix*/ sf_file Fvel, Fden, Ffft; /*Model*/ sf_axis at,az,ax; /* cube axes */ /* I/O arrays*/ float *src; /*point source, distributed source*/ float **lt, **rt; float **vel, **den, **c11; /* Grid index variables */ int it,iz,im,ik,ix,i,j; int nt,nz,nx, m2, nk, nkx, nkz, nzx, nz2, nx2, nzx2, n1, n2, pad1; float cx, cz; float kx, kz, dkx, dkz, kx0, kz0; float dx, dz, dt, d1, d2; float ox, oz; sf_complex *cwavex, *cwavez, *cwavemx, *cwavemz; float **record; float **wavex, **wavez; float *curtxx, *pretxx; float *curvx, *prevx, *curvz, *prevz; /*source*/ spara sp={0}; int srcrange; float srctrunc; bool srcdecay; float slx, slz; int spx, spz; /*options*/ float gdep; int gp; tstart = clock(); sf_init(argc,argv); if(!sf_getbool("verb",&verb)) verb=false; /* verbosity */ Fvel = sf_input("vel"); Fden = sf_input("den"); /* setup I/O files */ Fsrc = sf_input ("in" ); Fo = sf_output("out"); Frec = sf_output("rec"); /*record*/ /* Read/Write axes */ at = sf_iaxa(Fsrc,1); nt = sf_n(at); dt = sf_d(at); ax = sf_iaxa(Fvel,2); nx = sf_n(ax); dx = sf_d(ax); ox=sf_o(ax); az = sf_iaxa(Fvel,1); nz = sf_n(az); dz = sf_d(az); oz=sf_o(az); sf_oaxa(Fo,az,1); sf_oaxa(Fo,ax,2); sf_oaxa(Fo,at,3); /*set for record*/ sf_oaxa(Frec, at, 1); sf_oaxa(Frec, ax, 2); if (!sf_getbool("cmplx",&cmplx)) cmplx=false; /* use complex FFT */ if (!sf_getint("pad1",&pad1)) pad1=1; /* padding factor on the first axis */ nk = fft2_init(cmplx,pad1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; /* propagator matrices */ left = sf_input("left"); right = sf_input("right"); if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx); if (!sf_histint(left,"n2",&m2)) sf_error("Need n2= in left"); if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2); if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk); lt = sf_floatalloc2(nzx,m2); rt = sf_floatalloc2(m2,nk); sf_floatread(lt[0],nzx*m2,left); sf_floatread(rt[0],m2*nk,right); /*model veloctiy & density*/ if (!sf_histint(Fvel,"n1", &n1) || n1 != nz) sf_error("Need n1=%d in vel", nz); if (!sf_histfloat(Fvel,"d1", &d1) || d1 != dz) sf_error("Need d1=%d in vel", dz); if (!sf_histint(Fvel,"n2", &n2) || n2 != nx) sf_error("Need n2=%d in vel", nx); if (!sf_histfloat(Fvel,"d2", &d2) || d2 != dx) sf_error("Need d2=%d in vel", dx); if (!sf_histint(Fden,"n1", &n1) || n1 != nz) sf_error("Need n1=%d in den", nz); if (!sf_histfloat(Fden,"d1", &d1) || d1 != dz) sf_error("Need d1=%d in den", dz); if (!sf_histint(Fden,"n2", &n2) || n2 != nx) sf_error("Need n2=%d in den", nx); if (!sf_histfloat(Fden,"d2", &d2) || d2 != dx) sf_error("Need d2=%d in den", dx); vel = sf_floatalloc2(nz, nx); den = sf_floatalloc2(nz, nx); c11 = sf_floatalloc2(nz, nx); sf_floatread(vel[0], nzx, Fvel); sf_floatread(den[0], nzx, Fden); for (ix = 0; ix < nx; ix++) { for (iz = 0; iz < nz; iz++) { c11[ix][iz] = den[ix][iz]*vel[ix][iz]*vel[ix][iz]; } } /*parameters of fft*/ Ffft = sf_input("fft"); if (!sf_histint(Ffft,"n1", &nkz)) sf_error("Need n1 in fft"); if (!sf_histint(Ffft,"n2", &nkx)) sf_error("Need n2 in fft"); if ( nkx*nkz != nk ) sf_error("Need nk=nkx*nkz, nk=%d, nkx=%d, nkz=%d", nk, nkx, nkz); if (!sf_histfloat(Ffft,"d1", &dkz)) sf_error("Need d1 in fft"); if (!sf_histfloat(Ffft,"d2", &dkx)) sf_error("Need d2 in fft"); if (!sf_histfloat(Ffft,"o1", &kz0)) sf_error("Need o1 in fft"); if (!sf_histfloat(Ffft,"o2", &kx0)) sf_error("Need o2 in fft"); /*parameters of geometry*/ if (!sf_getfloat("gdep", &gdep)) gdep = 0.0; /*depth of geophone (meter)*/ if (gdep <0.0) sf_error("gdep need to be >=0.0"); /*source and receiver location*/ if (!sf_getfloat("slx", &slx)) slx=-1.0; /*source location x */ if (!sf_getint("spx", &spx)) spx = -1; /*source location x (index)*/ if((slx<0 && spx <0) || (slx>=0 && spx >=0 )) sf_error("Need src location"); if (slx >= 0 ) spx = (int)((slx-ox)/dx+0.5); if (!sf_getfloat("slz", &slz)) slz = -1.0; /* source location z */ if (!sf_getint("spz", &spz)) spz=-1; /*source location z (index)*/ if((slz<0 && spz <0) || (slz>=0 && spz >=0 )) sf_error("Need src location"); if (slz >= 0 ) spz = (int)((slz-ox)/dz+0.5); if (!sf_getfloat("gdep", &gdep)) gdep = -1.0; /* recorder depth on grid*/ if (!sf_getint("gp", &gp)) gp=0; /* recorder depth on index*/ if ( gdep>=oz) { gp = (int)((gdep-oz)/dz+0.5);} if (gp < 0.0) sf_error("gdep need to be >=oz"); /*source and receiver location*/ if (!sf_getbool("srcdecay", &srcdecay)) srcdecay=false; /*source decay*/ if (!sf_getint("srcrange", &srcrange)) srcrange=10; /*source decay range*/ if (!sf_getfloat("srctrunc", &srctrunc)) srctrunc=100; /*trunc source after srctrunc time (s)*/ /* read wavelet & reflectivity */ src = sf_floatalloc(nt); sf_floatread(src,nt,Fsrc); curtxx = sf_floatalloc(nzx2); curvx = sf_floatalloc(nzx2); curvz = sf_floatalloc(nzx2); pretxx = sf_floatalloc(nzx); prevx = sf_floatalloc(nzx); prevz = sf_floatalloc(nzx); cwavex = sf_complexalloc(nk); cwavez = sf_complexalloc(nk); cwavemx = sf_complexalloc(nk); cwavemz = sf_complexalloc(nk); wavex = sf_floatalloc2(nzx2,m2); wavez = sf_floatalloc2(nzx2,m2); record = sf_floatalloc2(nt,nx); ifft2_allocate(cwavemx); ifft2_allocate(cwavemz); for (iz=0; iz < nzx; iz++) { pretxx[iz]=0.; prevx[iz] =0.; prevz[iz] =0.; } for (iz=0; iz < nzx2; iz++) { curtxx[iz]=0.; curvx[iz]=0.; curvz[iz]=0.; } /* Check parameters*/ if(verb) { sf_warning("======================================"); #ifdef SF_HAS_FFTW sf_warning("FFTW is defined"); #endif #ifdef SF_HAS_COMPLEX_H sf_warning("Complex is defined"); #endif sf_warning("nx=%d nz=%d nzx=%d dx=%f dz=%f", nx, nz, nzx, dx, dz); sf_warning("nkx=%d nkz=%d dkx=%f dkz=%f nk=%d", nkx, nkz, dkx, dkz, nk); sf_warning("nx2=%d nz2=%d nzx2=%d", nx2, nz2, nzx2); sf_warning("======================================"); } /*set source*/ sp.trunc=srctrunc; sp.srange=srcrange; sp.alpha=0.5; sp.decay=srcdecay?1:0; /* MAIN LOOP */ for (it=0; it<nt; it++) { if(verb) sf_warning("it=%d/%d;",it,nt-1); /*vx, vz--- matrix multiplication */ fft2(curtxx,cwavex); /* P^(k,t) */ for (im = 0; im < m2; im++) { for (ik = 0; ik < nk; ik++) { kx = kx0+dkx*(ik/nkz); kz = kz0+dkz*(ik%nkz); #ifdef SF_HAS_COMPLEX_H cwavemz[ik] = cwavex[ik]*rt[ik][im]; cwavemx[ik] = fplus(kx,dx)*cwavemz[ik]; cwavemz[ik] = fplus(kz,dz)*cwavemz[ik]; #else cwavemz[ik] = sf_crmul(cwavex[ik],rt[ik][im]); cwavemx[ik] = sf_cmul(fplus(kx,dx), cwavemz[ik]); cwavemz[ik] = sf_cmul(fplus(kz,dz), cwavemz[ik]); #endif } ifft2(wavex[im], cwavemx); /* dp/dx */ ifft2(wavez[im], cwavemz); /* dp/dz */ } for (ix = 0; ix < nx; ix++) { for (iz = 0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ cx = 0.0; cz = 0.0; for (im=0; im<m2; im++) { cx += lt[im][i]*wavex[im][j]; cz += lt[im][i]*wavez[im][j]; } curvx[j] = -1*dt/den[ix][iz]*cx + prevx[i]; /*vx(t+dt/2) = -dt/rho*dp/dx(t) + vx(t-dt/2) */ prevx[i] = curvx[j]; curvz[j] = -1*dt/den[ix][iz]*cz + prevz[i]; prevz[i] = curvz[j]; } } /*txx--- matrix multiplication */ fft2(curvx, cwavex); fft2(curvz, cwavez); for (im = 0; im < m2; im++) { for (ik = 0; ik < nk; ik++ ) { kx = kx0 + dkx*(ik/nkz); kz = kz0 + dkz*(ik%nkz); #ifdef SF_HAS_COMPLEX_H cwavemz[ik] = cwavez[ik]*rt[ik][im]; cwavemx[ik] = cwavex[ik]*rt[ik][im]; cwavemx[ik] = fminu(kx,dx)*cwavemx[ik]; cwavemz[ik] = fminu(kz,dz)*cwavemz[ik]; #else cwavemz[ik] = sf_crmul(cwavez[ik],rt[ik][im]); cwavemx[ik] = sf_crmul(cwavex[ik],rt[ik][im]); cwavemx[ik] = sf_cmul(fplus(kx,dx), cwavemx[ik]); cwavemz[ik] = sf_cmul(fplus(kz,dz), cwavemz[ik]); #endif } ifft2(wavex[im], cwavemx); /* dux/dx */ ifft2(wavez[im], cwavemz); /* duz/dz */ } for (ix = 0; ix < nx; ix++) { for (iz = 0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ cx = 0.0; cz = 0.0; for (im=0; im<m2; im++) { cx += lt[im][i]*wavex[im][j]; cz += lt[im][i]*wavez[im][j]; } curtxx[j] = -1*dt*c11[ix][iz]*(cx+cz) + pretxx[i]; } } if ((it*dt)<=sp.trunc ) { curtxx[spz+spx*nz2] += src[it]*dt; } for (ix = 0; ix < nx; ix++) { /* write wavefield to output */ sf_floatwrite(pretxx+ix*nz,nz,Fo); } /*record*/ for (ix = 0; ix < nx; ix++){ record[ix][it] = pretxx[ix*nz+gp]; } for (ix = 0; ix < nx; ix++) { for (iz = 0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ pretxx[i] = curtxx[j]; } } }/*End of MAIN LOOP*/ if(verb) sf_warning("."); for ( ix = 0; ix < nx; ix++) { sf_floatwrite(record[ix], nt, Frec); } tend = clock(); duration=(double)(tend-tstart)/CLOCKS_PER_SEC; sf_warning(">> The CPU time of sfsglr is: %f seconds << ", duration); exit (0); }
void ifftu2(unsigned int D, const long dimensions[D], unsigned long flags, const long ostrides[D], complex float* dst, const long istrides[D], const complex float* src) { ifft2(D, dimensions, flags, ostrides, dst, istrides, src); fftscale2(D, dimensions, flags, ostrides, dst, ostrides, dst); }
int psp4(float **wvfld, float **wvfld0, float **dat, float **dat_v, float *vel, pspar par) /*< pseudo-spectral wave extrapolation using wavefield injection >*/ { /*survey parameters*/ int nx, nz; float dx, dz; int n_srcs; int *spx, *spz; int gpz, gpx, gpl; int gpz_v, gpx_v, gpl_v; int snap; /*fft related*/ bool cmplx; int pad1; /*absorbing boundary*/ bool abc; int nbt, nbb, nbl, nbr; float ct,cb,cl,cr; /*source parameters*/ int src; /*source type*/ int nt; float dt,*f0,*t0,*A; /*misc*/ bool verb, ps; float vref; int nx1, nz1; /*domain of interest*/ int it,iz,ik,ix,i,j; /* index variables */ int nk,nzx,nz2,nx2,nzx2,nkz,nth; int it1, it2, its; float dkx,dkz,kx0,kz0,vref2,kx,kz,k,t; float c, old; /*wave prop arrays*/ float *vv; sf_complex *cwave,*cwavem; float *wave,*curr,*prev,*lapl; /*source*/ float **rick; float freq; int fft_size; /*passing the parameters*/ nx = par->nx; nz = par->nz; dx = par->dx; dz = par->dz; n_srcs= par->n_srcs; spx = par->spx; spz = par->spz; gpz = par->gpz; gpx = par->gpx; gpl = par->gpl; gpz_v = par->gpz_v; gpx_v = par->gpx_v; gpl_v = par->gpl_v; snap = par->snap; cmplx = par->cmplx; pad1 = par->pad1; abc = par->abc; nbt = par->nbt; nbb = par->nbb; nbl = par->nbl; nbr = par->nbr; ct = par->ct; cb = par->cb; cl = par->cl; cr = par->cr; src = par->src; nt = par->nt; dt = par->dt; f0 = par->f0; t0 = par->t0; A = par->A; verb = par->verb; ps = par->ps; vref = par->vref; #ifdef _OPENMP #pragma omp parallel { nth = omp_get_num_threads(); } #else nth = 1; #endif if (verb) sf_warning(">>>> Using %d threads <<<<<", nth); nz1 = nz-nbt-nbb; nx1 = nx-nbl-nbr; nk = fft2_init(cmplx,pad1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; dkz = 1./(nz2*dz); kz0 = (cmplx)? -0.5/dz:0.; dkx = 1./(nx2*dx); kx0 = -0.5/dx; nkz = (cmplx)? nz2:(nz2/2+1); if(nk!=nx2*nkz) sf_error("wavenumber dimension mismatch!"); sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0); sf_warning("nk=%d,nkz=%d,nz2=%d,nx2=%d",nk,nkz,nz2,nx2); if(abc) abc_init(nz,nx,nz2,nx2,nbt,nbb,nbl,nbr,ct,cb,cl,cr); /* allocate and read/initialize arrays */ vv = sf_floatalloc(nzx); lapl = sf_floatalloc(nk); wave = sf_floatalloc(nzx2); curr = sf_floatalloc(nzx2); prev = sf_floatalloc(nzx2); cwave = sf_complexalloc(nk); cwavem = sf_complexalloc(nk); if (src==0) { rick = sf_floatalloc2(nt,n_srcs); for (i=0; i<n_srcs; i++) { for (it=0; it<nt; it++) { rick[i][it] = 0.f; } rick[i][(int)(t0[i]/dt)] = A[i]; /*time delay*/ freq = f0[i]*dt; /*peak frequency*/ fft_size = 2*kiss_fft_next_fast_size((nt+1)/2); ricker_init(fft_size, freq, 0); sf_freqfilt(nt,rick[i]); ricker_close(); } } else rick = NULL; for (iz=0; iz < nzx; iz++) { vv[iz] = vel[iz]*vel[iz]*dt*dt; } vref *= dt; vref2 = vref*vref; for (iz=0; iz < nzx2; iz++) { curr[iz] = 0.; prev[iz] = 0.; } /* constructing the pseudo-analytical op */ for (ix=0; ix < nx2; ix++) { kx = kx0+ix*dkx; for (iz=0; iz < nkz; iz++) { kz = kz0+iz*dkz; k = 2*SF_PI*hypot(kx,kz); if (ps) lapl[iz+ix*nkz] = -k*k; else lapl[iz+ix*nkz] = 2.*(cos(vref*k)-1.)/vref2; } } /* modeling */ /* step forward in time */ it1 = 0; it2 = nt; its = +1; /* MAIN LOOP */ for (it=it1; it!=it2; it+=its) { if(verb) sf_warning("it=%d/%d;",it,nt); /* matrix multiplication */ fft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*lapl[ik]; #else cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]); #endif } ifft2(wave,cwavem); #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j,old,c) #endif for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ old = c = curr[j]; c += c - prev[j]; prev[j] = old; c += wave[j]*vv[i]; curr[j] = c; } } if (NULL!=wvfld0) { /* wavefield injection */ if (snap > 0 && it%snap==0) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j,ik) #endif for (ix=0; ix<nx1; ix++) { for (iz=0; iz<nz1; iz++) { i = iz + nz1*ix; j = iz+nbt + (ix+nbl)*nz2; /* padded grid */ ik = iz+nbt + (ix+nbl)*nz; /* padded grid */ curr[j] += vv[ik]*wvfld0[it/snap][i]; } } } } else { /* source injection */ t = it*dt; for (i=0; i<n_srcs; i++) { for(ix=-1;ix<=1;ix++) { for(iz=-1;iz<=1;iz++) { ik = spz[i]+iz+nz*(spx[i]+ix); j = spz[i]+iz+nz2*(spx[i]+ix); if (src==0) { curr[j] += vv[ik]*rick[i][it]/(abs(ix)+abs(iz)+1); } else { curr[j] += vv[ik]*Ricker(t, f0[i], t0[i], A[i])/(abs(ix)+abs(iz)+1); } } } } } /*apply abc*/ if (abc) { abc_apply(curr); abc_apply(prev); } /* record data */ if (NULL!=dat) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix) #endif for (ix = 0; ix < gpl; ix++) { dat[ix][it] = curr[gpz+(ix+gpx)*nz2]; } } if (NULL!=dat_v) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(iz) #endif for (iz = 0; iz < gpl_v; iz++) { dat_v[iz][it] = curr[gpz_v+iz+(gpx_v)*nz2]; } } /* save wavefield */ if (snap > 0 && it%snap==0) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j) #endif for (ix=0; ix<nx1; ix++) { for (iz=0; iz<nz1; iz++) { i = iz + nz1*ix; j = iz+nbt + (ix+nbl)*nz2; /* padded grid */ wvfld[it/snap][i] = curr[j]; } } } } if(verb) sf_warning("."); /*free up memory*/ fft2_finalize(); if (abc) abc_close(); free(vv); free(lapl); free(wave); free(curr); free(prev); free(cwave); free(cwavem); return 0; }
int psp3(float **wvfld, float **wvfld1, float **dat, float **dat1, float *img, float *vel, pspar par) /*< pseudo-spectral back propagation of two receiver wavefields >*/ { /*survey parameters*/ int nx, nz; float dx, dz; int n_srcs; int *spx, *spz; int gpz, gpx, gpl; int gpz_v, gpx_v, gpl_v; int snap; /*fft related*/ bool cmplx; int pad1; /*absorbing boundary*/ bool abc; int nbt, nbb, nbl, nbr; float ct,cb,cl,cr; /*source parameters*/ int src; /*source type*/ int nt; float dt,*f0,*t0,*A; /*misc*/ bool verb, ps; float vref; int nx1, nz1; /*domain of interest*/ int it,iz,ik,ix,i,j; /* index variables */ int nk,nzx,nz2,nx2,nzx2,nkz,nth; int it1, it2, its; float dkx,dkz,kx0,kz0,vref2,kx,kz,k; float c, old; /*wave prop arrays*/ float *vv; sf_complex *cwave,*cwavem; float *wave,*curr,*curr1,*prev,*prev1,*lapl; /*passing the parameters*/ nx = par->nx; nz = par->nz; dx = par->dx; dz = par->dz; n_srcs= par->n_srcs; spx = par->spx; spz = par->spz; gpz = par->gpz; gpx = par->gpx; gpl = par->gpl; gpz_v = par->gpz_v; gpx_v = par->gpx_v; gpl_v = par->gpl_v; snap = par->snap; cmplx = par->cmplx; pad1 = par->pad1; abc = par->abc; nbt = par->nbt; nbb = par->nbb; nbl = par->nbl; nbr = par->nbr; ct = par->ct; cb = par->cb; cl = par->cl; cr = par->cr; src = par->src; nt = par->nt; dt = par->dt; f0 = par->f0; t0 = par->t0; A = par->A; verb = par->verb; ps = par->ps; vref = par->vref; #ifdef _OPENMP #pragma omp parallel { nth = omp_get_num_threads(); } #else nth = 1; #endif if (verb) sf_warning(">>>> Using %d threads <<<<<", nth); nz1 = nz-nbt-nbb; nx1 = nx-nbl-nbr; nk = fft2_init(cmplx,pad1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; dkz = 1./(nz2*dz); kz0 = (cmplx)? -0.5/dz:0.; dkx = 1./(nx2*dx); kx0 = -0.5/dx; nkz = (cmplx)? nz2:(nz2/2+1); if(nk!=nx2*nkz) sf_error("wavenumber dimension mismatch!"); sf_warning("dkz=%f,dkx=%f,kz0=%f,kx0=%f",dkz,dkx,kz0,kx0); sf_warning("nk=%d,nkz=%d,nz2=%d,nx2=%d",nk,nkz,nz2,nx2); if(abc) abc_init(nz,nx,nz2,nx2,nbt,nbb,nbl,nbr,ct,cb,cl,cr); /* allocate and read/initialize arrays */ vv = sf_floatalloc(nzx); lapl = sf_floatalloc(nk); wave = sf_floatalloc(nzx2); curr = sf_floatalloc(nzx2); curr1 = sf_floatalloc(nzx2); prev = sf_floatalloc(nzx2); prev1 = sf_floatalloc(nzx2); cwave = sf_complexalloc(nk); cwavem = sf_complexalloc(nk); for (iz=0; iz < nzx; iz++) { vv[iz] = vel[iz]*vel[iz]*dt*dt; } vref *= dt; vref2 = vref*vref; for (iz=0; iz < nzx2; iz++) { curr[iz] = 0.; curr1[iz] = 0.; prev[iz] = 0.; prev1[iz] = 0.; } for (iz=0; iz < nz1*nx1; iz++) { img[iz] = 0.; } /* constructing the pseudo-analytical op */ for (ix=0; ix < nx2; ix++) { kx = kx0+ix*dkx; for (iz=0; iz < nkz; iz++) { kz = kz0+iz*dkz; k = 2*SF_PI*hypot(kx,kz); if (ps) lapl[iz+ix*nkz] = -k*k; else lapl[iz+ix*nkz] = 2.*(cos(vref*k)-1.)/vref2; } } /* step backward in time */ it1 = nt-1; it2 = -1; its = -1; /* MAIN LOOP */ for (it=it1; it!=it2; it+=its) { if(verb) sf_warning("it=%d/%d;",it,nt); /* first receiver wavefield */ /* matrix multiplication */ fft2(curr,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*lapl[ik]; #else cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]); #endif } ifft2(wave,cwavem); #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j,old,c) #endif for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ old = c = curr[j]; c += c - prev[j]; prev[j] = old; c += wave[j]*vv[i]; curr[j] = c; } } /* inject data */ if (NULL!=dat) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix) #endif for (ix = 0; ix < gpl; ix++) { curr[gpz+(ix+gpx)*nz2] += vv[gpz+(ix+gpx)*nz]*dat[ix][it]; } } /*apply abc*/ if (abc) { abc_apply(curr); abc_apply(prev); } /* second receiver wavefield */ /* matrix multiplication */ fft2(curr1,cwave); for (ik = 0; ik < nk; ik++) { #ifdef SF_HAS_COMPLEX_H cwavem[ik] = cwave[ik]*lapl[ik]; #else cwavem[ik] = sf_cmul(cwave[ik],lapl[ik]); #endif } ifft2(wave,cwavem); #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j,old,c) #endif for (ix = 0; ix < nx; ix++) { for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ old = c = curr1[j]; c += c - prev1[j]; prev1[j] = old; c += wave[j]*vv[i]; curr1[j] = c; } } /* inject data */ if (NULL!=dat1) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix) #endif for (ix = 0; ix < gpl; ix++) { curr1[gpz+(ix+gpx)*nz2] += vv[gpz+(ix+gpx)*nz]*dat1[ix][it]; } } /*apply abc*/ if (abc) { abc_apply(curr1); abc_apply(prev1); } /* cross-correlation imaging condition */ if (snap > 0 && it%snap==0) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j) #endif for (ix = 0; ix < nx1; ix++) { for (iz = 0; iz < nz1; iz++) { i = iz + nz1*ix; j = iz+nbt + (ix+nbl)*nz2; /* padded grid */ img[i] += curr[j]*curr1[j]; //!!!IMPORTANT!!! } } } /* save wavefield */ if (snap > 0 && it%snap==0) { #ifdef _OPENMP #pragma omp parallel for default(shared) private(ix,iz,i,j) #endif for (ix=0; ix<nx1; ix++) { for (iz=0; iz<nz1; iz++) { i = iz + nz1*ix; j = iz+nbt + (ix+nbl)*nz2; /* padded grid */ wvfld[it/snap][i] = curr[j]; wvfld1[it/snap][i] = curr1[j]; } } } } if(verb) sf_warning("."); /*free up memory*/ fft2_finalize(); if (abc) abc_close(); free(vv); free(lapl); free(wave); free(curr); free(curr1); free(prev); free(prev1); free(cwave); free(cwavem); return 0; }
cv::Mat L0Smoothing(cv::Mat Im, double lambda = 0.02, double kappa = 2.0) { cv::Mat out(Im.rows, Im.cols, CV_32FC3); Matrix SR(Im.rows, Im.cols); Matrix SG(Im.rows, Im.cols); Matrix SB(Im.rows, Im.cols); for(int j = 0; j < Im.cols; ++j) { for(int i = 0; i < Im.rows; ++i) { cv::Vec3f& v1 = Im.at<cv::Vec3f>(i, j); SR(i, j) = v1[0]; SG(i, j) = v1[1]; SB(i, j) = v1[2]; } } double betamax = 1e5; Matrix fx(1, 2); fx(0, 0) = 1; fx(0, 1) = -1; Matrix fy(2, 1); fy(0, 0) = 1; fy(1, 0) = -1; Matrix sizeI2D(1, 2); sizeI2D(0, 0) = Im.rows; sizeI2D(0, 1) = Im.cols; Matrix2 otfFx = psf2otf(fx, sizeI2D); Matrix2 otfFy = psf2otf(fy, sizeI2D); Matrix otfFx2 = MatAbsPow2(otfFx); Matrix otfFy2 = MatAbsPow2(otfFy); Matrix2 Normin1R = fft2(SR); Matrix2 Normin1G = fft2(SG); Matrix2 Normin1B = fft2(SB); Matrix Denormin2 = otfFx2 + otfFy2; float beta = 2 * lambda; int count = 1; while(beta < betamax) { float lb = lambda / beta; Matrix Denormin = beta * Denormin2; MatAdd(Denormin, 1); Matrix hR = Matdiff(SR, 2); Matrix vR = Matdiff(SR, 1); Matrix hG = Matdiff(SG, 2); Matrix vG = Matdiff(SG, 1); Matrix hB = Matdiff(SB, 2); Matrix vB = Matdiff(SB, 1); Matrix Pos2Sum = MatPow2(hR) + MatPow2(vR) + MatPow2(hG) + MatPow2(vG) + MatPow2(hB) + MatPow2(vB); for(int j = 0; j < Im.cols; ++j) { for(int i = 0; i < Im.rows; ++i) { if(Pos2Sum(i, j) < lb) { hR(i, j) = 0; vR(i, j) = 0; hG(i, j) = 0; vG(i, j) = 0; hB(i, j) = 0; vB(i, j) = 0; } } } Matrix Normin2R = Matdiffinv(hR, 2) + Matdiffinv(vR, 1); Matrix Normin2G = Matdiffinv(hG, 2) + Matdiffinv(vG, 1); Matrix Normin2B = Matdiffinv(hB, 2) + Matdiffinv(vB, 1); Matrix2 FSR = (Normin1R + fft2(Normin2R) * beta) / Denormin; Matrix2 FSG = (Normin1G + fft2(Normin2G) * beta) / Denormin; Matrix2 FSB = (Normin1B + fft2(Normin2B) * beta) / Denormin; SR = ifft2(FSR); SG = ifft2(FSG); SB = ifft2(FSB); beta = beta * kappa; printf("."); for(uint i = 0; i < out.rows; ++i) { for(uint j = 0; j < out.cols; ++j) { cv::Vec3f& v1 = out.at<cv::Vec3f>(i, j); v1[0] = SR(i, j); v1[1] = SG(i, j); v1[2] = SB(i, j); } } cv::imshow("out", out); char filename[100]; sprintf(filename, "o%02d.png", count++); cv::Mat theout; out.convertTo(theout, CV_8UC3, 255); cv::imwrite(filename, theout); cv::waitKey(1); } for(uint j = 0; j < out.cols; ++j) { for(uint i = 0; i < out.rows; ++i) { cv::Vec3f& v1 = out.at<cv::Vec3f>(i, j); v1[0] = SR(i, j); v1[1] = SG(i, j); v1[2] = SB(i, j); } } return out; }
int main(int argc, char* argv[]) { int iz,im,ik,ix,i,j; /* index variables */ int nz,nx, m2, nk, nzx, nz2, nx2, nzx2, n2; float c; sf_complex *cwavem; float **wave, *curr; sf_complex **lt, **rt; sf_file left, right, inp, mig; sf_init(argc,argv); inp = sf_input("in"); mig = sf_output("out"); if (SF_FLOAT != sf_gettype(inp)) sf_error("Need float input"); if (!sf_histint(inp,"n1",&nz)) sf_error("No n1= in input"); if (!sf_histint(inp,"n2",&nx)) sf_error("No n2= in input"); nk = fft2_init(false,1,nz,nx,&nz2,&nx2); nzx = nz*nx; nzx2 = nz2*nx2; /* propagator matrices */ left = sf_input("left"); right = sf_input("right"); if (!sf_histint(left,"n1",&n2) || n2 != nzx) sf_error("Need n1=%d in left",nzx); if (!sf_histint(left,"n2",&m2)) sf_error("Need n2= in left"); if (!sf_histint(right,"n1",&n2) || n2 != m2) sf_error("Need n1=%d in right",m2); if (!sf_histint(right,"n2",&n2) || n2 != nk) sf_error("Need n2=%d in right",nk); lt = sf_complexalloc2(nzx,m2); rt = sf_complexalloc2(m2,nk); sf_complexread(lt[0],nzx*m2,left); sf_complexread(rt[0],m2*nk,right); wave = sf_floatalloc2(nzx2,m2); cwavem = sf_complexalloc(nk); curr = sf_floatalloc(nz); ifft2_allocate(cwavem); for (im = 0; im < m2; im++) { #ifdef _OPENMP #pragma omp parallel for private(ik) #endif for (ik = 0; ik < nk; ik++) { cwavem[ik] = rt[ik][im]; } ifft2(wave[im],cwavem); } for (ix = 0; ix < nx; ix++) { #ifdef _OPENMP #pragma omp parallel for private(iz,i,j,c,im) #endif for (iz=0; iz < nz; iz++) { i = iz+ix*nz; /* original grid */ j = iz+ix*nz2; /* padded grid */ for (im = 0; im < m2; im++) { c += crealf(lt[im][i])*wave[im][j]; } curr[iz] = c; } sf_floatwrite(curr,nz,mig); } exit (0); }
void main() { //* Initialize parameters (system size, grid spacing, etc.) double eps0 = 8.8542e-12; // Permittivity (C^2/(N m^2)) int N = 64; // Number of grid points on a side (square grid) double L = 1; // System size double h = L/N; // Grid spacing for periodic boundary conditions Matrix x(N), y(N); int i,j; for( i=1; i<=N; i++ ) x(i) = (i-0.5)*h; // Coordinates of grid points y = x; // Square grid cout << "System is a square of length " << L << endl; //* Set up charge density rho(i,j) Matrix rho(N,N); rho.set(0.0); // Initialize charge density to zero cout << "Enter number of line charges: "; int M; cin >> M; for( i=1; i<=M; i++ ) { cout << "For charge #" << i << endl; cout << "Enter x coordinate: "; double xc; cin >> xc; cout << "Enter y coordinate: "; double yc; cin >> yc; int ii = (int)(xc/h) + 1; // Place charge at nearest int jj = (int)(yc/h) + 1; // grid point cout << "Enter charge density: "; double q; cin >> q; rho(ii,jj) += q/(h*h); } //* Compute matrix P const double pi = 3.141592654; Matrix cx(N), cy(N); for( i=1; i<=N; i++ ) cx(i) = cos((2*pi/N)*(i-1)); cy = cx; Matrix RealP(N,N), ImagP(N,N); double numerator = -h*h/(2*eps0); double tinyNumber = 1e-20; // Avoids division by zero for( i=1; i<=N; i++ ) for( j=1; j<=N; j++ ) RealP(i,j) = numerator/(cx(i)+cy(j)-2+tinyNumber); ImagP.set(0.0); //* Compute potential using MFT method Matrix RealR(N,N), ImagR(N,N), RealF(N,N), ImagF(N,N); for( i=1; i<=N; i++ ) for( j=1; j<=N; j++ ) { RealR(i,j) = rho(i,j); ImagR(i,j) = 0.0; // Copy rho into R for input to fft2 } fft2(RealR,ImagR); // Transform rho into wavenumber domain // Compute phi in the wavenumber domain for( i=1; i<=N; i++ ) for( j=1; j<=N; j++ ) { RealF(i,j) = RealR(i,j)*RealP(i,j) - ImagR(i,j)*ImagP(i,j); ImagF(i,j) = RealR(i,j)*ImagP(i,j) + ImagR(i,j)*RealP(i,j); } Matrix phi(N,N); ifft2(RealF,ImagF); // Inv. transf. phi into the coord. domain for( i=1; i<=N; i++ ) for( j=1; j<=N; j++ ) phi(i,j) = RealF(i,j); //* Print out the plotting variables: x, y, phi ofstream xOut("x.txt"), yOut("y.txt"), phiOut("phi.txt"); for( i=1; i<=N; i++ ) { xOut << x(i) << endl; yOut << y(i) << endl; for( j=1; j<N; j++ ) phiOut << phi(i,j) << ", "; phiOut << phi(i,N) << endl; } }
void compute_imgcov(const long cov_dims[4], complex float* imgcov, const long nskerns_dims[5], const complex float* nskerns) { debug_printf(DP_DEBUG1, "Zeropad...\n"); long xh = cov_dims[0]; long yh = cov_dims[1]; long zh = cov_dims[2]; long kx = nskerns_dims[0]; long ky = nskerns_dims[1]; long kz = nskerns_dims[2]; long channels = nskerns_dims[3]; long nr_kernels = nskerns_dims[4]; long imgkern_dims[5] = { xh, yh, zh, channels, nr_kernels }; complex float* imgkern1 = md_alloc(5, imgkern_dims, CFL_SIZE); complex float* imgkern2 = md_alloc(5, imgkern_dims, CFL_SIZE); md_resize_center(5, imgkern_dims, imgkern1, nskerns_dims, nskerns, CFL_SIZE); // resort array debug_printf(DP_DEBUG1, "FFT (juggling)...\n"); long istr[5]; long mstr[5]; long idim[5] = { xh, yh, zh, channels, nr_kernels }; long mdim[5] = { nr_kernels, channels, xh, yh, zh }; md_calc_strides(5, istr, idim, CFL_SIZE); md_calc_strides(5, mstr, mdim, CFL_SIZE); long m2str[5] = { mstr[2], mstr[3], mstr[4], mstr[1], mstr[0] }; ifftmod(5, imgkern_dims, FFT_FLAGS, imgkern1, imgkern1); ifft2(5, imgkern_dims, FFT_FLAGS, m2str, imgkern2, istr, imgkern1); float scalesq = (kx * ky * kz) * (xh * yh * zh); // second part for FFT scaling md_free(imgkern1); debug_printf(DP_DEBUG1, "Calculate Gram matrix...\n"); int cosize = channels * (channels + 1) / 2; assert(cov_dims[3] == cosize); #pragma omp parallel for collapse(3) for (int k = 0; k < zh; k++) { for (int j = 0; j < yh; j++) { for (int i = 0; i < xh; i++) { complex float gram[cosize]; gram_matrix2(channels, gram, nr_kernels, (const complex float (*)[nr_kernels])(imgkern2 + ((k * yh + j) * xh + i) * (channels * nr_kernels))); #ifdef FLIP // add (scaled) identity matrix for (int i = 0, l = 0; i < channels; i++) for (int j = 0; j <= i; j++, l++) gram[l] = ((i == j) ? (kx * ky * kz) : 0.) - gram[l]; #endif for (int l = 0; l < cosize; l++) imgcov[(((l * zh) + k) * yh + j) * xh + i] = gram[l] / scalesq; } } } md_free(imgkern2); }