Ejemplo n.º 1
0
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]);
}
Ejemplo n.º 2
0
  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);
  }
Ejemplo n.º 3
0
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 );
  }
Ejemplo n.º 4
0
  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);
  }
Ejemplo n.º 5
0
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);	

}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
Archivo: psp.c Proyecto: 1014511134/src
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;
}
Ejemplo n.º 8
0
Archivo: psp.c Proyecto: 1014511134/src
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;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
Archivo: Mlrmig0.c Proyecto: huahbo/src
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);
}
Ejemplo n.º 11
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;
  }
}
Ejemplo n.º 12
0
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);
}