void stretch_lop (bool adj /* adjoint flag */, bool add /* addition flag */, int n1, int n2, /* sizes */ float *ord /* data [nd] */, float *modl /* model [nt] */) /*< apply interpolation >*/ { int id, i1, i2; float w1, w2; if (n1 != nd || n2 != nt) sf_error("%s: wrong sizes",__FILE__); sf_adjnull(adj,add,nd,nt,ord,modl); for (id = 0; id < nd; id++) { if (m[id]) continue; i1 = x[id]; i2 = i1 + 1; w2 = w[id]; w1 = 1.0f - w2; if (adj) { ord[id] += w2 * modl[i2] + w1 * modl[i1]; } else { modl[i1] += w1 * ord[id]; modl[i2] += w2 * ord[id]; } } }
void tomo2_lop (bool adj, bool add, int nm, int ny, float* x, float* ord) { int ir, id, i0, j0, i, j, im; float w; if (ny != nr) sf_error("%s: wrong dimensions: %d != %d",__FILE__,ny,nr); sf_adjnull (adj,add,nm,nd,x,ord); for (ir = 0; ir < nr; ir++) { nd = rl[ir]; for (id=0; id < nd; id++) { if (mask[ir][id]) continue; i0 = nxy[ir][id][0]; j0 = nxy[ir][id][1]; for (j = MAX(0,-j0); j < MIN(nf,m2-j0); j++) { w = w2[ir][id][j]; for (i = MAX(0,-i0); i < MIN(nf,m1-i0); i++) { im = (i+i0) + (j+j0)*m1; if( adj) { x[im] += ord[ir] * w * w1[ir][id][i]; } else { ord[ir] += x[im] * w * w1[ir][id][i]; } } } } } }
void allp_lop (bool adj, bool add, int nx, int ny, float* xx, float* yy) { int i1, i2, iw, is, i; float a[7]; sf_adjnull (adj, add, nx, ny, xx, yy); for (i2=0; i2 < n2-1; i2++) { for (i1 = nw*nj; i1 < n1-nw*nj; i1++) { i = i1 + i2*n1; passfilter(nw, pp[i2][i1], a); for (iw = 0; iw <= 2*nw; iw++) { is = (iw-nw)*nj; if (adj) { xx[i+is+n1] += yy[i] * a[iw]; xx[i-is] -= yy[i] * a[iw]; } else { yy[i] += (xx[i+is+n1] - xx[i-is]) * a[iw]; } } } } }
void sf_polydiv_lop( bool adj, bool add, int nx, int ny, float* xx, float*yy) /*< linear operator >*/ { int ia, iy, ix; sf_adjnull( adj, add, nx, ny, xx, yy); for (ix=0; ix < nx; ix++) tt[ix] = 0.; if (adj) { for (ix = nx-1; ix >= 0; ix--) { tt[ix] = yy[ix]; for (ia = 0; ia < aa->nh; ia++) { iy = ix + aa->lag[ia]; if( iy >= ny) continue; tt[ix] -= aa->flt[ia] * tt[iy]; } } for (ix=0; ix < nx; ix++) xx[ix] += tt[ix]; } else { for (iy = 0; iy < ny; iy++) { tt[iy] = xx[iy]; for (ia = 0; ia < aa->nh; ia++) { ix = iy - aa->lag[ia]; if( ix < 0) continue; tt[iy] -= aa->flt[ia] * tt[ix]; } } for (iy=0; iy < ny; iy++) yy[iy] += tt[iy]; } }
void stretch4_invert (bool add /* add flag */, map4 str, float* ord /* [nd] */, float* mod /* [n1] */) /*< convert model to ordinates by spline interpolation >*/ { int id, it, i, nt, i1, i2; float *w, *mm; sf_adjnull(false,add,str->nt,str->nd,mod,ord); mm = str->diag; nt = str->nt; for (it = 0; it < nt; it++) { mm[it] = mod[it]; } sf_tridiagonal_solve(str->tslv, mm); for (id = 0; id < str->nd; id++) { if (str->m[id]) continue; it = str->x[id]; w = str->w[id]; i1 = SF_MAX(0,-it); i2 = SF_MIN(4,nt-it); for (i=i1; i < i2; i++) { ord[id] += w[i]*mm[it+i]; } } }
void dsrtomo_oper(bool adj, bool add, int nx, int nr, float *x, float *r) /*< linear operator >*/ { int i,j; sf_adjnull(adj,add,nx,nr,x,r); if (adj) { /* given dt solve dw */ /* data precon */ for (i=0; i < nn[1]*nn[2]; i++) { if (dp != NULL && dp[i] != 1) pstk[(long) i*nn[0]] = 0.; else pstk[(long) i*nn[0]] = r[i]; for (j=1; j < nn[0]; j++) pstk[(long) i*nn[0]+j] = 0.; } /* linear operator */ upgrad_inverse(upg,temp,pstk,NULL); upgrad_spread(upg,x,temp); /* model precon */ if (mp != NULL) { for (i=0; i < nn[0]*nn[1]; i++) { if (mp[i] != 1) x[i] = 0.; } } } else { /* given dw solve dt */ /* model precon */ if (mp != NULL) { for (i=0; i < nn[0]*nn[1]; i++) { if (mp[i] != 1) x[i] = 0.; } } /* linear operator */ upgrad_collect(upg,x,temp); upgrad_solve(upg,temp,pstk,NULL); /* data precon */ for (i=0; i < nn[1]*nn[2]; i++) { if (dp != NULL && dp[i] != 1) r[i] = 0.; else r[i] = pstk[(long) i*nn[0]]; } } }
static void fit(bool adj, bool add, int nm, int nd, float *m, float *d) /* L1 fitting criterion */ { sf_adjnull(adj, add, nm, nd, m, d); sf_copy_lop(adj, true, nd, nd, m, d); helix_icaf_init(mm, aa, 1); helix_icaf_lop(adj,true,aa->nh,nd,m+nd,d); }
void stretch4_apply_adj (bool add, /* add flag */ map4 str, float* ord /* [nd] */, float* mod /* [n1] */) /*< transform model to ordinates by adjoint operation >*/ { int id, it, i, nt, i1, i2; float *w, *mm, *mod2; sf_adjnull(true,add,str->nd,str->nt,ord,mod); mm = str->diag; nt = str->nt; mod2 = sf_floatalloc(nt); for (it = 0; it <= nt; it++) { mod2[it] = mod[it]; } for (it = 0; it <= str->ib; it++) { mod2[it] = 0.0f; } for (it = str->ie; it < nt; it++) { mod2[it] = 0.0f; } sf_spline4_post(nt,0,nt,mod2,mm); for (it = 0; it <= str->ib; it++) { mm[it] = 0.0f; } for (it = str->ie; it < nt; it++) { mm[it] = 0.0f; } sf_banded_solve (str->slv, mm); for (id = 0; id < str->nd; id++) { if (str->m[id]) continue; it = str->x[id]; w = str->w[id]; i1 = SF_MAX(0,-it); i2 = SF_MIN(4,nt-it); for (i=i1; i < i2; i++) { ord[id] += w[i]*mm[it+i]; } } }
void stretch4_apply (bool add /* add flag */, map4 str, float* ord /* [nd] */, float* mod /* [n1] */) /*< transform ordinates to model >*/ { int id, it, i, nt, i1, i2; float *w, *mm, *mod2; sf_adjnull(false,add,str->nd,str->nt,ord,mod); mm = str->diag; nt = str->nt; mod2 = sf_floatalloc(nt); for (it = 0; it < nt; it++) { mm[it] = 0.0f; } for (id = 0; id < str->nd; id++) { if (str->m[id]) continue; it = str->x[id]; w = str->w[id]; i1 = SF_MAX(0,-it); i2 = SF_MIN(4,nt-it); for (i=i1; i < i2; i++) { mm[it+i] += w[i]*ord[id]; } } sf_banded_solve (str->slv, mm); for (it = 0; it <= str->ib; it++) { mm[it] = 0.0f; } for (it = str->ie; it < nt; it++) { mm[it] = 0.0f; } sf_spline4_post(nt,0,nt,mm,mod2); for (it=0; it < nt; it++) { if (it > str->ib && it < str->ie) { mod[it] += mod2[it]; } } free(mod2); }
void laplac2_lop(bool adj, bool add, int np, int nr, float *p, float *r) /*< linear operator >*/ { int i1,i2,j; sf_adjnull(adj,add,np,nr,p,r); for (i2=0; i2 < n2; i2++) { for (i1=0; i1 < n1; i1++) { j = i1+i2*n1; if (i1 > 0) { if (adj) { p[j-1] -= r[j]; p[j] += r[j]; } else { r[j] += p[j] - p[j-1]; } } if (i1 < n1-1) { if (adj) { p[j+1] -= r[j]; p[j] += r[j]; } else { r[j] += p[j] - p[j+1]; } } if (i2 > 0) { if (adj) { p[j-n1] -= r[j]; p[j] += r[j]; } else { r[j] += p[j] - p[j-n1]; } } if (i2 < n2-1) { if (adj) { p[j+n1] -= r[j]; p[j] += r[j]; } else { r[j] += p[j] - p[j+n1]; } } } } }
void wavelet_lop(bool adj, bool add, int nx, int ny, float *x, float *y) /*< linear operator >*/ { int it, i, j; sf_adjnull (adj,add,nx,ny,x,y); if (adj) { for (j=0; j< scale; j++) { for(i=0; i< nx; i++) { t[j*nx+i] = y[j*nx+i]; } } if (unit) { for (it=0; it < scale*nt; it++) { if (inv) { t[it] /= w[it]; } else { t[it] *= w[it]; } } } } else { for (it=0; it < nx; it++) { t[it]=x[it]; } for (it=nx; it < nt; it++) { t[it] = 0.; } } transform(adj); if (adj) { for (it=0; it < nx; it++) { x[it] += t[it]; } } else { if (unit) { for (it=0; it < scale*nt; it++) { t[it] *= w[it]; } } for (j=0; j< scale; j++) { for(i=0; i< nx; i++) { y[j*nx+i] += t[j*nx+i]; } } } }
void matmult_lop (bool adj, bool add, int nx, int ny, float* x, float*y) /*< linear operator >*/ { int ix, iy; sf_adjnull (adj, add, nx, ny, x, y); for (ix = 0; ix < nx; ix++) { for (iy = 0; iy < ny; iy++) { if (adj) x[ix] += a[iy][ix] * y[iy]; else y[iy] += a[iy][ix] * x[ix]; } } }
static void predict_smooth_lop(bool adj, bool add, int nx, int ny, float* x, float* y) { sf_adjnull(adj,add,nx,ny,x,y); if (adj) { sf_triangle2_lop (true, false, nx, nx, t, y); predict_lop (true, add, nx, nx, x, t); } else { predict_lop (false, false, nx, nx, x, t); sf_triangle2_lop (false, add, nx, nx, t, y); } }
void predk_lop(bool adj, bool add, int nx, int ny, float* x, float* y) /*< linear operator >*/ { int i; if (nx != n*n12 || ny != nx) sf_error("%s: wrong dimensions",__FILE__); sf_adjnull(adj,add,nx,ny,x,y); for (i=0; i < n; i++) { /** loop over components **/ predict_set(p[i]); predict_lop(adj,true,n12,n12,x+i*n12,y+i*n12); } }
/*------------------------------------------------------------*/ void slant_lop (bool adj, bool add, int nm, int nd, float *modl, float *data) /*< linear operator >*/ { int ix, is, it; float x, s, sxx, t, z; if (nm != nt*ns || nd != nt*nx) sf_error("%s: wrong dimensions",__FILE__); sf_adjnull (adj, add, nm, nd, modl, data); for (is=0; is < ns; is++) { /* slowness */ s = s0 + is*ds; for (ix=0; ix < nx; ix++) { /* offset */ x = x0 + ix*dx; sxx = s*x; for (it=0; it < nt; it++) { /* time */ z = t0 + it*dt; t = pull? z + sxx: z - sxx; str[it] = t; tx[it] = anti*(s-s1); amp[it] = 1.; } /* it */ sf_aastretch_define (str, tx, amp); if (pull) { if (rho) { sf_chain(sf_halfint_lop,sf_aastretch_lop, adj,true,nt,nt,nt,modl+is*nt,data+ix*nt,tmp); } else { sf_aastretch_lop(adj,true,nt,nt,modl+is*nt,data+ix*nt); } } else { if (rho) { sf_chain(sf_aastretch_lop,sf_halfint_lop, (bool)!adj,true,nt,nt,nt,data+ix*nt,modl+is*nt,tmp); } else { sf_aastretch_lop((bool)!adj,true,nt,nt,data+ix*nt,modl+is*nt); } } } /* ix */ } /* is */ }
void sf_repeat_lop (bool adj, bool add, int nx, int ny, float *xx, float *yy) /*< combined linear operator >*/ { int i2; if (nx != ny || nx != n1*n2) sf_error("%s: Wrong size (nx=%d ny=%d n1=%d n2=%d)", __FILE__,nx,ny,n1,n2); sf_adjnull (adj, add, nx, ny, xx, yy); for (i2=0; i2 < n2; i2++) { oper(adj,true,n1,n1,xx+i2*n1,yy+i2*n1); } }
void icai1_lop (bool adj, bool add, int nx, int ny, float* xx, float* yy) /*< linear operator >*/ { int b, x, y; if(ny != nx) sf_error("%s: size problem: %d != %d",__FILE__,ny,nx); sf_adjnull (adj, add, nx, ny, xx, yy); for( b=0; b < nb; b++) { for( y = nb - lg; y <= ny - lg; y++) { x = y - b + lg - 1; if( adj) xx[x] += yy[y] * bb[b]; else yy[y] += xx[x] * bb[b]; } } }
void copy_scaled_lop(bool adj, bool add, int nx, int ny, float* xx, float* yy) /*< linear operator >*/ { int i; if (ny!=nx) sf_error("%s: size mismatch: %d != %d",__FILE__,ny,nx); sf_adjnull (adj, add, nx, ny, xx, yy); for (i=0; i < nx; i++) { if (adj) { xx[i] += yy[i] * scale; } else { yy[i] += xx[i] * scale; } } }
void hypotenusei_lop(bool adj, bool add, int n1, int n2, float *zz, float *tt) /*< linear operator >*/ { int it; sf_adjnull(adj,add,n1,n2,zz,tt); for (it=0; it < nt; it++) { if (iz[it] < 0) continue; if (adj) zz[iz[it]] += tt[it]; else tt[it] += zz[iz[it]]; } }
void pbeamform_lop(bool adj, bool add, int nc, int nd, float* c, float* d) /*< linear operator >*/ { int i1, ic, id; if (nd != n1*n2) sf_error("%s: wrong size",__FILE__); sf_adjnull(adj,add,nc,nd,c,d); if (adj) { if (gauss) { pwdsl_lop(false,false,nd,nd,d,t2); pwdsl_lop(true,false,nd,nd,t,t2); } else { pwdsl_lop(true,false,nd,nd,t,d); } for (ic=id=0; id < n2; id++) { if (0==id%rect) { for (i1=0; i1 < n1; i1++) { c[ic*n1+i1] += t[id*n1+i1]; } ic++; } } } else { for (ic=id=0; id < n2; id++) { if (0==id%rect) { for (i1=0; i1 < n1; i1++) { t[id*n1+i1] = c[ic*n1+i1]; } ic++; } else { for (i1=0; i1 < n1; i1++) { t[id*n1+i1] = 0.; } } } if (gauss) { pwdsl_lop(false,false,nd,nd,t,t2); pwdsl_lop(true,true,nd,nd,d,t2); } else { pwdsl_lop(false,true,nd,nd,t,d); } } }
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++; }
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 npolydiv_lop (bool adj, bool add, int nx, int ny, float *xx, float *yy) /*< linear operator >*/ { int id, ia, na, ix, iy, ip, *lag; float *flt; sf_adjnull(adj,add,nx,ny,xx,yy); for (id=0; id < nd; id++) { tt[id] = adj? yy[id]: xx[id]; } if (adj) { for (iy=nd-1; iy >= 0; iy--) { ip = aa->pch[iy]; lag = aa->hlx[ip]->lag; flt = aa->hlx[ip]->flt; na = aa->hlx[ip]->nh; for (ia=0; ia < na; ia++) { ix = iy - lag[ia]; if (ix < 0) continue; tt[ix] -= flt[ia] * tt[iy]; } } for (id=0; id < nd; id++) { xx[id] += tt[id]; } } else { for (iy=0; iy < nd; iy++) { ip = aa->pch[iy]; lag = aa->hlx[ip]->lag; flt = aa->hlx[ip]->flt; na = aa->hlx[ip]->nh; for (ia=0; ia < na; ia++) { ix = iy - lag[ia]; if (ix < 0) continue; tt[iy] -= flt[ia] * tt[ix]; } } for (id=0; id < nd; id++) { yy[id] += tt[id]; } } }
void rsin_destruct(bool adj, bool add, int nx, int ny, float *xx, float *yy) /*< destruction operator >*/ { int i; if (nx != ny) sf_error("%s: wrong dimensions",__FILE__); sf_adjnull(adj, add, nx, nx, xx, yy); for (i = 2; i < nx-1; i++) { if(adj) { xx[i-1] += yy[i]; xx[i+1] += yy[i]; xx[i] -= 2*c0*yy[i]; } else { yy[i] += xx[i-1] + xx[i+1] - 2*c0*xx[i]; } } }
void weight2_lop (bool adj, bool add, int nx, int ny, float* xx, float* yy) /*< linear operator >*/ { int i; if (ny!=2*nx) sf_error("%s: size mismatch: %d != 2*%d",__FILE__,ny,nx); sf_adjnull (adj, add, nx, ny, xx, yy); for (i=0; i < nx; i++) { if (adj) { xx[i] += yy[i] * w[0][i]; xx[i] += yy[i+nx] * w[1][i]; } else { yy[i] += xx[i] * w[0][i]; yy[i+nx] += xx[i] * w[1][i]; } } }
void expont_lop (bool adj, bool add, int nx, int ny, float *xx, float *yy) /*< linear operator >*/ { int it, ix, i; sf_adjnull(adj,add,nx,ny,xx,yy); for (ix=0; ix < n2; ix++) { for (it=2; it < n1; it++) { i = it + ix*n1; if (adj) { xx[i-1] -= a[i]*b[i]*yy[i]; xx[i] += 0.5*yy[i]; xx[i-2] += 0.5*b[i]*b[i]*yy[i]; } else { yy[i] += 0.5*(xx[i] + b[i]*(b[i]*xx[i-2] - 2.*a[i]*xx[i-1])); } } } }
void kirch_lop (bool adj, bool add, int nm, int nd, float *modl, float *data) /*< Simplest-form Kirchhoff operator >*/ { int im, id1, id2, ix,iz,it,ir,i; float t,t1,t2,z,b1,b2,f,g; sf_adjnull(adj,add,nm,nd,modl,data); for (iz=0; iz < nt-1; iz++) { z = t0 + dt * iz; /* vertical traveltime (t_0) */ for (ir=0; ir < nx; ir++) { /* Loop over receiver */ for (ix=0; ix < nx; ix++) { /* Loop over output trace */ b1=(ix-ir)*dx/vrms[iz]; b2=(x0+ix*dx-xs)/vrms[iz]; t1 = hypotf(0.5*z,b1); t2 = hypotf(0.5*z,b2); t=t1+t2; f = (t-t0)/dt; it = f; f = f-it; i = it+1; g = 1.-f; if(it >= nt) break; im = ix*nt+iz; id1 = ix*nt+it; id2 = ix*nt+i; if( adj) { modl[im] += data[id1]*g + data[id2]*f; } else { data[id1] += modl[im]*g; data[id2] += modl[im]*f; }/* if */ }/* ix */ }/* ib */ }/* iz */ }
void spray_lop(bool adj, bool add, int n, int nu, float* trace, float *u) /*< linear operator >*/ { int i, is, ip, i1; if (nu != n*ns2) sf_error("%s: wrong size %d != %d*%d",__FILE__,nu,n,ns2); sf_adjnull(adj,add,n,nu,trace,u); for (i=0; i < n; i++) { if (adj) { trace[i] += u[i*ns2+ns]; } else { u[i*ns2+ns] += trace[i]; } /* predict forward */ for (is=0; is < ns; is++) { ip = i-is-1; if (ip < 0) break; i1 = ip*ns2+ns-is-1; if (adj) { trace[i] += u[i1]; } else { u[i1] += trace[i]; } } /* predict backward */ for (is=0; is < ns; is++) { ip = i+is+1; if (ip >= n) break; i1 = ip*ns2+ns+is+1; if (adj) { trace[i] += u[i1]; } else { u[i1] += trace[i]; } } } }
void sf_trianglen_lop (bool adj, bool add, int nx, int ny, float* x, float* y) /*< linear operator >*/ { int i, j, i0; if (nx != ny || nx != nd) sf_error("%s: Wrong data dimensions: nx=%d, ny=%d, nd=%d", __FILE__,nx,ny,nd); sf_adjnull (adj,add,nx,ny,x,y); if (adj) { for (i=0; i < nd; i++) { tmp[i] = y[i]; } } else { for (i=0; i < nd; i++) { tmp[i] = x[i]; } } for (i=0; i < dim; i++) { if (NULL != tr[i]) { for (j=0; j < nd/n[i]; j++) { i0 = sf_first_index (i,j,dim,n,s); sf_smooth2 (tr[i], i0, s[i], false, tmp); } } } if (adj) { for (i=0; i < nd; i++) { x[i] += tmp[i]; } } else { for (i=0; i < nd; i++) { y[i] += tmp[i]; } } }
void filter_lop (bool adj, bool add, int nx, int ny, float* xx, float* yy) /*< linear operator >*/ { int i; float t; assert (ny == nx); sf_adjnull (adj, add, nx, ny, xx, yy); if (adj) { /* !!! INSERT CODE !!! */ } else { t = a*xx[0]; yy[0] += t; for (i = 1; i < nx; i++) { t = a*xx[i] + b*xx[i-1] + c*t; yy[i] += t; } } }