% apply Pavlis and Booker (1980) variable partitioning
% method to a simple inverse problem, randomly generated
% The script shows that the solution to the partitioned
% problem is the same as to the unpartitioned problem.
G=random('uniform',0,1,N,M); % random data kernel
mtrue=random('uniform',-1,1,M,1); % random true model parameters
dtrue=G*mtrue; % true data
dobs=dtrue; % no noise in this problem, so error should be zero
% some solution statistics
fprintf('Prediction error of full inverse problem: %f\n', E );
Prediction error of full inverse problem: 0.000000
fprintf('Distance between full and true solutions: %f\n', L );
Distance between full and true solutions: 0.000000
% divide model parameters into two groups m=[m1',m2']'
% svd of first data kernel
LAMBDAp=LAMBDA(1:M1,1:M1);
% first partitioned problem, Gp*m2=dp
m2est = (Gp'*Gp)\(Gp'*dp);
% second partitioned problem, Gpp*m1=dpp
dpp = Up'*(dobs-G2*m2est);
m1est = (Gpp'*Gpp)\(Gpp'*dpp);
% some solution statistics
d12pre=G1*m1est+G2*m2est;
fprintf('Prediction error of partitioned inverse problem: %f\n', E12 );
Prediction error of partitioned inverse problem: 0.000000
m12est = [m1est', m2est']';
fprintf('Distance between partitioned and true solutions: %f\n', L12 );
Distance between partitioned and true solutions: 0.000000
% Partial derivative of wavefield error for the
% acoustic case using adjoint methods.
% mycase controls time of error, 1, 2, 3 allowed
% must be run for each case to produce sequence of
t0 = tmin + (tmax-tmin)/10;
% source time function is Gaussian curve
fS = exp( -0.1*(t-t0).^2 );
% distance and traveltime from Source to Receiver
RSR = sqrt( (xS-xR)^2 + (yS-yR)^2 );
% distance and traveltime from Source to Heterogenety
RSH = sqrt( (xS-xH)^2 + (yS-yH)^2 );
% distance and traveltime from Heterogenety to Receiver
RHR = sqrt( (xH-xR)^2 + (yH-yR)^2 );
% reference field at the receiver
uR(nSR+1:Nt) = fS(1:Nt-nSR)/(4*pi*RSR);
% waveform error, a gaussian pulse at time te
e = e + Ae*exp( -0.4*(t-te).^2 );
% second derivative of error
edd(2:Nt-1) = (e(1:Nt-2)-2*e(2:Nt-1)+e(3:Nt))/(Dt^2);
% plot source time function
axis( [tmin, tmax, -1.25, 1.25] );
plot( t, fS/max(abs(fS)), 'k-', 'LineWidth', 2 );
% plot reference wavefield at heterogeneity
fH(nSH+1:Nt) = fS(1:Nt-nSH)/(4*pi*RSH);
axis( [tmin, tmax, -1.25, 1.25] );
plot( t, fH/max(abs(fH)), 'k-', 'LineWidth', 2 );
axis( [tmin, tmax, -1.25, 1.25] );
plot( t, e/max(abs(e)), 'k-', 'LineWidth', 2 );
% plot second derivarive of error at heterogeneity
eddH(1:Nt-nHR) = edd(nHR+1:Nt);
% plot reference wavefield and error at heterogeneity
axis( [tmin, tmax, -1.25, 1.25] );
plot( t, a, 'k-', 'LineWidth', 2 );
plot( t, b, 'r-', 'LineWidth', 2 );
fprintf('Caption: (Top) Source time function fS. (2nd) Reference wavefield\n');
Caption: (Top) Source time function fS. (2nd) Reference wavefield
fprintf('at heterogeneity fH. (3rd) Wavefield error at receiver eR. (Bottom)\n');
at heterogeneity fH. (3rd) Wavefield error at receiver eR. (Bottom)
fprintf('Reference wavefield (fH, black) and second derivative of wavefield error\n');
Reference wavefield (fH, black) and second derivative of wavefield error
fprintf('at heterogeneity (eddH, red)\n');
at heterogeneity (eddH, red)
% tabulate dEdm on 2D grid
% source to heterogeneity parameters
RSh = sqrt( (xS-xh)^2 + (yS-yh)^2 + Dx^2);
% heterogeneity to receiver parameters
RhR = sqrt( (xR-xh)^2 + (yR-yh)^2 + Dx^2);
a(NSh+1:Nt) = fS(1:Nt-NSh)/(4*pi*RSh);
b(1:Nt-NhR) = 4*s0*edd(NhR+1:Nt)/(4*pi*RhR);
% correlate the two wavefields
d(ix,iy) = sum( a .* b );
% plot 2D inage of dEdm with source, heterogeneity,
% receiver positions superimposed
axis( [xmin, xmax, ymin, ymax] );
plot( yS, xS, 'ko', 'LineWIdth', 4 );
plot( yR, xR, 'ko', 'LineWIdth', 4 );
plot( yH, xH, 'ro', 'LineWIdth', 4 );
fprintf('Caption: The derivtive dEdm as a function of position (x,y),\n');
Caption: The derivtive dEdm as a function of position (x,y),
fprintf('with source and receiver (blavk circles) and heterogenity (red circle)\n');
with source and receiver (blavk circles) and heterogenity (red circle)
fprintf('superimposed.\n');
% seismic migration in a medium with a uniform
% reference slowness s0, and with a reference
% (unperturbed) wavefield that is a downgoing
% Note: This script uses a function gda_delay()
% that is not desribed in the text (sorry about
% that) that delays a time series by a given amount.
% It is roughly equivalent to the MatLab function
% circshift(), except that it allows delays that
% are non-integral multiples of the sampling interval
% Dt. It uses a Fourier technique.
% axes setup. Note: Although the calulations
% are for a plane wave that starts at z=0 and
% advances in the positive z direction, I plot
% eveything upside down so that it looks "downgoing"
% sampling Dt depends on sampling Dz
% in order to prevent singularities, geometrical
% spreading 1/R is replaced with 1/(R+epsi)
% source time function is a Gaussian pulse
p = exp( -((t-t0).^2)/(2*sigmat*sigmat) );
pdd = [0;diff(p,2);0]; % first derivative
pdd = (0.1/(4*pi))*pdd/max(pdd); % second derivative
% unperturbed plane wave pulse on the grid
tau0 = s0*(z(iz)-zmin); % phase delay for a plane wave
% note that pwave wave experiences no geometerical spreading
% array of stations (receivers), all at zmin
tau0 = s0*(zs-zmin); % delay of planewave down to scatterer
R=sqrt(((x(ix)-xs)^2)+((z(iz)-zs)^2));
Ri = 1/(R+epsi); % fudged geometrical spreading
dtau = s0*R; % delay of scattered wave
tau1 = dtau+tau0; % total delay
d=gda_delay(pdd,Dt,tau1);
axis( [xmin, xmax, zmin, zmax] );
imagesc([xmin, xmax], [zmax, zmin], u0(:,:,it)+du(:,:,it), [-1, 1]);
plot(xs,zmax-zs,'wo','LineWidth',3);
plot(x(istas), zmax-0, 'k^', 'LineWidth', 2 );
axis( [xmin, xmax, zmin, zmax] );
imagesc([xmin, xmax], [zmax, zmin], u0(:,:,it)+du(:,:,it), [-1, 1]);
plot(xs,zmax-zs,'wo','LineWidth',3);
plot(x(istas), zmax-0, 'k^', 'LineWidth', 2 );
axis( [xmin, xmax, zmin, zmax] );
imagesc([xmin, xmax], [zmax, zmin], u0(:,:,it)+du(:,:,it), [-1, 1]);
plot(xs,zmax-zs,'wo','LineWidth',3);
plot(x(istas), zmax-0, 'k^', 'LineWidth', 2 );
axis( [xmin, xmax, zmin, zmax] );
imagesc([xmin, xmax], [zmax, zmin], u0(:,:,it)+du(:,:,it), [-1, 1]);
plot(xs,zmax-zs,'wo','LineWidth',3);
plot(x(istas), zmax-0, 'k^', 'LineWidth', 2 );
fprintf('Caption: Plot of wavefield\n');
Caption: Plot of wavefield
% plot record section on surface
axis( [xmin, xmax, 0, tp] );
imagesc([xmin, xmax], [0, tp], squeeze(u0(1,:,1:itp)+du(1,:,1:itp))', [-1, 1]);
fprintf('Caption: record section on z=0 surface\n');
Caption: record section on z=0 surface
for ixr = istas' % for each receiver on surface
xr = x(ixr); % receiver position
dub = zeros(Nz,Nx,Nt); % wavefield at receiver
a = squeeze(du(1,ixr,:)); % reduce to vector
for iz = (1:Nz) % back-propagate to each gridpoint
R=sqrt(((x(ix)-xr)^2)+((z(iz)-zr)^2)); % distance
Ri = 1/(R+epsi); % fudged geometrical spreading
taub = -s0*R; % time advance
dub(iz,ix,:)=d*(4*pi*Ri); % for this observation
dubT=dubT+dub; % stack all observations
for iz = (1:Nz) % each gridpoint
a = squeeze(u0(iz,ix,:)); % reduce to vector
add = [0;diff(a,2);0]; % 2nd derivative
b = squeeze(dubT(iz,ix,:)); % reduce to vector
c(iz,ix)=add'*b; % correlate (= dot product)
axis( [xmin, xmax, zmin, zmax] );
imagesc([xmin, xmax], [zmax, zmin], c/cmax, [-1, 1]);
plot(x(istas), zmax-0, 'k^', 'LineWidth', 2 );
fprintf('Caption: Plot of correlation (migrated record section)\n');
Caption: Plot of correlation (migrated record section)
% How much does a small secondary pulse near a main pulse
% affect differential traveltime as determined by cross
% correlation? Both timeseries are bandpass filtered before
% cross correlation. Calculation is performed both by brute
% force and Marquering et al (1999) formula
% Note: This script uses a function gda_timedelay() that is
% not described in the text (sorry about that) that does a
% standard cross-correlation to find the delay between two
% signals, and then refines that delay by fitting a parabola
% to the peak of the cross-correlation and finding the
% peak in the parabola. This process allows the delay to
% be estimated to a resolution much better than 1Dt (often
% several orders of magnitude better).
% Note: This script uses a function gda_chebyshevfilt() that is
% not described in the text (sorry about that) to bandpass
% narrow bandpass frequencies
pulsesize = 0.2; % secondary pulse size (main pulse is 1)
Na = floor(5*N/16); % left limit of secondary pulse position
Nb = floor(11*N/16); % left limit of secondary pulse position
% reference signal u0 has just one main pulse
u0f = gda_chebyshevfilt(u0, Dt, flow, fhigh); % bandpass filter
ilist = [Na:10:Nb]'; % times at which delay is calculated
ilist2 = [Na:100:Nb]'; % times at which time series is plotted
tpulse = zeros(Nlist,1); % save calculation in array
axis( [10, 35, -1, 10] );
for i=ilist' % loop over pulse positions
% another signal u has two pulses
duf = gda_chebyshevfilt(du, Dt, flow, fhigh); % band pass filtered perturbation
uf = u0f + duf; % bandpass filtered signal
if( ~isempty(find(ilist2==i,1)) )
plot( t, 100*uf+0.06*j, 'k-', 'LineWidth', 2 );
% brute force calculation of the delay by
% cross-correlation followed by parabolic refinement
% see the comments in gda_timedelay() for details.
[ tBmA_est, Cmax_est ] = gda_timedelay( u0f, uf, Dt );
% formula from Marquering et al, GJI 137, 805-815, 1999
u0fd = [diff(u0f); 0]/Dt; % 1st derivative
u0fdd = [0; diff(u0f,2); 0]/(Dt^2); % 2nd derivative
tau2(j) = (Dt*u0fd'*duf)/(Dt*u0fdd'*u0f);
fprintf('Caption: Series of time series with a reference pulse (large) all with the same start\n');
Caption: Series of time series with a reference pulse (large) all with the same start
fprintf('time and smaller perturbation pulses with different start times\n');
time and smaller perturbation pulses with different start times
fprintf('amplitude %.3f lowpass %.3f highpass %.3f\n', pulsesize, flow, fhigh);
amplitude 0.200 lowpass 0.200 highpass 0.300
axis( [ta-t0, tb-t0, (ta-t0)/scale, (tb-t0)/scale] );
plot( [0,0]', [(ta-t0)/scale, (tb-t0)/scale]', 'b:', 'LineWidth', 2 );
plot( [ta-t0, tb-t0]', [0,0]', 'b:', 'LineWidth', 2 );
xlabel('secondary pulse position (s)');
ylabel('perturbation in arrival time');
plot( tpulse, tau, 'k-', 'LineWidth', 3);
plot( tpulse, tau2, 'r-', 'LineWidth', 2);
fprintf('Caption: Delay associated with small perturbation pulse, calculated using\n');
Caption: Delay associated with small perturbation pulse, calculated using
fprintf('cross-correlation (black) and pertubative formula (red)\n');
cross-correlation (black) and pertubative formula (red)
% bannana-doughnut kernel for the acoustic case4
Nt = 2*Nx*SSF; % number of times depends on number of x's
Dt = 1/SSF; % time sampling depends on spatial sampling
t0 = tmin + (tmax-tmin)/2;
% define three frequency bands, one for each case
w0 = [0.005*wny; 0.025*wny; 0.1*wny];
% loop over three cases of finite frequencies
fprintf('Frequenvcy band %d: w0: %f\n', iw, w0(iw) );
% a band-limited source time function
fS = sinc(2*w0(iw)*(t-t0)) - sinc(0.5*w0(iw)*(t-t0));
% d/dt of source time function
fSd(1:Nt-1) = (fS(2:Nt)-fS(1:Nt-1))/(Dt);
% d2/dt2 of source time function
fSdd(2:Nt-1) = (fS(1:Nt-2)-2*fS(2:Nt-1)+fS(3:Nt))/(Dt^2);
% Source to Receiver distance and time
RSR = sqrt( (xS-xR)^2 + (yS-yR)^2 );
D = - (1/(4*pi*RSR)^2) * Dt * sum( fSd .^ 2 );
d = zeros(Nx,Ny); % the kernel on the (x,y) plane
for ix = (1:Nx) % loop over x
for iy = (1:Ny) % loop over y
% location of heterogeneity
% Source to heterogenity distance and time
RSh = sqrt( (xS-xh)^2 + (yS-yh)^2 );
% heterogenity to receiver distance and time
RhR = sqrt( (xR-xh)^2 + (yR-yh)^2 );
NShR = floor((TSh+ThR-TSR)/Dt);
c = 4*pi*RSR * 4*pi*(RSh+Dx) * 4*pi*(RhR+Dx);
% note, the Dx is a kludge to prevent singularies
a(1:Nt-NShR) = fSd(NShR+1:Nt);
% second derivative of reference field
% kernel is an inner product of a and b
d(ix,iy) = (2*s0*D)*Dt*sum( a .* b )/c;
axis( [xmin, xmax, ymin, ymax] );
dabsmax = max(abs(d(:)))/3;
imagesc(d, [-dabsmax, dabsmax]);
plot( yS, xS, 'ko', 'LineWidth', 4 );
plot( yR, xR, 'ko', 'LineWidth', 4 );
fprintf('Caption: Bannana-doughnut kernel for a frequency %d\n',iw);
axis( [tmin, tmax, -1.1*max(abs(fS)), 1.1*max(abs(fS))] );
plot( t, fS, 'k-', 'LineWidth', 2 );
fprintf('Caption: Source wavelet for frequency %d\n',iw);
end
Frequenvcy band 1: w0: 0.157080

Caption: Bannana-doughnut kernel for a frequency 1

Caption: Source wavelet for frequency 1
Frequenvcy band 2: w0: 0.785398

Caption: Bannana-doughnut kernel for a frequency 2

Caption: Source wavelet for frequency 2
Frequenvcy band 3: w0: 3.141593

Caption: Bannana-doughnut kernel for a frequency 3

Caption: Source wavelet for frequency 3