void mis2(int niter /* number of iterations */, int nx /* model size */, float *xx /* model */, sf_filter aa /* helix filter */, const bool *known /* mask for known data */, float eps /* regularization parameter */, bool doprec /* to apply preconditioning */) /*< interpolate >*/ { int ix; float *dd; if (doprec) { /* preconditioned */ sf_mask_init(known); sf_polydiv_init(nx, aa); sf_solver_prec(sf_mask_lop, sf_cgstep, sf_polydiv_lop, nx, nx, nx, xx, xx, niter, eps, "end"); sf_polydiv_close(); } else { /* regularized */ dd = sf_floatalloc(nx); for (ix=0; ix < nx; ix++) { dd[ix]=0.; } sf_helicon_init(aa); sf_solver (sf_helicon_lop, sf_cgstep, nx, nx, xx, dd, niter, "known", known, "x0", xx, "end"); free(dd); } sf_cgstep_close(); }
float wilson2_factor(int niter /* number of iterations */, float s0 /* zero-lag auto-correlation */, sf_filter ss /* input auto-correlation */, float a0 /* zero-lag filter */, sf_filter aa /* output factor */, bool verb /* verbosity flag */, float tol /* tolerance */) /*< Factor >*/ { float g0, *gg; int i, iter; for(i=0; i < n2; i++) { au[i] = 0.; } sf_helicon_init( aa); /* multiply polynoms */ sf_polydiv_init( n2, aa); /* divide polynoms */ au[n-1] = -a0*a0; sf_helicon_lop(false, false, n2, n2, au, bb); sf_helicon_lop(true, false, n2, n2, au, bb); au[n-1] += s0; for(i=0; i < ss->nh; i++) { /* symmetrize input auto */ au[n-1+ss->lag[i]] += ss->flt[i]; au[n-1-ss->lag[i]] += ss->flt[i]; } g0 = a0; gg = sf_floatalloc(aa->nh); for(i=0; i < aa->nh; i++) { gg[i] = aa->flt[i]; } for(iter=0; iter < niter; iter++) { sf_polydiv_lop(false,false, n2, n2, au, bb); /* bb = S/A */ sf_polydiv_lop(true, false, n2, n2, cc, bb); /* cc = S/(AA') */ /* b = plusside(cc) */ for(i=0; i < n; i++) { b[i] = 0.5*(cc[n-1+i] + cc[n-1-i])/a0; } sf_helicon_lop( false, false, n, n, b, c); /* c = A b */ a0 = 2.*(c[0]+g0); for(i=0; i < aa->nh; i++) { /* put on helix */ aa->flt[i] = 2.*(c[aa->lag[i]]+gg[i])/a0; } } a0 -= g0; for(i=0; i < aa->nh; i++) { aa->flt[i] = ((a0+g0)*aa->flt[i]-gg[i])/a0; } return a0; }
void signoi_lop (bool adj, bool add, int n1, int n2, float *data, float *sign) /*< linear operator >*/ { sf_helicon_init (nn); sf_polydiv_init (nd, ss); sf_adjnull(adj,add,n1,n2,data,sign); sf_helicon_lop (false, false, n1, n1, data, dd); sf_solver_prec(sf_helicon_lop, sf_cgstep, sf_polydiv_lop, nd, nd, nd, sign, dd, niter, eps, "verb", verb, "end"); sf_cgstep_close(); nn++; ss++; }
void laplacian_init(int type1 /* operator type */, int nz, int nx /* dimensions */, float dz, float dx /* sampling */, float **vt1 /* [nx][nz] (v*t)^2 */) /*< initialize >*/ { int i; float s1, s2, b0; const float tol=1.e-6; sf_filter ss, bb; type = type1; n1 = nz; n2 = nx; n12 = n1*n2; d1 = 1./(dz*dz); d2 = 1./(dx*dx); switch(type) { case 0: center = -2.0*(d1+d2); break; case 1: corner = (d1+d2)/12.0; s1 = (5*d1-d2)/6.0; s2 = (5*d2-d1)/6.0; d1 = s1; d2 = s2; center = -2.0*(2.0*corner+d1+d2); break; case 2: tri1 = sf_tridiagonal_init(n1); sf_tridiagonal_const_define(tri1,10.0/(12.0*d1),1.0/(12.0*d1),false); work1 = sf_floatalloc(n1); tri2 = sf_tridiagonal_init(n2); sf_tridiagonal_const_define(tri2,10.0/(12.0*d2),1.0/(12.0*d2),false); work2 = sf_floatalloc(n2); break; case 3: corner = 3.0*(d1/d2+d2/d1); ss = sf_allocatehelix(4); ss->flt[0] = ss->flt[2] = (10.0 + corner)/144.0; ss->flt[1] = ss->flt[3] = (2 - corner)/288.0; ss->lag[0] = 1; ss->lag[1] = n1-1; ss->lag[2] = n1; ss->lag[3] = n1+1; bb = sf_allocatehelix(n1+1); for (i=0; i <= n1; i++) { bb->lag[i] = i+1; bb->flt[i] = 0.0; } wilson_init(n1*10); b0 = wilson_factor(100, (50.0 - corner)/72.0, ss, bb, true, tol); wilson_close(); sf_deallocatehelix(ss); bb = compress(bb,tol); sf_warning("nb=%d",bb->nh); work1 = sf_floatalloc(n12); corner = (d1+d2)/(12.0*b0*b0); s1 = (5*d1-d2)/(6.0*b0*b0); s2 = (5*d2-d1)/(6.0*b0*b0); d1 = s1; d2 = s2; center = -2.0*(2.0*corner+d1+d2); sf_polydiv_init(n1*n2,bb); break; case 4: dd1 = -d1/12.0; dd2 = -d2/12.0; d1 *= 4.0/3.0; d2 *= 4.0/3.0; center = -2.0*(d1+d2+dd1+dd2); break; case 5: vt = vt1; break; default: sf_error("%s: Unknown Laplacian type",__FILE__); } }