static void init(char meth) { int i,j,ind; for( i=0;i<nx;i++ ) { *(x0+i)=i*hx; *(t0+i)=0.0; *(v+i)=(*(f+i)); *(s+i)=1/(*(f+i)); *(q+i)=1.0; ind=i; for( j=1;j<nz;j++ ) { ind+=nx; *(x0+ind)=0.0; *(t0+ind)=INFTY; *(v+ind)=0.0; } for( j=1;j<nt;j++ ){ ind=i+j*nx; *(q+ind)=1.0; } } if ('c'==meth) chebyshev_init(); fastmarch_init(nx,nz,nt, hx,hz,ht, x0,t0,v,s); }
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); }
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); }
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); }
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); }