Ejemplo n.º 1
0
int main (int argc,char* argv[]) 
{
    int b1, b2, b3, n1, n2, n3, i, nshot, ndim, is,order,n123, *p;
    float br1, br2, br3, o1, o2, o3, d1, d2, d3, slow;
    float **s, *t, *v;
    char *sfile;
    bool isvel, sweep, plane[3];
    sf_file vel, time, shots;

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

    if (SF_FLOAT != sf_gettype(vel)) 
	sf_error("Need float input");
    if(!sf_histint(vel,"n1",&n1)) sf_error("No n1= in input");
    if(!sf_histint(vel,"n2",&n2)) sf_error("No n2= in input");
    if(!sf_histint(vel,"n3",&n3)) n3=1;

    if(!sf_histfloat(vel,"d1",&d1)) sf_error("No d1= in input");
    if(!sf_histfloat(vel,"d2",&d2)) sf_error("No d2= in input");
    if(!sf_histfloat(vel,"d3",&d3)) d3=d2;

    if(!sf_histfloat(vel,"o1",&o1)) o1=0.;
    if(!sf_histfloat(vel,"o2",&o2)) o2=0.;
    if(!sf_histfloat(vel,"o3",&o3)) o3=0.;

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

    if(!sf_getint("order",&order)) order=2;
    /* [1,2] Accuracy order */

    if (!sf_getbool("sweep",&sweep)) sweep=false;
    /* if y, use fast sweeping instead of fast marching */

    if(!sf_getfloat("br1",&br1)) br1=d1;    
    if(!sf_getfloat("br2",&br2)) br2=d2; 
    if(!sf_getfloat("br3",&br3)) br3=d3;
    /* Constant-velocity box around the source (in physical dimensions) */
 
    if(!sf_getbool("plane1",&plane[2])) plane[2]=false;
    if(!sf_getbool("plane2",&plane[1])) plane[1]=false;
    if(!sf_getbool("plane3",&plane[0])) plane[0]=false;
    /* plane-wave source */

    if(!sf_getint("b1",&b1)) b1= plane[2]? n1: (int) (br1/d1+0.5); 
    if(!sf_getint("b2",&b2)) b2= plane[1]? n2: (int) (br2/d2+0.5); 
    if(!sf_getint("b3",&b3)) b3= plane[0]? n3: (int) (br3/d3+0.5); 
    /* Constant-velocity box around the source (in samples) */

    if( b1<1 ) b1=1;  
    if( b2<1 ) b2=1;  
    if( b3<1 ) b3=1;

    sfile = sf_getstring("shotfile");
    /* File with shot locations (n2=number of shots, n1=3) */

    if(NULL != sfile) {
	shots = sf_input("shotfile");

	if (SF_FLOAT != sf_gettype(shots)) 
	    sf_error("Need float shotfile");
	if(!sf_histint(shots,"n2",&nshot)) 
	    sf_error("No n2= in shotfile");
	if(!sf_histint(shots,"n1",&ndim) || ndim != 3) 
	    sf_error("Need n1=3 in shotfile");
  
	s = sf_floatalloc2 (ndim,nshot);
	sf_floatread(s[0],nshot*ndim,shots);
	sf_fileclose(shots);
    
	sf_putint (time,"n4",nshot);
	free (sfile);
    } else {
	nshot = 1;
	ndim = 3;
    
	s = sf_floatalloc2 (ndim,nshot);     

	if(!sf_getfloat("zshot",&s[0][0])  ) s[0][0]=0.; 
	/* Shot location (used if no shotfile) */
	if(!sf_getfloat("yshot",&s[0][1])) s[0][1]=o2 + 0.5*(n2-1)*d2;
	if(!sf_getfloat("xshot",&s[0][2])) s[0][2]=o3 + 0.5*(n3-1)*d3;

	sf_warning("Shooting from zshot=%g yshot=%g xshot=%g",
		   s[0][0],s[0][1],s[0][2]);
    }

    n123 = n1*n2*n3;

    t  = sf_floatalloc (n123);
    v  = sf_floatalloc (n123);
    p  = sf_intalloc   (n123);

    sf_floatread(v,n123,vel);
    if (isvel) {
	/* transform velocity to slowness squared */
	for(i = 0; i < n123; i++) {
	    slow = v[i];
	    v[i] = 1./(slow*slow);
	}
    } 
    
    if (!sweep) fastmarch_init (n3,n2,n1);
 
    /* loop over shots */
    for( is = 0; is < nshot; is++) {
	sf_warning("shot %d of %d;",is+1,nshot);
	if (sweep) {
	    continue;
	} else {
	    fastmarch(t,v,p, plane,
		      n3,n2,n1,
		      o3,o2,o1,
		      d3,d2,d1,
		      s[is][2],s[is][1],s[is][0], 
		      b3,b2,b1,
		      order);
	}	

	sf_floatwrite (t,n123,time);
    }
    sf_warning(".");

    exit (0);
}
Ejemplo n.º 2
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.º 3
0
int main(int argc, char* argv[])
{
    bool velocity;
    int dim, i, n[3], it, nt, order, j;
    float d[3], o[3], thres;
    float *s, *t0, *x0;
    int *f0;
    char key[3];
    sf_file in, out, ot0=NULL, ox0=NULL, of0=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, inputs are velocity / n, slowness-squared */

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

    /* allocate temporary memory */
    t0 = sf_floatalloc(nt);
    x0 = sf_floatalloc(nt);
    f0 = sf_intalloc(nt);

    /* output transformation matrix */
    if (NULL != sf_getstring("t0"))
	ot0 = sf_output("t0");
    if (NULL != sf_getstring("x0"))
	ox0 = sf_output("x0");

    /* output upwind neighbor */
    if (NULL != sf_getstring("f0")) {
	of0 = sf_output("f0");
	sf_settype(of0,SF_INT);
    }

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

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

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

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

    /* write output */
    sf_floatwrite(s,nt,out);
    if (NULL!=ot0) sf_floatwrite(t0,nt,ot0);
    if (NULL!=ox0) sf_floatwrite(x0,nt,ox0);

    /* caustic region (2D) */
    for (i=0; i < n[0]; i++) {
	for (j=0; j < n[1]; j++) {
	    if (j > 0) {
		if (x0[j*n[0]+i] <= x0[(j-1)*n[0]+i]) {
		    f0[j*n[0]+i] = 0;
		    continue;
		}
		if ((x0[j*n[0]+i]-x0[(j-1)*n[0]+i]) > thres*d[1]) {
		    f0[j*n[0]+i] = 0;
		    continue;
		}
	    }
	    if (j < n[1]-1) {
		if (x0[(j+1)*n[0]+i] <= x0[j*n[0]+i]) {
		    f0[j*n[0]+i] = 0;
		    continue;
		}
		if ((x0[(j+1)*n[0]+i]-x0[j*n[0]+i]) > thres*d[1]) {
		    f0[j*n[0]+i] = 0;
		    continue;
		}
	    }
	}
    }

    /* write flag */
    if (NULL!=of0) sf_intwrite(f0,nt,of0);

    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[]) 
{
    float xmin;
    char *method, meth;
    sf_file fv=NULL,fv2=NULL,fx=NULL,ft=NULL;

    sf_init(argc,argv);
    fv = sf_input("in");
    fv2 = sf_output("out");
    fx = sf_output("x0");
    ft = sf_output("t0");

    if (SF_FLOAT != sf_gettype(fv)) sf_error("Need float input");
    if (!sf_histint(fv,"n1",&nx)) sf_error("No n1= in input");
    if (!sf_histint(fv,"n2",&nt)) sf_error("No n2= in input");

    if (!sf_histfloat(fv,"d1",&hx)) sf_error("No d1= in input");
    if (!sf_histfloat(fv,"d2",&ht)) sf_error("No d2= in input");
    ht /= 2; /* convert to one-way traveltime */

    if (!sf_getint("nz",&nz)) sf_error("Need nz=");
    if (!sf_getfloat("dz",&hz)) sf_error("Need dz=");

    sf_putint(fv2,"n2",nz);
    sf_putfloat(fv2,"d2",hz);
    sf_putfloat(fv2,"o2",0.);

    sf_putint(fx,"n2",nz);
    sf_putfloat(fx,"d2",hz);
    sf_putfloat(fx,"o2",0.);

    sf_putint(ft,"n2",nz);
    sf_putfloat(ft,"d2",hz);
    sf_putfloat(ft,"o2",0.);

    if (NULL == (method = sf_getstring("method"))) method="lf";
    /* method (chebyshev,lax-friedrichs) */
    meth = method[0];

    if ('c'==meth) {
	if (!sf_getint("nc",&nc)) nc=100;
	/* number of chebyshev coefficients */
	if (nc > NC) sf_error("nc must be smaller than %d",NC);
	if (!sf_getint("neval",&neval)) neval=20;
	/* numvber of used chebyshev coefficients */
    }

    nxt=nx*nt;
    nxz=nx*nz;

    nx1=nx-1;
    nx2=nx-2;

    nz1=nz-1;
    nt1=nt-1;

    xmax = nx1*hx;
    xmin = 0.;

    bma=0.5*(xmax-xmin);
    bpa=0.5*(xmax+xmin);

    dx=0.1*hx;
    dz=0.1*hz;
 
    f= sf_floatalloc(nxt);
    x0= sf_floatalloc(nxz);
    t0= sf_floatalloc(nxz);
    v= sf_floatalloc(nxz);
    s= sf_floatalloc(nxt); 
    q= sf_floatalloc(nxt);

    if ('c'==meth) {
	g= sf_floatalloc(nt*NC);
	fc= sf_floatalloc(nt*NC);
	y= sf_floatalloc(nt*NC);
    } else {
	g= sf_floatalloc(nxt);
	fc= NULL;
	y= NULL;
    } 

    sf_floatread(f,nxt,fv);

    /* three parts of the algorithm */
    init(meth);

    if ('c'==meth) {
	qp_cheb();
    } else {
	qp_lf();
    }

    fastmarch();

    sf_floatwrite(v,nxz,fv2);
    sf_floatwrite(x0,nxz,fx);
    sf_floatwrite(t0,nxz,ft);


    exit(0);
}