Ejemplo n.º 1
0
void levint2 (bool cdstep                /* if use conj. directions */,
	      int niter                  /* number of iterations */, 
	      int warmup                 /* initial iterations */,
	      int nd                     /* data size */,
	      float *x, float *y         /* data coordinates */, 
	      float *dd                  /* data */, 
	      float o1, float d1, int n1 /* inline */, 
	      float o2, float d2, int n2 /* crossline */, 
	      filter aa                  /* PEF */, 
	      float *rr                  /* residual */, 
	      float eps                  /* regularization parameter */) 
/*< 2-D inverse interpolation with PEF estimation >*/
{
    int nm, nr;

    nm = n1*n2;
    nr = nm+aa->nh;

    lint2_init (n1,o1,d1, n2,o2,d2, x, y);
    pefhel_init (aa, nm, rr);

    if (cdstep) {
	sf_cdstep_init();
	sf_solver_reg (lint2_lop, sf_cdstep, helicon_lop, nm, nm, nd, rr, dd, 
		       warmup, eps, "x0", rr, "nmem", warmup, "end");
	sf_cdstep_close();
	/*
	  sf_solver_reg (lint2_lop, sf_cdstep, pefhel_lop, nm, nr, nd, rr, dd, 
	  niter, eps, "x0", rr, "nlreg", helicon_lop, "nmem", 3, "end");
	  sf_cdstep_close();
	*/
    } else {
	sf_solver_reg (lint2_lop, sf_cgstep, helicon_lop, nm, nm, nd, rr, dd, 
		       warmup, eps, "x0", rr, "end");
	sf_cgstep_close();
	/*
	  sf_solver_reg (lint2_lop, sf_cgstep, pefhel_lop, nm, nr, nd, rr, dd, 
	  niter, eps, "x0", rr, "nlreg", helicon_lop,"end");
	  sf_cgstep_close();
	*/
    }
}
Ejemplo n.º 2
0
void signoi2_lop (bool adj, bool add, int n1, int n2, 
		 float *data, float *sign)
/*< alternative linear operator >*/
{
    helicon2_init (nd, nn);
    sf_helicon_init (ss); 

    sf_adjnull(adj,add,n1,n2,data,sign);

    helicon2_lop (false, false, n1, n1, data, dd);
    sf_solver_reg(helicon2_lop, sf_cgstep, sf_helicon_lop, 
		  nd, nd, nd, sign, dd, niter, eps, 
		  "verb", verb, "end");
    sf_cgstep_close();

    nn++;
    ss++;
}
Ejemplo n.º 3
0
int main(int argc, char* argv[])
{
    bool velocity, verb, shape;
    int dim, i, j, n[3], rect[3], it, nt, order, nt0, nx0;
    int iter, niter, iline, nline, cgiter, *f0, *m0=NULL;
    float d[3], o[3], dt0, dx0, ot0, ox0, eps, tol, *p=NULL, *p0=NULL, thres;
    float *vd, *vdt, *vdx, *s, *t0, *x0, *ds, *rhs, *rhs0, *rhs1=NULL, error0, error1, error, scale;
    char key[6];
    sf_file in, out, dix, t_0=NULL, x_0=NULL, f_0=NULL, grad=NULL, cost=NULL, mini=NULL, prec=NULL;

    sf_init(argc,argv);
    in = sf_input("in");
    out = sf_output("out");

    /* read input dimension */
    dim = sf_filedims(in,n);

    nt = 1;
    for (i=0; i < dim; i++) {
	sprintf(key,"d%d",i+1);
	if (!sf_histfloat(in,key,d+i)) sf_error("No %s= in input",key);
	sprintf(key,"o%d",i+1);
	if (!sf_histfloat(in,key,o+i)) o[i]=0.;
	nt *= n[i];
    }
    if (dim < 3) {
	n[2] = 1; d[2] = d[1]; o[2] = o[1];
    }

    /* read initial guess */
    s = sf_floatalloc(nt);
    sf_floatread(s,nt,in);

    if (!sf_getbool("velocity",&velocity)) velocity=true;
    /* y, input is velocity / n, slowness-squared */

    if (velocity) {
	for (it=0; it < nt; it++) {
	    s[it] = 1./s[it]*1./s[it];
	}
    }

    /* read Dix velocity */
    if (NULL == sf_getstring("dix")) sf_error("No Dix input dix=");
    dix = sf_input("dix");

    if(!sf_histint(dix,"n1",&nt0)) sf_error("No n1= in dix");
    if(!sf_histint(dix,"n2",&nx0)) sf_error("No n2= in dix");
    if(!sf_histfloat(dix,"d1",&dt0)) sf_error("No d1= in dix");
    if(!sf_histfloat(dix,"d2",&dx0)) sf_error("No d2= in dix");
    if(!sf_histfloat(dix,"o1",&ot0)) sf_error("No o1= in dix");
    if(!sf_histfloat(dix,"o2",&ox0)) sf_error("No o2= in dix");

    vd = sf_floatalloc(nt0*nx0);
    sf_floatread(vd,nt0*nx0,dix);
    sf_fileclose(dix);

    /* Dix velocity derivative in t0 (2nd order FD) */
    vdt = sf_floatalloc(nt0*nx0);
    for (i=0; i < nt0; i++) {
	for (j=0; j < nx0; j++) {
	    if (i == 0)
		vdt[j*nt0+i] = (-vd[j*nt0+i+2]+4.*vd[j*nt0+i+1]-3.*vd[j*nt0+i])/(2.*dt0);
	    else if (i == nt0-1)
		vdt[j*nt0+i] = (3.*vd[j*nt0+i]-4.*vd[j*nt0+i-1]+vd[j*nt0+i-2])/(2.*dt0);
	    else
		vdt[j*nt0+i] = (vd[j*nt0+i+1]-vd[j*nt0+i-1])/(2.*dt0);
	}
    }

    /* Dix velocity derivative in x0 (2nd order FD) */
    vdx = sf_floatalloc(nt0*nx0);
    for (j=0; j < nx0; j++) {
	for (i=0; i < nt0; i++) {
	    if (j == 0)
		vdx[j*nt0+i] = (-vd[(j+2)*nt0+i]+4.*vd[(j+1)*nt0+i]-3.*vd[j*nt0+i])/(2.*dx0);
	    else if (j == nx0-1)
		vdx[j*nt0+i] = (3.*vd[j*nt0+i]-4.*vd[(j-1)*nt0+i]+vd[(j-2)*nt0+i])/(2.*dx0);
	    else
		vdx[j*nt0+i] = (vd[(j+1)*nt0+i]-vd[(j-1)*nt0+i])/(2.*dx0);
	}
    }

    if (!sf_getint("order",&order)) order=1;
    /* fastmarch accuracy order */

    if (!sf_getfloat("thres",&thres)) thres=10.;
    /* thresholding for caustics */

    if (!sf_getint("niter",&niter)) niter=1;
    /* number of nonlinear updates */

    if (!sf_getint("cgiter",&cgiter)) cgiter=200;
    /* number of CG iterations */

    if (!sf_getbool("shape",&shape)) shape=false;
    /* regularization (default Tikhnov) */

    if (!sf_getfloat("eps",&eps)) eps=0.1;
    /* regularization parameter */

    if (!sf_getint("nline",&nline)) nline=0;
    /* maximum number of line search (default turned-off) */

    if (!sf_getbool("verb",&verb)) verb=false;
    /* verbosity flag */

    if (shape) {
	if (!sf_getfloat("tol",&tol)) tol=1.e-6;
	/* tolerance for shaping regularization */

	for (i=0; i < dim; i++) {
	    sprintf(key,"rect%d",i+1);
	    if (!sf_getint(key,rect+i)) rect[i]=1;
	    /*( rect#=(1,1,...) smoothing radius on #-th axis )*/
	}
	
	/* triangle smoothing operator */
	sf_trianglen_init(dim,rect,n);
	sf_repeat_init(nt,1,sf_trianglen_lop);
	
	sf_conjgrad_init(nt,nt,nt,nt,eps,tol,verb,false);
	p = sf_floatalloc(nt);
    } else {
	/* initialize 2D gradient operator */
	sf_igrad2_init(n[0],n[1]);
    }
    
    /* allocate memory for fastmarch */
    t0 = sf_floatalloc(nt);
    x0 = sf_floatalloc(nt);
    f0 = sf_intalloc(nt);

    /* allocate memory for update */
    ds  = sf_floatalloc(nt);
    rhs = sf_floatalloc(nt);

    /* output transformation matrix */
    if (NULL != sf_getstring("t0")) {
	t_0 = sf_output("t0");
	sf_putint(t_0,"n3",niter+1);
    }
    if (NULL != sf_getstring("x0")) {
	x_0 = sf_output("x0");
	sf_putint(x_0,"n3",niter+1);
    }

    /* output auxiliary label */
    if (NULL != sf_getstring("f0")) {
	f_0 = sf_output("f0");
	sf_settype(f_0,SF_INT);
	sf_putint(f_0,"n3",niter+1);
    }

    /* output gradient */
    if (NULL != sf_getstring("grad")) {
	grad = sf_output("grad");
	sf_putint(grad,"n3",niter);
    }

    /* output cost */
    if (NULL != sf_getstring("cost")) {
	cost = sf_output("cost");
	sf_putint(cost,"n3",niter+1);
    }

    /* read mask (desired minimum) */
    m0 = sf_intalloc(nt);

    if (NULL != sf_getstring("mask")) {
	mini = sf_input("mask");
	sf_intread(m0,nt,mini);
	sf_fileclose(mini);
    } else {
	for (it=0; it < nt; it++) m0[it] = -1;
    }

    /* read cost (desired minimum) */
    rhs0 = sf_floatalloc(nt);

    if (NULL != sf_getstring("mval")) {
	mini = sf_input("mval");
	sf_floatread(rhs0,nt,mini);
	sf_fileclose(mini);
    } else {
	for (it=0; it < nt; it++) rhs0[it] = 0.;
    }

    /* read preconditioner */
    if (NULL != sf_getstring("prec")) {
	prec = sf_input("prec");
	p0 = sf_floatalloc(nt);
	sf_floatread(p0,nt,prec);
	sf_fileclose(prec);

	rhs1 = sf_floatalloc(nt);
    }

    /* fastmarch initialization */
    fastmarch_init(n,o,d,order);

    /* update initialization */
    t2d_init(dim,n,d,nt0,dt0,ot0,nx0,dx0,ox0);

    /* fastmarch */
    fastmarch(t0,x0,f0,s);

    /* caustic region (2D) */
    t2d_caustic(x0,f0,n,d,thres);

    /* set up operator */
    t2d_set(t0,x0,f0,s,vd,vdt,vdx,m0,p0);

    /* evaluate cost */
    t2d_cost(rhs);

    for (it=0; it < nt; it++) {
	if (f0[it] >= 0 || m0[it] >= 0)
	    rhs[it] = 0.;
	else
	    rhs[it] -= rhs0[it];
    }

    if (p0 == NULL) {
	error0 = error1 = cblas_snrm2(nt,rhs,1);
    } else {
	for (it=0; it < nt; it++) rhs1[it] = p0[it]*rhs[it];
	error0 = error1 = cblas_snrm2(nt,rhs1,1);
    }

    /* write optional outputs */    
    if (NULL!=t_0)  sf_floatwrite(t0,nt,t_0);
    if (NULL!=x_0)  sf_floatwrite(x0,nt,x_0);
    if (NULL!=f_0)  sf_intwrite(f0,nt,f_0);
    if (NULL!=cost) sf_floatwrite(rhs,nt,cost);

    sf_warning("Start conversion, cost %g",1.);

    /* nonlinear loop */
    for (iter=0; iter < niter; iter++) {
	
	/* solve ds */
	if (shape) {
	    if (p0 == NULL)
		sf_conjgrad(NULL,t2d_oper,sf_repeat_lop,p,ds,rhs,cgiter);
	    else
		sf_conjgrad(t2d_prec,t2d_oper,sf_repeat_lop,p,ds,rhs,cgiter);
	} else {
	    sf_solver_reg(t2d_oper,sf_cgstep,sf_igrad2_lop,2*nt,nt,nt,ds,rhs,cgiter,eps,"verb",verb,"end");
	    sf_cgstep_close();
	}

	/* add ds */
	for (it=0; it < nt; it++) {
	    s[it] = s[it]+ds[it]+0.25*ds[it]*ds[it]/s[it];
	}

	/* fastmarch */
	fastmarch(t0,x0,f0,s);

	/* caustic region (2D) */
	t2d_caustic(x0,f0,n,d,thres);

	/* set up operator */
	t2d_set(t0,x0,f0,s,vd,vdt,vdx,m0,p0);

	/* evaluate cost */
	t2d_cost(rhs);

	for (it=0; it < nt; it++) {
	    if (f0[it] >= 0 || m0[it] >= 0)
		rhs[it] = 0.;
	    else
		rhs[it] -= rhs0[it];
	}
	
	if (p0 == NULL) {
	    error = cblas_snrm2(nt,rhs,1);
	} else {
	    for (it=0; it < nt; it++) rhs1[it] = p0[it]*rhs[it];
	    error = cblas_snrm2(nt,rhs1,1);
	}

	error = cblas_snrm2(nt,rhs,1);

	/* line search */
	if (nline > 0 && error >= error1) {

	    scale = 0.5;
	    for (iline=0; iline < nline; iline++) {

		for (it=0; it < nt; it++) {
		    s[it] = s[it]+(scale*ds[it])+0.25*(scale*ds[it])*(scale*ds[it])/s[it];
		}
		
		fastmarch(t0,x0,f0,s);
		t2d_caustic(x0,f0,n,d,thres);

		t2d_set(t0,x0,f0,s,vd,vdt,vdx,m0,p0);
		t2d_cost(rhs);

		for (it=0; it < nt; it++) {
		    if (f0[it] >= 0 || m0[it] >= 0)
			rhs[it] = 0.;
		    else
			rhs[it] -= rhs0[it];
		}
		
		if (p0 == NULL) {
		    error = cblas_snrm2(nt,rhs,1);
		} else {
		    for (it=0; it < nt; it++) rhs1[it] = p0[it]*rhs[it];
		    error = cblas_snrm2(nt,rhs1,1);
		}
		
		error = cblas_snrm2(nt,rhs,1);
		if (error < error1) {
		    sf_warning("Exist line search %d of %d",iline+1,nline);
		} else {
		    scale *= 0.5;
		}
	    }
	}

	error1 = error;

	/* write optional outputs */
	if (NULL!=t_0)  sf_floatwrite(t0,nt,t_0);
	if (NULL!=x_0)  sf_floatwrite(x0,nt,x_0);
	if (NULL!=f_0)  sf_intwrite(f0,nt,f_0);
	if (NULL!=cost) sf_floatwrite(rhs,nt,cost);
	if (NULL!=grad) sf_floatwrite(ds,nt,grad);

	sf_warning("Cost after iteration %d: %g",iter+1,error/error0);
    }

    /* write output */
    if (velocity) {
	for (it=0; it < nt; it++) {
	    s[it] = 1./sqrtf(s[it]);
	}
    }

    sf_floatwrite(s,nt,out);

    exit(0);
}
Ejemplo n.º 4
0
int main(int argc, char* argv[])
{
    bool adj, velocity, l1norm, plane[3], verb;
    int dim, i, count, n[SF_MAX_DIM], it, nt, **m, nrhs, is, nshot=1, *flag, order, iter, niter, stiter, *k, nfreq, nmem;
    float o[SF_MAX_DIM], d[SF_MAX_DIM], **t, *t0, *s, *temps, **source, *rhs, *ds;
    float rhsnorm, rhsnorm0, rhsnorm1, rate, eps, gama;
    char key[4], *what;
    sf_file sinp, sout, shot, time, reco, rece, topo, grad, norm;
    sf_weight weight=NULL;

    sf_init(argc,argv);
    sinp = sf_input("in");
    sout = sf_output("out");

    if (NULL == (what = sf_getstring("what"))) what="tomo";
    /* what to compute (default tomography) */

    switch (what[0]) {
	case 'l': /* linear operator */

	    if (NULL == sf_getstring("time"))
		sf_error("Need time=");
	    time = sf_input("time");

	    /* read operator dimension from time table */
	    dim = sf_filedims(time,n);
	    
	    nt = 1;
	    for (i=0; i < 3; i++) {
		sprintf(key,"d%d",i+1);
		if (!sf_histfloat(time,key,d+i)) sf_error("No %s= in input",key);
		sprintf(key,"o%d",i+1);
		if (!sf_histfloat(time,key,o+i)) o[i]=0.;
		nt *= n[i]; plane[i] = false;
	    }
	    if (dim < 3) {
		n[2] = 1; o[2] = o[1]; d[2] = d[1]; plane[2] = false;
	    }

	    dim = 2;

	    /* read in shot file */
	    if (NULL == sf_getstring("shot"))
		sf_error("Need source shot=");
	    shot = sf_input("shot");
	    
	    if (!sf_histint(shot,"n2",&nshot)) nshot=1;
	    sf_fileclose(shot);

	    /* read in receiver file */
	    m = sf_intalloc2(nt,nshot);
	    if (NULL == sf_getstring("receiver")) {
		for (is=0; is < nshot; is++) {
		    for (it=0; it < nt; it++) {
			m[is][it] = 1;
		    }
		}
	    } else {
		rece = sf_input("receiver");
		sf_intread(m[0],nt*nshot,rece);
		sf_fileclose(rece);
	    }

	    /* number of right-hand side */
	    nrhs = 0;
	    for (is=0; is < nshot; is++) {
		for (it=0; it < nt; it++) {
		    if (m[is][it] == 1) nrhs++;
		}
	    }
	    rhs = sf_floatalloc(nrhs);

	    t = sf_floatalloc2(nt,nshot);
	    sf_floatread(t[0],nt*nshot,time);

	    if (!sf_getbool("adj",&adj)) adj=false;
	    /* adjoint flag (for what=linear) */

	    /* initialize fatomo */
	    fatomo_init(dim,n,d,nshot);

	    /* set operators */
	    fatomo_set(t,m);

	    t0 = sf_floatalloc(nt);

	    if (adj) {
		sf_floatread(rhs,nrhs,sinp);

		fatomo_lop(true,false,nt,nrhs,t0,rhs);

		sf_putint(sout,"n1",nt);
		sf_putint(sout,"n2",1);
		sf_putint(sout,"n3",1);
		sf_floatwrite(t0,nt,sout);
	    } else {
		sf_floatread(t0,nt,sinp);

		fatomo_lop(false,false,nt,nrhs,t0,rhs);
		
		sf_putint(sout,"n1",nrhs);
		sf_putint(sout,"n2",1);
		sf_putint(sout,"n3",1);
		sf_floatwrite(rhs,nrhs,sout);
	    }

	    break;
	    
	case 't': /* tomography */

	    /* read input dimension */
	    dim = sf_filedims(sinp,n);
	    
	    nt = 1;
	    for (i=0; i < dim; i++) {
		sprintf(key,"d%d",i+1);
		if (!sf_histfloat(sinp,key,d+i)) sf_error("No %s= in input",key);
		sprintf(key,"o%d",i+1);
		if (!sf_histfloat(sinp,key,o+i)) o[i]=0.;
		nt *= n[i]; plane[i] = false;
	    }
	    if (dim < 3) {
		n[2] = 1; o[2] = o[1]; d[2] = d[1]; plane[2] = false;
	    }
	    
	    /* read initial guess */
	    s = sf_floatalloc(nt);
	    sf_floatread(s,nt,sinp);
	    
	    if (!sf_getbool("velocity",&velocity)) velocity=true;
	    /* if y, the input is velocity; n, slowness squared */

	    if (velocity) {
		for (it=0; it < nt; it++) {
		    s[it] = 1./s[it]*1./s[it];
		}
	    }

	    /* allocate memory for temporary data */
	    ds    = sf_floatalloc(nt);
	    flag  = sf_intalloc(nt);
	    
	    temps = sf_floatalloc(nt);
	    for (it=0; it < nt; it++) {
		temps[it] = s[it];
	    }
	    
	    if (!sf_getbool("l1norm",&l1norm)) l1norm=false;
	    /* norm for minimization (default L2 norm) */

	    if (!sf_getbool("verb",&verb)) verb=false;
	    /* verbosity flag */

	    /* read in shot file */
	    if (NULL == sf_getstring("shot"))
		sf_error("Need source shot=");
	    shot = sf_input("shot");

	    if (!sf_histint(shot,"n2",&nshot)) nshot=1;

	    source = sf_floatalloc2(3,nshot);
	    sf_floatread(source[0],3*nshot,shot);
	    sf_fileclose(shot);

	    /* allocate memory for time table */
	    t = sf_floatalloc2(nt,nshot);

	    /* read in receiver file */
	    m = sf_intalloc2(nt,nshot);
	    if (NULL == sf_getstring("receiver")) {
		for (is=0; is < nshot; is++) {
		    for (it=0; it < nt; it++) {
			m[is][it] = 1;
		    }
		}
	    } else {
		rece = sf_input("receiver");
		sf_intread(m[0],nt*nshot,rece);
		sf_fileclose(rece);
	    }
	    
	    /* number of right-hand side */
	    nrhs = 0;
	    for (is=0; is < nshot; is++) {
		for (it=0; it < nt; it++) {
		    if (m[is][it] == 1) nrhs++;
		}
	    }
	    rhs = sf_floatalloc(nrhs);
	    
	    /* read in record file */
	    if (NULL == sf_getstring("record"))
		sf_error("Need data record=");
	    reco = sf_input("record");

	    t0 = sf_floatalloc(nrhs);
	    sf_floatread(t0,nrhs,reco);
	    sf_fileclose(reco);

	    /* read in topography file */
	    if (NULL != sf_getstring("topo")) {
		topo = sf_input("topo");
		k = sf_intalloc(nt);
		sf_intread(k,nt,topo);
		sf_fileclose(topo);
	    } else {
		k = NULL;
	    }
	    
	    if (!sf_getint("order",&order)) order=2;
	    /* fast marching accuracy order */

	    if (!sf_getint("niter",&niter)) niter=10;
	    /* number of slowness inversion iterations */

	    if (!sf_getint("stiter",&stiter)) stiter=200;
	    /* number of step iterations */

	    if (!sf_getfloat("eps",&eps)) eps=0.;
	    /* regularization parameter */

	    /* output gradient at each iteration */
	    if (NULL != sf_getstring("gradient")) {
		grad = sf_output("gradient");
		sf_putint(grad,"n3",n[2]);
		sf_putfloat(grad,"d3",d[2]);
		sf_putfloat(grad,"o3",o[2]);
		sf_putint(grad,"n4",niter);
	    } else {
		grad = NULL;
	    }

	    /* output misfit L2 norm at each iteration */
	    if (NULL != sf_getstring("misnorm")) {
		norm = sf_output("misnorm");
		sf_putint(norm,"n1",niter+1);
		sf_putfloat(norm,"d1",1.);
		sf_putfloat(norm,"o1",0.);
		sf_putint(norm,"n2",1);
		sf_putint(norm,"n3",1);
	    } else {
		norm = NULL;
	    }

	    /* initialize fatomo */
	    fatomo_init(dim,n,d,nshot);

	    /* initialize 2D gradient operator */
	    sf_igrad2_init(n[0],n[1]);

	    if (l1norm) {
		/*
		if (!sf_getfloat("perc",&perc)) perc=90.;

		l1_init(nt,stiter,perc,false);
		*/
		if (!sf_getint("nfreq",&nfreq)) nfreq=1;
		/* l1-norm weighting nfreq */

		if (!sf_getint("nmem",&nmem)) nmem=1;
		/* l1-norm weighting nmem */

		weight = sf_l1;
		sf_irls_init(nt);
	    }

	    /* initial misfit */
	    fastmarch_init(n[2],n[1],n[0]);
	    
	    i = 0;
	    for (is=0; is < nshot; is++) {
		fastmarch(t[is],s,flag,plane,
			  n[2],n[1],n[0],o[2],o[1],o[0],d[2],d[1],d[0],
			  source[is][2],source[is][1],source[is][0],1,1,1,order);

		for (it=0; it < nt; it++) {
		    if (m[is][it] == 1) {
			rhs[i] = t0[i]-t[is][it];
			i++;
		    }
		}
	    }
	    
	    fastmarch_close();
	    
	    /* calculate L2 data-misfit */
	    rhsnorm0 = cblas_snrm2(nrhs,rhs,1);
	    rhsnorm = rhsnorm0;
	    rhsnorm1 = rhsnorm;
	    rate = rhsnorm1/rhsnorm0;

	    if (l1norm)
		sf_warning("L1 misfit after iteration 0 of %d: %g",niter,rate);
	    else
		sf_warning("L2 misfit after iteration 0 of %d: %g",niter,rate);

	    if (norm != NULL) sf_floatwrite(&rate,1,norm);

	    /* iterations over inversion */
	    for (iter=0; iter < niter; iter++) {
		
		/* clean-up */
		for (it=0; it < nt; it++) {
		    ds[it] = 0.;
		}

		/* prepare for CG */
		fatomo_set(t,m);

		/* solve ds */
		if (l1norm) {
		    /*
		      sf_solver_reg(fatomo_lop,l1step,sf_igrad2_lop,2*nt, nt,nrhs,ds,rhs,stiter,eps,"verb",verb,"end");
		    */
		    sf_solver_reg(fatomo_lop,sf_cgstep,sf_igrad2_lop,2*nt,nt,nrhs,ds,rhs,stiter,eps,"wght",weight,"nfreq",nfreq,"nmem",nmem,"verb",verb,"end");
		    
		    /*
		      l1step_close();
		    */
		    
		    sf_cgstep_close();
		} else {
		    sf_solver_reg(fatomo_lop,sf_cgstep,sf_igrad2_lop,2*nt,nt,nrhs,ds,rhs,stiter,eps,"verb",verb,"end");
			
		    sf_cgstep_close();
		}
		
		/* line search */
		gama = 1.;
		for (count=0; count < 10; count++) {
		    
		    /* update slowness */
		    for (it=0; it < nt; it++) {
			if (k == NULL || k[it] != 1)
			    temps[it] = (s[it]+gama*ds[it])*(s[it]+gama*ds[it])/s[it];
		    }

		    /* forward fast-marching for stencil time */
		    fastmarch_init(n[2],n[1],n[0]);
		    
		    i = 0;
		    for (is=0; is < nshot; is++) {
			fastmarch(t[is],temps,flag,plane,
				  n[2],n[1],n[0],o[2],o[1],o[0],d[2],d[1],d[0],
				  source[is][2],source[is][1],source[is][0],1,1,1,order);
			
			for (it=0; it < nt; it++) {
			    if (m[is][it] == 1) {
				rhs[i] = t0[i]-t[is][it];
				i++;
			    }
			}
		    }
		    
		    fastmarch_close();
		    
		    rhsnorm = cblas_snrm2(nrhs,rhs,1);
		    rate = rhsnorm/rhsnorm1;
		    
		    if (rate < 1.) {
			for (it=0; it < nt; it++) {
			    s[it] = temps[it];
			}
			rhsnorm1 = rhsnorm;
			rate = rhsnorm1/rhsnorm0;
			break;
		    }
		    
		    gama *= 0.5;
		}
		
		if (count == 10) {
		    sf_warning("Line-search Failure. Iteration terminated at %d of %d.",iter+1,niter);
		    sf_warning("Dimensions for GRAD and NORM need to be fixed before read.");
		    break;
		}

		if (l1norm)
		    sf_warning("L1 misfit after iteration %d of %d: %g (line-search %d)",iter+1,niter,rate,count);
		else
		    sf_warning("L2 misfit after iteration %d of %d: %g (line-search %d)",iter+1,niter,rate,count);
		
		if (grad != NULL) sf_floatwrite(ds,nt,grad);
		if (norm != NULL) sf_floatwrite(&rate,1,norm);
	    }
	    
	    /* convert to velocity */
	    if (velocity) {
		for (it=0; it < nt; it++) {
		    s[it] = 1./sqrtf(s[it]);
		}
	    }
	    
	    sf_floatwrite(s,nt,sout);

       	    break;
    }
    
    exit(0);
}
Ejemplo n.º 5
0
int main(int argc, char* argv[])
{
    int nt, ncmp, ncdp, nh, nh2, nm, nd, memsize, niter, reg, ix, ih, i3, i2, i1, iter, filt, nw, np;
    float t0, cmp0, cdp0, h0, dt, dcmp, dcdp, dh, apt, rho, aal, norm;
    bool verb, half, amp;
    float ***data, ***modl, **vrms, **mask, *off, *error=NULL;
    float **pp, **qq, *aa;
    char *errfile;
    sf_file in, out, vel, offset, err=NULL;
    sf_file fdip;

    int ompchunk = 1;
    int ompnth = 1;

#ifdef _OPENMP
    int ompath=1;
#endif

    /*------------------------------------------------------------*/
    sf_init(argc,argv);

    if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1;
    /* OpenMP data chunk size */
#ifdef _OPENMP
    if(! sf_getint("ompnth",  &ompnth))     ompnth=0;
    /* OpenMP available threads */

#pragma omp parallel
    ompath=omp_get_num_threads();
    if(ompnth<1) ompnth=ompath;
    omp_set_num_threads(ompnth);
    sf_warning("using %d threads of a total of %d",ompnth,ompath);
#endif

    in = sf_input("in");
    vel = sf_input("vel");
    out = sf_output("out");

    if (!sf_getbool("verb",&verb)) verb=false;
    /* verbosity flag */

    if (!sf_getbool("half",&half)) half = true;
    /* if y, the third axis is half-offset instead of full offset */

    if (!sf_getbool("amp",&amp)) amp = true;
    /* if y, use amplitue factor */

    if (!sf_histint(in,"n1",&nt)) sf_error("No n1= in input");
    if (!sf_histfloat(in,"d1",&dt)) sf_error("No d1= in input");
    if (!sf_histfloat(in,"o1",&t0)) sf_error("No o1= in input");

    if (!sf_histint(in,"n2",&ncmp)) sf_error("No n2= in input");
    if (!sf_histfloat(in,"d2",&dcmp)) sf_error("No d2= in input");
    if (!sf_histfloat(in,"o2",&cmp0)) sf_error("No o2= in input");

    if (!sf_getint("ncdp",&ncdp)) ncdp = ncmp;
    if (!sf_getfloat("dcdp",&dcdp)) dcdp = dcmp;
    if (!sf_getfloat("cdp0",&cdp0)) cdp0 = cmp0;

    sf_putint(out,"n2",ncdp);
    sf_putfloat(out,"d2",dcdp);
    sf_putfloat(out,"o2",cdp0);

    if (!sf_histint(in,"n3",&nh)) sf_error("No n3= in input");

    if (NULL != sf_getstring("offset")) {
        offset = sf_input("offset");
        nh2 = sf_filesize(offset);

        if (nh2 != nh*ncmp) sf_error("Wrong dimensions in offset, it should be %d",nh*ncmp);

        off = sf_floatalloc(nh2);
        sf_floatread (off,nh2,offset);
        sf_fileclose(offset);
        if (!half) {
           for (ih = 0; ih < nh2; ih++) {
               off[ih] *= 0.5;
            }
        }
    } else {
        if (!sf_histfloat(in,"o3",&h0)) sf_error("No o3=");
        if (!sf_histfloat(in,"d3",&dh)) sf_error("No d3=");

        if (!half) dh *= 0.5,h0 *= 0.5;

        off = sf_floatalloc(nh*ncmp);
        for (ix = 0; ix < ncmp; ix++) {
            for (ih = 0; ih < nh; ih++) {
                off[ih*ncmp+ix] = h0 + ih*dh;
            }
        }
        offset = NULL;
    }

    if (!sf_getint("reg",&reg)) reg=0;
    /* regularization type */ 

    if (!sf_getfloat("antialias",&aal)) aal = 1.0;
    /* antialiasing */

    if (!sf_getfloat("apt",&apt)) apt=ncmp;
    /* migration aperture */

    if (!sf_getfloat("rho",&rho)) rho = 1.-1./nt;
    /* Leaky integration constant */

    if (!sf_getint("niter",&niter)) niter=5;
    /* number of iterations */


    nm = nt*ncdp*nh;
    nd = nt*ncmp*nh;

    vrms = sf_floatalloc2(nt,ncdp);
    mask = sf_floatalloc2(ncmp,nh);
    data = sf_floatalloc3(nt,ncmp,nh);
    modl = sf_floatalloc3(nt,ncdp,nh);

    /* read velocity file */
    sf_floatread(vrms[0],nt*ncdp,vel);
    sf_fileclose(vel);

    memsize = nm+nd+nt*ncdp+ncmp*nh;
    if (verb) sf_warning("memory needs: %f G (%f M)",4.*memsize/1024/1024/1024,4.*memsize/1024/1024);

    if (niter > 0) {
        errfile = sf_getstring("err");
        /* output file for error */
        if (NULL != errfile) {
            err = sf_output(errfile);
            sf_putint(err,"n1",niter);
            sf_putfloat(err,"d1",1);
            sf_putfloat(err,"o1",1);
            sf_putstring(err,"label1","Iteration Number");
            sf_putstring(err,"label2","Relative Squared Error");
            sf_putint(err,"n2",1);
            sf_putint(err,"n3",1);
        }
        error = sf_floatalloc(niter);
    }

    sf_floatread(data[0][0],nd,in);

    for (i3=0; i3 < nh; i3++) {
        for (i2=0; i2 < ncmp; i2++) {
            mask[i3][i2]=cblas_sdot(nt,data[i3][i2],1,data[i3][i2],1);
        }
    }

    tkirmig_init(ompnth,ompchunk,nt,dt,t0,ncmp,dcmp,cmp0,ncdp,dcdp,cdp0,nh,dh,h0,apt,aal,rho,vrms,off,mask,amp,verb);

    sf_cdstep_init();

    if (verb) sf_warning("Iteration begin...");

    if (reg == 0)
       sf_solver(tkirmig_lop,sf_cdstep,nm,nd,modl[0][0],data[0][0],
                 niter,"nmem",0,"nfreq",niter,"err",error,"end");

    else if (reg == 1) {
       filt=2;
       aa=sf_floatalloc(filt);
       aa[0]=1.;
       aa[1]=-1.;
       tcaih_init(filt,aa,nt,ncdp,nh);
       sf_solver_reg(tkirmig_lop,sf_cdstep,tcaih_lop,nm+filt*nt*ncdp,nm,nd,
                    modl[0][0],data[0][0],niter,0.01,"nmem",0,"nfreq",niter,
                    "err",error,"end");
    }
    else if (reg == 2) {
       sf_causinth_init(nt,ncdp,nh);
       sf_solver_prec(tkirmig_lop,sf_cdstep,sf_causinth_lop,nm,nm,nd,
                      modl[0][0],data[0][0],niter,0.01,"nmem",0,"nfreq",niter,
                      "err",error,"end");
    }
    else if (reg == 3) {
       sf_triangleh_init(3,nt,ncdp,nh);
       sf_solver_prec(tkirmig_lop,sf_cdstep,sf_triangleh_lop,nm,nm,nd,
                      modl[0][0],data[0][0],niter,0.01,"nmem",0,"nfreq",niter,
                      "err",error,"end");
    }

    else if (reg == 4) {
       sf_warning("pwd constraints along t-x plane and smoothing along offset axis");
       if (!sf_getstring("fdip")) sf_error("Need input dip file!");
       if (!sf_getint("nw",&nw)) nw=3;
       fdip = sf_input("fdip");

       if (!sf_histint(fdip,"n3",&np)) np=1;
       sf_warning("np=%d",np);
       pp = sf_floatalloc2(nt,ncdp);

       if (np > 1) {
          qq = sf_floatalloc2(nt,ncdp);
       } else {
          qq = NULL;
       }

       if (NULL != qq) {
          predicth2_init(nt,ncdp,nh,0.1,nw,pp,qq);
       } else {
          predicth_init(nt,ncdp,nh,0.1,nw,1,false);
          predict_set(pp);
       }

       sf_floatread(pp[0],nt*ncdp,fdip);

       if (NULL != qq) {
          sf_floatread(qq[0],nt*ncdp,fdip);
          sf_solver_prec(tkirmig_lop,sf_cdstep,predicth2_lop,nm,nm,nd,
                      modl[0][0],data[0][0],niter,0.01,"nmem",0,"nfreq",niter,
                      "err",error,"end");
         predict2_close();
       } else {
         sf_solver_prec(tkirmig_lop,sf_cdstep,predicth_lop,nm,nm,nd,
                      modl[0][0],data[0][0],niter,0.01,"nmem",0,"nfreq",niter,
                      "err",error,"end");
         predict_close();
      }
    }

    sf_cdstep_close();
    sf_floatwrite(modl[0][0],nm,out);

    if (NULL != err) {
       for (i3=0; i3 < nh; i3++) {
           for (i2=0; i2 < ncmp; i2++) {
               for (i1=0; i1 < nt; i1++) {
                   norm += data[i3][i2][i1]*data[i3][i2][i1];
               }
           }
        }
        
        for (iter=0; iter < niter; iter++) error[iter] /=norm;
        sf_floatwrite(error,niter,err);
    }

    sf_warning("iter/niter=%d/%d, err=%f",iter,niter,error);

    exit(0);
}
Ejemplo n.º 6
0
void adaptsub_icaf(float *input1, float *input2, float *output,  int ns,  int ntr, int order, int Twin, int Xwin, float mu, char *method, bool verb)
/*<adaptive matched-filter subtraction using internal convolution>*/
{
	float value;
	float  **Data,**Mult;
	float  *d,*m,*x;
	int i,j,ii,jj,ind,ind2,twin,xwin,k,samples;
	int oo=(Twin+1)/2 ;
	twin=(Twin-1)/2;
	xwin=(Xwin-1)/2;
	k=Twin*Xwin;
	samples=ns*ntr;


	Data=sf_floatalloc2(ntr+Xwin-1,ns+Twin-1);
	Mult=sf_floatalloc2(ntr+Xwin-1,ns+Twin-1);

	d = sf_floatalloc(k);
	m = sf_floatalloc(k);
	x = sf_floatalloc(order);

	for (i=0;i<order;i++) x[i]=0.0;

	pad (input1, Data, ns, ntr, twin, xwin);
	pad (input2, Mult, ns, ntr, twin, xwin);



	for(ind=0,j=0; j < ntr; j++)
	{
		for(i=0; i < ns; i++,ind++)
		{
			value=0.0;
			for(ind2=0,jj=0; jj < Xwin; jj++)
			{   // patching 2D
				for(ii=0; ii < Twin; ii++,ind2++)
				{
					d[ind2] =  Data[i+ii][j+jj];
					m[ind2] =  Mult[i+ii][j+jj];
				}
			}



			sf_cdstep_init();

			if ('o' == method[0] || 'O' == method[0]) {

				icaf1_init (k  /* data length */,
							m  /* data [k] */,
							1  /* filter lag (lag=1 is causal) */);

				sf_solver_prec (icaf1_lop, sf_cdstep, sf_copy_lop, order, order, k,
						x, d, 3*order, mu,"end");
			}
			else {

				filter1d_icaf_init(Twin  /* window time length */,
								    Xwin  /* window space length */,
								    m /* signal to be matched */);

				sf_solver_reg (filter1d_icaf_lop, sf_cdstep, sf_copy_lop, order, order, k,
									x, d, 3*order, mu,"end");

				filter1d_icaf_close();
			}

			sf_cdstep_close();

			for(ii=0 ; ii < order ; ii++) {
				value += x[ii] * Mult[i + oo -ii-1][j+xwin];       // matched signal
			}
			output[ind] = input1[ind] - value;       			   // subtraction

		}
		if (verb)
		sf_warning("\r\t\t\t\t\t\t\t\t\t %3.2f%% ",(float)100*(ind+1)/samples);

	}

	free(Data[0]);
	free(Data);
	free(Mult[0]);
	free(Mult);


	free(d);
	free(m);
	free(x);
}
Ejemplo n.º 7
0
void adaptsub_tcaf(float *input1, float *input2, float *output,  int ns,  int ntr, int order, int Twin, int Xwin, float mu, char *method, bool verb)
/*<adaptive matched-filter subtraction using transient convolution>*/
{
	float value;
	float  **Data,**Mult;
	float  *d,*m,*x;
	int nd,nm;
	int i,j,ii,jj,ind,twin,xwin,samples;

	int o  =  (order-1)/2;
	int oo =  (Twin+1)/2+(order-1)/2 ;
	twin=(Twin-1)/2;
	xwin=(Xwin-1)/2;

	samples=ns*ntr;


	Data=sf_floatalloc2(ntr+Xwin-1,ns+Twin-1);
	Mult=sf_floatalloc2(ntr+Xwin-1,ns+Twin-1);
;

	nm = Twin*Xwin;

	if ('o' == method[0] || 'O' == method[0])
		nd = (Twin*Xwin) + order-1;
	else
		nd = (Twin+order-1)*Xwin;


	d = sf_floatalloc(nd);
	m = sf_floatalloc(nm);
	x = sf_floatalloc(order);

	for (i=0;i<order;i++) x[i]=0.0;

	pad (input1, Data, ns, ntr, twin, xwin);
	pad (input2, Mult, ns, ntr, twin, xwin);



	for(ind=0,j=0; j < ntr; j++)
	{
		for(i=0; i < ns; i++,ind++)
		{
			value=0.0;
			for(jj=0; jj < Xwin; jj++)
			{   // patching 2D
				for(ii=0; ii < Twin; ii++)
				{
					if ('o' == method[0] || 'O' == method[0])
						d[ii+(jj * Twin) + o] =  Data[i+ii][j+jj];
					else
						d[ii+(jj* (Twin+2*o) ) + o] =  Data[i+ii][j+jj];

					m[ii+(jj*Twin)] =  Mult[i+ii][j+jj];
				}
			}

			//sf_cdstep_init();

			if ('o' == method[0] || 'O' == method[0]) {

				tcaf1_init (nm  /* data length */,
							m  /* data [k] */);

				sf_solver_prec (tcaf1_lop, sf_cdstep, sf_copy_lop, order, order, nd,
						x, d, 3*order, mu,"end");
			}
			else {


				filter1d_tcaf_init(Twin  /* window time length */,
								    Xwin  /* window space length */,
								    order /* filter order */,
								    m /* signal to be matched */);


				sf_solver_reg (filter1d_tcaf_lop, sf_cdstep, sf_copy_lop, order, order, nd,
									x, d, 3*order, mu,"end");



				filter1d_tcaf_close();
			}

			sf_cdstep_close();

			for(ii=0 ; ii < order ; ii++) {
				value += x[ii] * Mult[i + oo -(ii+1)][j+xwin];       // matched signal
			}
			output[ind] = input1[ind] - value;       			   // subtraction

		}
		if (verb)
		sf_warning("\r\t\t\t\t\t\t\t\t\t %3.2f%% ",(float)100*(ind+1)/samples);

	}

	free(Data[0]);
	free(Data);
	free(Mult[0]);
	free(Mult);


	free(d);
	free(m);
	free(x);
}
Ejemplo n.º 8
0
int main(int argc, char* argv[])
{
    bool velocity, causal, limit, verb, shape;
    int dimw, dimt, i, n[SF_MAX_DIM], rect[SF_MAX_DIM], iw, nw, ir, nr;
    long nt, *order;
    int iter, niter, cgiter, count;
    int *ff, *dp, *mp, nloop;
    float o[SF_MAX_DIM], d[SF_MAX_DIM], *dt, *dw, *dv, *t, *w, *t0, *w1, *p=NULL;
    float eps, tol, thres, rhsnorm, rhsnorm0, rhsnorm1, rate, gama;
    char key[6];
    sf_file in, out, reco, grad, mask, prec;

    sf_init(argc,argv);
    in  = sf_input("in");
    out = sf_output("out");
   
    /* read dimension */
    dimw = sf_filedims(in,n);
	    
    nw = 1;
    for (i=0; i < dimw; i++) {
	sprintf(key,"d%d",i+1);
	if (!sf_histfloat(in,key,d+i)) sf_error("No %s= in input.",key);
	sprintf(key,"o%d",i+1);
	if (!sf_histfloat(in,key,o+i)) o[i]=0.;
	nw *= n[i];
    }
	    
    if (dimw > 2) sf_error("Only works for 2D now.");
	    
    n[2] = n[1]; d[2] = d[1]; o[2] = o[1];
    dimt = 3; nr = n[1]*n[2]; nt = nw*n[2];

    /* read initial velocity */
    w = sf_floatalloc(nw);
    sf_floatread(w,nw,in);
	    
    if (!sf_getbool("velocity",&velocity)) velocity=true;
    /* if y, the input is velocity; n, slowness-squared */
	    	    
    /* convert to slowness-squared */
    if (velocity) {
	for (iw=0; iw < nw; iw++)
	    w[iw] = 1./w[iw]*1./w[iw];
	
	dv = sf_floatalloc(nw);
    } else {
	dv = NULL;
    }
	    
    if (!sf_getbool("limit",&limit)) limit=false;
    /* if y, limit computation within receiver coverage */

    if (!sf_getbool("shape",&shape)) shape=false;
    /* shaping regularization (default no) */
	    
    /* read record */
    if (NULL == sf_getstring("reco"))
	sf_error("Need record reco=");
    reco = sf_input("reco");
    
    t0 = sf_floatalloc(nr);
    sf_floatread(t0,nr,reco);
    sf_fileclose(reco);
	    
    /* read receiver mask */	    
    if (NULL == sf_getstring("mask")) {
	mask = NULL;
	dp = NULL;
    } else {
	mask = sf_input("mask");
	dp = sf_intalloc(nr);
	sf_intread(dp,nr,mask);
	sf_fileclose(mask);
    }
	    
    /* read model mask */
    if (NULL == sf_getstring("prec")) {
	prec = NULL;
	mp = NULL;
    } else {
	prec = sf_input("prec");
	mp = sf_intalloc(nw);
	sf_intread(mp,nw,prec);
	sf_fileclose(prec);
    }

    if (!sf_getbool("verb",&verb)) verb=false;
    /* verbosity flag */
	    
    if (!sf_getint("niter",&niter)) niter=5;
    /* number of inversion iterations */
	    
    if (!sf_getint("cgiter",&cgiter)) cgiter=10;
    /* number of conjugate-gradient iterations */
	    
    if (!sf_getfloat("thres",&thres)) thres=5.e-5;
    /* threshold (percentage) */
	    
    if (!sf_getfloat("tol",&tol)) tol=1.e-3;
    /* tolerance for bisection root-search */

    if (!sf_getint("nloop",&nloop)) nloop=10;
    /* number of bisection root-search */

    /* output gradient at each iteration */
    if (NULL != sf_getstring("grad")) {
	grad = sf_output("grad");
	sf_putint(grad,"n3",niter);
    } else {
	grad = NULL;
    }
	    
    if (!sf_getfloat("eps",&eps)) eps=0.;
    /* regularization parameter */

    if (shape) {
	for (i=0; i < dimw; i++) {
	    sprintf(key,"rect%d",i+1);
	    if (!sf_getint(key,rect+i)) rect[i]=1;
	    /*( rect#=(1,1,...) smoothing radius on #-th axis )*/
	}
	
	/* triangle smoothing operator */
	sf_trianglen_init(dimw,rect,n);
	sf_repeat_init(nw,1,sf_trianglen_lop);
	
	sf_conjgrad_init(nw,nw,nr,nr,eps,1.e-6,verb,false);
	p = sf_floatalloc(nw);
    } else {
	/* initialize 2D gradient operator */
	sf_igrad2_init(n[0],n[1]);
    }

    /* allocate temporary array */
    t  = sf_floatalloc(nt);
    dw = sf_floatalloc(nw);
    dt = sf_floatalloc(nr);
    w1 = sf_floatalloc(nw);
    ff = sf_intalloc(nt);

    if (!sf_getbool("causal",&causal)) causal=true;
    /* if y, neglect non-causal branches of DSR */

    /* initialize eikonal */
    dsreiko_init(n,o,d,
		 thres,tol,nloop,
		 causal,limit,dp);
	    
    /* initialize operator */
    dsrtomo_init(dimt,n,d);

    /* upwind order */
    order = dsrtomo_order();

    /* initial misfit */
    dsreiko_fastmarch(t,w,ff,order);
    dsreiko_mirror(t);

    /* calculate L2 data-misfit */
    for (ir=0; ir < nr; ir++) {
	if (dp == NULL || dp[ir] == 1) {
	    dt[ir] = t0[ir]-t[(long) ir*n[0]];
	} else {
	    dt[ir] = 0.;
	}
    }

    rhsnorm0 = cblas_snrm2(nr,dt,1);
    rhsnorm = rhsnorm0;
    rhsnorm1 = rhsnorm;
    rate = rhsnorm1/rhsnorm0;
	    
    sf_warning("L2 misfit after iteration 0 of %d: %g",niter,rate);
    
    /* iterations over inversion */
    for (iter=0; iter < niter; iter++) {
	
	/* clean-up */
	for (iw=0; iw < nw; iw++) dw[iw] = 0.;
	
	/* set operator */
	dsrtomo_set(t,w,ff,dp,mp);
	
	/* solve dw */
	if (shape) {
	    sf_conjgrad(NULL,dsrtomo_oper,sf_repeat_lop,p,dw,dt,cgiter);
	} else {
	    sf_solver_reg(dsrtomo_oper,sf_cgstep,sf_igrad2_lop,2*nw,nw,nr,dw,dt,cgiter,eps,"verb",verb,"end");
	    sf_cgstep_close();
	}
	
	/* output gradient */
	if (grad != NULL) {
	    if (velocity) {
		for (iw=0; iw < nw; iw++) {
		    dv[iw] = -dw[iw]/(2.*sqrtf(w[iw])*(w[iw]+dw[iw]/2.));
		}
		sf_floatwrite(dv,nw,grad);
	    } else {
		sf_floatwrite(dw,nw,grad);
	    }
	}
	
	/* line search */
	gama = 0.5;
	for (count=0; count < 5; count++) {
	    
	    /* update slowness */
	    for (iw=0; iw < nw; iw++) 
		w1[iw] = (w[iw]+gama*dw[iw])*(w[iw]+gama*dw[iw])/w[iw];
	    
	    /* compute new misfit */
	    dsreiko_fastmarch(t,w1,ff,order);
	    dsreiko_mirror(t);
	    
	    for (ir=0; ir < nr; ir++) {
		if (dp == NULL || dp[ir] == 1) {
		    dt[ir] = t0[ir]-t[(long) ir*n[0]];
		} else {
		    dt[ir] = 0.;
		}
	    }

	    rhsnorm = cblas_snrm2(nr,dt,1);
	    rate = rhsnorm/rhsnorm1;
	    
	    if (rate < 1.) {
		for (iw=0; iw < nw; iw++) w[iw] = w1[iw];
		
		rhsnorm1 = rhsnorm;
		rate = rhsnorm1/rhsnorm0;
		break;
	    }
	    
	    gama *= 0.5;
	}
	
	if (count == 5) {
	    sf_warning("Line-search failure at iteration %d of %d.",iter+1,niter);
	    break;
	}
	
	sf_warning("L2 misfit after iteration %d of %d: %g (line-search %d)",iter+1,niter,rate,count);
    }
    
    /* convert to velocity */
    if (velocity) {
	for (iw=0; iw < nw; iw++) {
	    w[iw] = 1./sqrtf(w[iw]);
	}
    }
    
    sf_floatwrite(w,nw,out);
       
    exit(0);
}
Ejemplo n.º 9
0
int main(int argc, char* argv[])
{
    int nhe, nxs, nh, nxm, nt, nv;
    float dhe, he0, dxs, xs0, dh, h0, dxm, xm0, dt, t0, v, apt, dv, ov, eps;
    int nm, nd, niter;
    bool half, verb, linear, weight, reg, sparse;

    float *cmp, *csp, *error;

    char *errfile;

    sf_file in, out, err;

    int ompchunk = 1;
    int ompnth = 1;

#ifdef _OPENMP
    int ompath=1;
#endif

    /*------------------------------------------------------------*/
    sf_init(argc,argv);

    if(! sf_getint("ompchunk",&ompchunk)) ompchunk=1;
    /* OpenMP data chunk size */
#ifdef _OPENMP
    if(! sf_getint("ompnth",  &ompnth))     ompnth=0;
    /* OpenMP available threads */

#pragma omp parallel
    ompath=omp_get_num_threads();
    if(ompnth<1) ompnth=ompath;
    omp_set_num_threads(ompnth);
    sf_warning("using %d threads of a total of %d",ompnth,ompath);
#endif

    in = sf_input("in");
    out = sf_output("out");

    if (!sf_getint("niter",&niter)) niter=true;
    /* iteration number */

    if (!sf_getbool("weight",&weight)) weight=false;
    /* weighting flag */

    if (!sf_getbool("linear",&linear)) linear=true;
    /* yes: linear interpolation, no: nearest-neighbor interpolation */

    if (!sf_getfloat("v",&v)) v=2000.;
    /* velocity */

    if (!sf_getbool("reg",&reg)) reg=false;
    /* regularization flag */

    if (!sf_getbool("sparse",&sparse)) sparse=false;
    /* sparse flag */

    if (!sf_getbool("half",&half)) half=true;
    /* half offset flag */

    if (!sf_getbool("verb",&verb)) verb=false;
    /* verbosity flag */

    if (niter > 0) {
        errfile = sf_getstring("err");
        /* output file for error */
        if (NULL != errfile) {
            err = sf_output(errfile);
            sf_putint(err,"n1",niter);
            sf_putfloat(err,"d1",1);
            sf_putfloat(err,"o1",1);
            sf_putstring(err,"label1","Iteration Number");
            sf_putstring(err,"label2","Relative Squared Error");
            sf_putint(err,"n2",1);
            sf_putint(err,"n3",1);
        }
        error = sf_floatalloc(niter);
    }

    if (!sf_histint(in,"n1",&nt)) sf_error("No n1= in input");
    if (!sf_histfloat(in,"d1",&dt)) sf_error("No d1= in input");
    if (!sf_histfloat(in,"o1",&t0)) sf_error("No o1= in input");

    if (!sf_histint(in,"n3",&nxm)) sf_error("No n3= in input");
    if (!sf_histfloat(in,"d3",&dxm)) sf_error("No d3= in input");
    if (!sf_histfloat(in,"o3",&xm0)) sf_error("No o3= in input");

    if (!sf_histint(in,"n2",&nh)) sf_error("No n2= in input");
    if (!sf_histfloat(in,"d2",&dh)) sf_error("No d2= in input");
    if (!sf_histfloat(in,"o2",&h0)) sf_error("No o2= in input");

    if (!sf_getint("nhe",&nhe)) nhe = nh;
    if (!sf_getfloat("dhe",&dhe)) dhe = dh;
    if (!sf_getfloat("he0",&he0)) he0 = h0;

    if (!sf_getint("nxs",&nxs)) nxs = nxm;
    if (!sf_getfloat("dxs",&dxs)) dxs = dxm;
    if (!sf_getfloat("xs0",&xs0)) xs0 = xm0;

    sf_putint(out,"n1",nt);
    sf_putfloat(out,"d1",dt);
    sf_putfloat(out,"o1",t0);

    sf_putint(out,"n2",nhe);
    sf_putfloat(out,"d2",dhe);
    sf_putfloat(out,"o2",he0);

    sf_putint(out,"n3",nxs);
    sf_putfloat(out,"d3",dxs);
    sf_putfloat(out,"o3",xs0);

    if (!sf_getfloat("apt",&apt)) apt=SF_MAX(fabsf(he0),fabsf(he0+(nhe-1)*dhe));
    /* aperture */

    nm = nhe*nxs*nt;
    nd = nh*nxm*nt;

    /* Allocate 3-D array for the convenience of inversion with regularization */
    cmp = sf_floatalloc(nd);
    csp = sf_floatalloc(nm);

    if (verb) sf_warning("Memory needs: %f G (%f M)", 4.*(nm+nd)/1024./1024./1024., 
              4.*(nm+nd)/1024./1024);
    if (verb) sf_warning("The aperture is %f", apt);

    sf_floatread(cmp,nd,in);

    if (verb) sf_warning("Inversion to CSP...");

    sf_cdstep_init();

    csp2d_init(ompnth,ompchunk,nhe,dhe,he0,nxs,dxs,xs0,nh,dh,h0,nxm,dxm,xm0,nt,dt,t0,apt,v,
               weight, linear,half,verb);


    if (reg) {
       if (!sf_getint("nv",&nv)) sf_error("No nv in parameters");
       /* scanning velocity number */
       if (!sf_getfloat("dv",&dv)) sf_error("No dv in parameters");
       /* scanning velocity increment */
       if (!sf_getfloat("ov",&ov)) sf_error("No ov in parameters");
       /* scanning velocity origin */

       if (!sf_getfloat("eps",&eps)) eps=0.01;
       /* penalty parameter */

       radon2d_init(ompnth,ompchunk,nxs,nt,t0,dt,nhe,he0,dhe,nv,ov,dv,half,verb);

       if (sparse) {
          int miter;
          float *w;
          if (!sf_getint("miter",&miter)) sf_error("No miter in parameters");
          /* number of nonlinear iteration */
          w = sf_floatalloc(nm);
          for (int im=0; im < nm; im++) w[im] = 1.f;
          for (int iter=0; iter < miter; iter++) {
              //sf_solver_reg(csp2d_lop,sf_cdstep,radon2d_lop,nxs*nv*nt,nm,nd,
              //      csp,cmp,niter,0.01,"nmem",0,"nfreq",niter,"err",error,"mwt", w,"end");
              for (int im=0; im < nm; im++) w[im] = fabsf(csp[im]);
          }

       } else {
         sf_solver_reg(csp2d_lop,sf_cdstep,radon2d_lop,nxs*nv*nt,nm,nd,
                    csp,cmp,niter,eps,"nmem",0,"nfreq",niter,"err",error,"end");
       }
    } else {
      sf_solver(csp2d_lop,sf_cdstep,nm,nd,csp,cmp,
                niter,"nmem",0,"nfreq",niter,"err",error,"end");
    }

    sf_cdstep_close();

    sf_floatwrite(csp,nm,out);

    if (NULL != err) {
       for (int iter=1; iter < niter; iter++) error[iter] /= error[0];
       error[0] = 1.;
       sf_floatwrite(error,niter,err);
    }

    exit(0);

}