% least squares fit to synthetic data
z = sort(random('Uniform',zmin,zmax,N,1));
dobs = a+b*z+random('Normal',0,sigmad,N,1);
covm = sigmad2 * inv(GTG);
fprintf('Estimated solution:\n');
fprintf('m1: %.2f +/- %.2f (95%%)', mest(1), 2*sqrt(covm(1,1)));
fprintf('m2: %.2f +/- %.2f (95%%)', mest(2), 2*sqrt(covm(2,2)));
[emax, iemax] = max(abs(e));
% plot of data & straight line fit
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z, dobs, 'ro', 'LineWidth', 2);
plot( z, dpre, 'b-', 'LineWidth', 2);
% plot illustrating definition of prediction error
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z(i), dobs(i), 'ro', 'LineWidth', 2);
plot( z, dpre, 'b-', 'LineWidth', 2);
plot( [z(i), z(i)]', [pdmin, dpre(i)]', 'k:', 'LineWidth', 2);
plot( [zmin, z(i)]', [dpre(i), dpre(i)]', 'k:', 'LineWidth', 2);
plot( [zmin, z(i)]', [dobs(i), dobs(i)]', 'k:', 'LineWidth', 2);
fprintf('Caption: (left) Observed data (circles) and predicted data (blue).\n');
Caption: (left) Observed data (circles) and predicted data (blue).
fprintf('(right) depiction of one predicted datum correponding to a single\n');
(right) depiction of one predicted datum correponding to a single
fprintf('observed datum (red).\n');
e = random('Uniform',-1,1,N,1);
% variery of powers of errors
fprintf('Errors E1 %f E2 %f E10 %f\n', E1, E2, E10);
Errors E1 16.971244 E2 4.119617 E10 1.097731
axis( [zmin, zmax, pemin, pemax ]' );
plot( [z(i), z(i), z(i+1), z(i+1) ]', [0, e(i), e(i), 0]', 'k-', 'LineWidth', 2 );
plot( [zmin, zmax ]', [0, 0]', 'k-', 'LineWidth', 2 );
axis( [zmin, zmax, pemin, pemax ]' );
plot( [z(i), z(i), z(i+1), z(i+1) ]', [0, e1(i), e1(i), 0]', 'k-', 'LineWidth', 2 );
plot( [zmin, zmax ]', [0, 0]', 'k-', 'LineWidth', 2 );
axis( [zmin, zmax, pemin, pemax ]' );
plot( [z(i), z(i), z(i+1), z(i+1) ]', [0, e2(i), e2(i), 0]', 'k-', 'LineWidth', 2 );
plot( [zmin, zmax ]', [0, 0]', 'k-', 'LineWidth', 2 );
axis( [zmin, zmax, pemin, pemax ]' );
plot( [z(i), z(i), z(i+1), z(i+1) ]', [0, e10(i), e10(i), 0]', 'k-', 'LineWidth', 2 );
plot( [zmin, zmax ]', [0, 0]', 'k-', 'LineWidth', 2 );
fprintf('Caption: Comparisons of norms (top plot) Observed error, 1\n');
Caption: Comparisons of norms (top plot) Observed error, 1
fprintf('(second plot) |e|, (third plot) |e|^2, (fourth plot) |e|^10.');
(second plot) |e|, (third plot) |e|^2, (fourth plot) |e|^10.
% Ln fits of straight line to to synthetic data, via grid search.
z = sort(random('Uniform',zmin,zmax,N,1));
dobs = a+b*z+random('Normal',0,sd,N,1);
dobs(N)=random('uniform',0,dobs(N),1,1);
% grid (a=intercept, b=slope)
% populate grid with errors
Einf(i,j)=sum(abse.^20); % cheating; using large but finite power
% Important! Examine the error surface to make sure that
% the minimum is within the grid!
gda_draw(log10(E1),'caption L1',' ',log10(E2), 'caption L2',' ',log10(Einf),'caption Linf');
fprintf('Caption: Error surfaces (left) L1 norm, (middle) L2 norm, (right0 Linf norm.\n');
Caption: Error surfaces (left) L1 norm, (middle) L2 norm, (right0 Linf norm.
[Einfmin, cinf] = min(Ep);
% write our intecept & slope
fprintf('Solution (intercept a and slope b)\n');
Solution (intercept a and slope b)
fprintf('True: a %.3f b %.3f\n', a, b );
fprintf('L1: a %.3f b %.3f\n', a1, b1 );
fprintf('L2: a %.3f b %.3f\n', a2, b2 );
fprintf('Linf: a %.3f b %.3f\n', ainf, binf );
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z, dobs, 'ko', 'LineWidth', 2);
plot( z, dpre1, 'r-', 'LineWidth', 2);
plot( z, dpre2, 'g-', 'LineWidth', 2);
plot( z, dpreinf, 'b-', 'LineWidth', 2);
fprintf('Caption: Straight line fits to observed data (circles), showing\n');
Caption: Straight line fits to observed data (circles), showing
fprintf('L1 fit (red), L2 fit (green), Linf fit (blue).\n');
L1 fit (red), L2 fit (green), Linf fit (blue).
% Kepler's 3rd law example, period^2 = radius^3
D=load('../data/planetary.txt');
radius=D(:,1)/1e9; % work in units of 10^9 km
period=D(:,2)/1000; % and units of 10^3 days
% take radius^2 to be the observation
% and period to be the auxillary variable
% (which is ok, since time can be measured so accurately)
% predicted solutiona nd its error
sigmad2 = e'*e / (N-M); % posterior variance of data
fprintf('Estimated solution:\n');
fprintf('m1 %f +1 %f (95%)\n', mest(1), 2*sqrt(covm(1,1)));
m1 -0.025331 +1 0.091256 (95
fprintf('m2 %f +1 %f (95%)\n', mest(2), 2*sqrt(covm(2,2)));
m2 0.009980 +1 0.008962 (95
fprintf('m3 %f +1 %f (95%)\n', mest(3), 2*sqrt(covm(3,3)));
m3 0.024996 +1 0.000105 (95
% plot smooth parabola, so use lots of z's
deval=mest(1)+mest(2)*zeval+mest(3)*zeval.^2;
axis( [0, 100, 0, 250 ]');
plot(z,dobs,'ro','LineWidth',3);
plot(zeval,deval,'k-','LineWidth',3);
ylabel('radius^3, Tm^3');
axis( [0, 100, -0.5, 0.5 ]');
plot(z,e,'ro','LineWidth',3);
plot( [0, 100], [0, 0], 'k-','LineWidth',2);
fprintf('Caption: Kepler''s third law example. (Top) Observed data (red)\n');
Caption: Kepler's third law example. (Top) Observed data (red)
fprintf('least squares fit (black). (Bottom) Prediction error (red).')
least squares fit (black). (Bottom) Prediction error (red).
% planar fit to depths of earthquakes in the Kurile subduction zone
D=load('../data/kurile_eqs.txt');
x = 111.12*cos((pi/180)*mean(lat))*(lon-min(lon));
y = 111.12*(lat-min(lat));
% use rotate button to examine it prom different perspectives!
axis( [pxmin, pxmax, pymin, pymax, pzmin, pzmax]' );
plot3(x,y,dobs,'ko','LineWidth',2);
plot3( [pxmin,pxmin], [pymin,pymin], [pzmin,pzmax], 'k-', 'LineWidth', 2 );
plot3( [pxmin,pxmin], [pymin,pymax], [pzmin,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmin,pxmax], [pymin,pymin], [pzmin,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmax], [pymax,pymax], [pzmax,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmax], [pymax,pymin], [pzmax,pzmax], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmin], [pymax,pymax], [pzmax,pzmax], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmin], [pymin,pymin], [pzmax,pzmax], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmax], [pymin,pymin], [pzmax,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmin,pxmin], [pymax,pymin], [pzmax,pzmax], 'k-', 'LineWidth', 2 );
plot3( [pxmin,pxmin], [pymax,pymax], [pzmax,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmax], [pymax,pymin], [pzmin,pzmin], 'k-', 'LineWidth', 2 );
plot3( [pxmax,pxmin], [pymax,pymax], [pzmin,pzmin], 'k-', 'LineWidth', 2 );
% solve inverse problem of fitting a plane to data
GTG = G'*G; % Gram matrix
mest = GTG\(G'*dobs); % least squres solution
dpre=G*mest; % predicted data
e = dobs-dpre; % prediction error
sigmad2 = e'*e/(N-M); % posterior variance of data
covm = sigmad2*inv(GTG); % covariance of solution
fprintf('Estimated solution:\n');
fprintf('m1 %f +1 %f (95%)\n', mest(1), 2*sqrt(covm(1,1)));
m1 -94.887492 +1 5.932558 (95
fprintf('m2 %f +1 %f (95%)\n', mest(2), 2*sqrt(covm(2,2)));
m2 0.659768 +1 0.022970 (95
fprintf('m3 %f +1 %f (95%)\n', mest(3), 2*sqrt(covm(3,3)));
m3 -0.657462 +1 0.020261 (95
% display fit as mesh in 3D space
xx=pxmin+(pxmax-pxmin)*[0:M-1]'/(M-1);
yy=pymin+(pymax-pymin)*[0:M-1]'/(M-1);
Z = mest(1)+mest(2)*X+mest(3)*Y;
if ( (Z(i,j)>0) || (Z(i,j)<pzmin) )
fprintf('Caption: Subdiction zone earthquake locations (black), best-fitting\n');
Caption: Subdiction zone earthquake locations (black), best-fitting
fprintf('planar surface (colored mesh).\n');
planar surface (colored mesh).
% Least squares estimation of layer interface
% properties from reflection coefficient data
% note that this version used functions to simplicy
% the structure of the code. In MATLAB, a function
% "myfcn" that takes arguments A and B are returns
% values C=2A and D=2B is codes as follows
% function [C,D] = myfcn(A,B)
% q=theta is the angle of incidence
a = 5000; % compressional velocity
b = 3000; % shear velocity
Dror = 0.07; % normalized jump in compressional velocity
Daoa = 0.10; % normalized jump in shear velocity
Dbob = 0.11; % normalized jump in density velocity
mtrue = [Dror, Daoa, Dbob]'; % group into model parameters
% loop over angle of incidence
N=4*Nq; % number of data, 4 reflection coefficients times Nq angles
M=3; % number of model parameters
G = zeros( N, M ); % initialize data kernel
% Reflection coefficients for an incident P wave
% I have coded them in a function, because they are messy
[ PDPUr, PDPUa, PDPUb, PDSUr, PDSUa, PDSUb ] = gda_PD( q(iq), r, a, b );
PDPU = PDPUr*Dror + PDPUa*Daoa + PDPUb*Dbob;
PDSU = PDSUr*Dror + PDSUa*Daoa + PDSUb*Dbob;
% Reflection coefficients for an incident S wave
% I have coded them in a function, because they are messy
[ SDPUr, SDPUa, SDPUb, SDSUr, SDSUa, SDSUb ] = gda_SD( q(iq), r, a, b );
SDPU = SDPUr*Dror + SDPUa*Daoa + SDPUb*Dbob;
SDSU = SDSUr*Dror + SDSUa*Daoa + SDSUb*Dbob;
G(iq,:) = [PDPUr, PDPUa, PDPUb];
G(iq+Nq,:) = [PDSUr, PDSUa, PDSUb];
G(iq+2*Nq,:) = [SDPUr, SDPUa, SDPUb];
G(iq+3*Nq,:) = [SDSUr, SDSUa, SDSUb];
% true reflection coefficients
% plot the reflection coefficents as a function of angle
axis( [qmin, qmax, -0.1, 0.1] );
plot( [qmin, qmax]', [0,0]', 'k:', 'LineWidth', 2 );
plot( q, dtrue(1:Nq), 'k-', 'LineWidth', 3 );
plot( q, dtrue(1+Nq:2*Nq), 'r-', 'LineWidth', 3 );
plot( q, dtrue(1+2*Nq:3*Nq), 'g-', 'LineWidth', 3 );
plot( q, dtrue(1+3*Nq:4*Nq), 'b-', 'LineWidth', 3 );
% make synthetic noisy data and plot it
dobs = dtrue + random('Normal',0,sigmad,N,1);
plot( q, dobs(1:Nq), 'k-', 'LineWidth', 2 );
plot( q, dobs(1+Nq:2*Nq), 'r-', 'LineWidth', 2 );
plot( q, dobs(1+2*Nq:3*Nq), 'g-', 'LineWidth', 2 );
plot( q, dobs(1+3*Nq:4*Nq), 'b-', 'LineWidth', 2 );
% least squares estimate of the layer interface properties
sigmadest = sqrt(sigmadest2);
fprintf('sigmad true %.4f est %.4f\n', sigmad, sigmadest);
sigmad true 0.0050 est 0.0051
covm = (sigmadest2)*GTGinv; % covariance of the estimates
fprintf('%.5f %.5f %.5f\n', covm(1,1), covm(1,2), covm(1,3) );
0.00007 -0.00007 -0.00008
fprintf('%.5f %.5f %.5f\n', covm(2,1), covm(2,2), covm(2,3) );
fprintf('%.5f %.5f %.5f\n', covm(3,1), covm(3,2), covm(3,3) );
sigmam1 = sqrt(covm(1,1));
sigmam2 = sqrt(covm(2,2));
sigmam3 = sqrt(covm(3,3));
fprintf('m1: true %.2f est %.2f +/- %.2f (95%%)\n', mtrue(1), mest(1), 2*sigmam1 );
m1: true 0.07 est 0.06 +/- 0.02 (95%)
fprintf('m2: true %.2f est %.2f +/- %.2f (95%%)\n', mtrue(2), mest(2), 2*sigmam2 );
m2: true 0.10 est 0.11 +/- 0.02 (95%)
fprintf('m3: true %.2f est %.2f +/- %.2f (95%%)\n', mtrue(3), mest(3), 2*sigmam3 );
m3: true 0.11 est 0.12 +/- 0.02 (95%)
plot( q, dpre(1:Nq), 'ko', 'LineWidth', 2 );
plot( q, dpre(1+Nq:2*Nq), 'ro', 'LineWidth', 2 );
plot( q, dpre(1+2*Nq:3*Nq), 'go', 'LineWidth', 2 );
plot( q, dpre(1+3*Nq:4*Nq), 'bo', 'LineWidth', 2 );
fprintf('Caption: Reflection coefficients PDPU (black), PDSU (red), SDPU (green) and SDSU (blue),\n');
Caption: Reflection coefficients PDPU (black), PDSU (red), SDPU (green) and SDSU (blue),
fprintf(' with true data (bold curves), observed data (dots) and predicted data (thin curves).\n');
with true data (bold curves), observed data (dots) and predicted data (thin curves).
plot( [0, 1]', [mtrue(1),mtrue(1)]', 'k-', 'LineWidth', 5 );
plot( [0, 1]', [mest(1),mest(1)]', 'r-', 'LineWidth', 3 );
plot( [0.5, 0.5]', [mest(1)-2*sigmam1,mest(1)+2*sigmam1]', 'r-', 'LineWidth', 3 );
ylabel('density perturbation');
plot( [0, 1]', [mtrue(2),mtrue(2)]', 'k-', 'LineWidth', 5 );
plot( [0, 1]', [mest(2),mest(2)]', 'r-', 'LineWidth', 3 );
plot( [0.5, 0.5]', [mest(2)-2*sigmam2,mest(2)+2*sigmam2]', 'r-', 'LineWidth', 3 );
ylabel('compressional velocity perturbation');
plot( [0, 1]', [mtrue(3),mtrue(3)]', 'k-', 'LineWidth', 5 );
plot( [0, 1]', [mest(3),mest(3)]', 'r-', 'LineWidth', 3 );
plot( [0.5, 0.5]', [mest(3)-2*sigmam3,mest(3)+2*sigmam3]', 'r-', 'LineWidth', 3 );
ylabel('shear velocity perturbation');
fprintf('Caption: (Left) Density perturbation, (middle) compressional velocity perturbation\n');
Caption: (Left) Density perturbation, (middle) compressional velocity perturbation
fprintf('and (right) shear velocity perturbation, showing true values (black), predicted\n');
and (right) shear velocity perturbation, showing true values (black), predicted
fprintf('values with 95 percent confidence interval (red).')
values with 95 percent confidence interval (red).
% sparse matrix and bicg() solver for 5x5 anti-identity matrix
% this uses the Generalized Least Squares (GLS) formalism
% in which the NxM data kernel, G, is the top part of the
% LxM GLS matrix, F. However, in this case, there is no
% global variable for sparse version of F
P=P+1; % increment element number
Fc(P,1)=j; % column index
mtrue = [1, 2, 3, 4, 5]';
dtrue = [5, 4, 3, 2 ,1]';
% observed data is true data
fprintf('element arrays of size P=%d\n',P);
element arrays of size P=5
fprintf('%d %.0f %.0f %.3f\n', i, Fr(i,1), Fc(i,1), Fv(i,1) );
end
1 1 5 1.000
2 2 4 1.000
3 3 3 1.000
4 4 2 1.000
5 5 1 1.000
Fr=Fr(1:P); Fc=Fc(1:P); Fv=Fv(1:P); % truncate
gdaFsparse = sparse(Fr,Fc,Fv,L,M); % build sparse matrix
clear Fr Fc Fv; % delete no longer needed arrays
% print F (huge gyrations to print a nice rectangular block!)
str = sprintf('%2.0f ', F(i,j) );
end
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
0 1 0 0 0
1 0 0 0 0
maxit = 3*(M+N); % maximum number of iterations allowed
mest=bicg(@gda_FTFmul,FTf,tol ,maxit);
bicg converged at iteration 1 to a solution with relative residual 0.
fprintf('i mtrue mest\n');
fprintf('%d %.2f %.2f\n', i, mtrue(i), mest(i) );
end
1 1.00 1.00
2 2.00 2.00
3 3.00 3.00
4 4.00 4.00
5 5.00 5.00
% sparse matrix and bicg() solver for case where number of
% non-zero elements on a row of F is unknown.
% this uses the Generalized Least Squares (GLS) formalism
% in which the NxM data kernel, G, is the top part of the
% LxM GLS matrix, F. However, in this case, there is no
% global variable for sparse version of F
Frow = zeros(M,1); % i-th row of F
% now set elements of Frow here
% I cooked up a case where F is an
% identity matrix except that 1 or 2
% randomly-chosen elements of each row
% have been overwritten by a random value
kk = randi(M); % randonm integer
v = randn(); % random value
% now extract non-zero values from Frow
P=P+1; % increment element number
Fc(P,1)=j; % column index
Fv(P,1)=Frow(j,1); % value
fprintf('element arrays of size P=%d\n',P);
element arrays of size P=11
fprintf('%d %.0f %.0f %.3f\n', i, Fr(i,1), Fc(i,1), Fv(i,1) );
end
1 1 1 1.000
2 1 3 -2.486
3 1 4 -2.192
4 2 2 1.000
5 2 3 -0.948
% delete unused parts of arrays
gdaFsparse = sparse(Fr,Fc,Fv,L,M); % build sparse array
clear Fr Fc Fv; % delete no longer needed arrays
% print F (huge gyrations to print a nice rectangular block!)
str = sprintf('%2.0f ', F(i,j) );
end
1 0 -2 -2 0
0 1 -1 0 0
0 0 1 0 1
0 0 0 1 -0
0 0 0 0 -2
mtrue = [1, 2, 3, 4, 5]';
dtrue = gdaFsparse*mtrue;
% observed data is true data
maxit = 3*(M+N); % maximum number of iterations allowed
mest=bicg(@gda_FTFmul,FTf,tol ,maxit);
bicg converged at iteration 5 to a solution with relative residual 9.7e-13.
fprintf('i mtrue mest\n');
fprintf('%d %.2f %.2f\n', i, mtrue(i), mest(i) );
end
1 1.00 1.00
2 2.00 2.00
3 3.00 3.00
4 4.00 4.00
5 5.00 5.00
% least squares fit to synthetic data
% using two solution methods
% this uses the Generalized Least Squares (GLS) formalism
% in which the NxM data kernel, G, is the top part of the
% LxM GLS matrix, F. However, in this case, there is no
% global variable for sparse version of F
z = sort(random('Uniform',zmin,zmax,N,1));
dobs = a+b*z+random('Normal',0,sd,N,1);
% standard matrix solution
mest1 = (G'*G)\(G'*dobs);
P=P+1; % increment element number
Fc(P,1)=j; % column index
P=P+1; % increment element number
Fc(P,1)=j; % column index
fprintf('element arrays of size P=%d\n',P);
element arrays of size P=60
fprintf('%d %.0f %.0f %.3f\n', i, Fr(i,1), Fc(i,1), Fv(i,1) );
end
1 1 1 1.000
2 1 2 0.155
3 2 1 1.000
4 2 2 0.527
5 3 1 1.000
6 3 2 0.605
7 4 1 1.000
8 4 2 1.062
9 5 1 1.000
10 5 2 1.332
11 6 1 1.000
12 6 2 1.672
13 7 1 1.000
14 7 2 1.734
15 8 1 1.000
16 8 2 1.981
17 9 1 1.000
18 9 2 2.691
19 10 1 1.000
20 10 2 2.920
21 11 1 1.000
22 11 2 3.395
23 12 1 1.000
24 12 2 3.724
25 13 1 1.000
26 13 2 3.909
27 14 1 1.000
28 14 2 3.993
29 15 1 1.000
30 15 2 4.168
% delete unused parts of arrays
gdaFsparse = sparse(Fr,Fc,Fv,L,M);
clear Fr Fc Fv; % delete no longer needed arrays
% print F (huge gyrations to print a nice rectangular block!)
str = sprintf('%2.0f ', F(i,j) );
end
1 0
1 1
1 1
1 1
1 1
1 2
1 2
1 2
1 3
1 3
1 3
1 4
1 4
1 4
1 4
1 4
1 4
1 4
1 5
1 5
1 5
1 6
1 7
1 7
1 8
1 8
1 9
1 9
1 10
1 10
maxit = 3*(M+N); % maximum number of iterations allowed
mest2=bicg(@gda_FTFmul,FTf,tol,maxit);
bicg converged at iteration 2 to a solution with relative residual 1.2e-14.
fprintf('i mtrue mest1 mest2\n');
fprintf('%d %.2f %.2f %.2f\n', i, mtrue(i), mest1(i), mest2(i) );
end
1 2.00 2.35 2.35
2 1.00 0.92 0.92
dpre2 = gdaFsparse*mest2;
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z, dobs, 'ko', 'LineWidth', 2);
plot( z, dpre1, 'r-', 'LineWidth', 3);
plot( z, dpre2, 'g--', 'LineWidth', 2);
fprintf('Caption: Data, with observed (circles), predicted (non-sparse method)\n');
Caption: Data, with observed (circles), predicted (non-sparse method)
fprintf('(red), prediced (sparse methid) (green)\n');
(red), prediced (sparse methid) (green)
% example of data smoothing and gap filling with
% weighted damped least squares
% global variable for sparse version of F
% the data is a sinusoid in an auxillary varible z;
z = Dz*[0:M-1]'; % z is an auxiallty variable
mtrue = sin( 3*pi*z/zmax );
% Evaluate sine wave at the following randomly-chosen z indices
index = [1, unidrnd(M,1,floor(M/2)),M]';
% observed data is sinusoid plus random noise
dobs = sin( 3*pi*zobs/zmax ) + random('Normal',0,sigmad,N,1);
% PART 1: First derivative smoothing
% the N data equations are just m = dobs. The only trick is lining
% up the corresponding elements of m and dobs, since they are not of
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j; % column index
f(nr,1) = dobs(i,1); % r.h.s. is data
% now implement 1st derivative flatness constraints but the last m
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j; % column index
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j+1; % column index
f(nr,1) = 0.0; % r.h.s. is data
fprintf('First-derivative smoothng\n');
First-derivative smoothng
fprintf('Expected P=%d elements, got %d\n', N+2*(M-1), P);
Expected P=252 elements, got 252
fprintf('Expected L=%d rows, got %d\n', N+M-1, nr);
Expected L=152 rows, got 152
Fr=Fr(1:P); % truncate to actual length
gdaFsparse = sparse(Fr,Fc,Fv,L,M);
clear Fr Fc Fv; % delete no longer needed arrays
% least squares solution, using bicg()
maxit = 3*(M+N); % maximum number of iterations allowed
mest=bicg(@gda_FTFmul,FTf,tol ,maxit);
bicg converged at iteration 72 to a solution with relative residual 8.3e-13.
set(gca,'LineWidth',2);set(gca,'LineWidth',3);
set(gca,'FontSize',14);hold on;
axis( [0, zmax, -1.1, 1.1 ] );
plot( z, mtrue, 'r-', 'LineWidth', 4 );
plot( z, mest, 'g-', 'LineWidth', 3 );
plot( zobs, dobs, 'ko', 'LineWidth', 2 );
fprintf('Caption: First derivative smoothing. True solution (red), estimated\n');
Caption: First derivative smoothing. True solution (red), estimated
fprintf('solution (green), observed data (black)\n');
solution (green), observed data (black)
% PART 2: Second derivative smoothing
Pmax = L*3*(M-2)+2*2+100;
% the N data equations are just m = dobs. The only trick is lining
% up the corresponding elements of m and dobs, since they are not of
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j; % column index
f(nr,1) = dobs(i,1); % r.h.s. is data
% now implement 2nd derivative smoothness constraints in the
% interior of m (that makes M-2 rows)
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j; % column index
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j+1; % column index
Fv(P,1) = -2.0*rDz2; % value
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = j+2; % column index
f(nr,1) = 0.0; % r.h.s. is data
% now implement 1st derivative smoothness constraints at the
% ends of m (that makes 2 rows)
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = 1; % column index
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = 2; % column index
nr=nr+1; % increment row counter
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = M-1; % column index
P=P+1; % increment element number
Fr(P,1) = nr; % row index
Fc(P,1) = M; % column index
fprintf('Second-derivative smoothng\n');
Second-derivative smoothng
fprintf('Expected P=%d elements, got %d\n', N+3*(M-2)+2*2, P);
Expected P=353 elements, got 353
fprintf('Expected L=%d rows, got %d\n', N+M, nr);
Expected L=153 rows, got 153
gdaFsparse = sparse(Fr,Fc,Fv,L,M);
clear Fr Fc Fv; % delete no longer needed arrays
% least squares solution, using bicg()
maxit = 3*(M+N); % maximum number of iterations allowed
mest=bicg(@gda_FTFmul,FTf,tol,maxit);
bicg converged at iteration 123 to a solution with relative residual 6.4e-13.
set(gca,'LineWidth',2);set(gca,'LineWidth',3);
set(gca,'FontSize',14);hold on;
axis( [0, zmax, -1.1, 1.1 ] );
plot( z, mtrue, 'r-', 'LineWidth', 4 );
plot( z, mest, 'g-', 'LineWidth', 3 );
plot( zobs, dobs, 'ko', 'LineWidth', 2 );
fprintf('Caption: Second derivative smoothing. True solution (red), estimated\n');
Caption: Second derivative smoothing. True solution (red), estimated
fprintf('solution (green), observed data (black)\n');
solution (green), observed data (black)
% gdama04_12 Example of smoothing operators
% using the formula of Menke and Eilon (2015)
set( gca, 'LineWidth', 3);
m1 = (epi/2)*exp(-epi*abs(x));
axis( [x(1), x(end), -1.1*amp, 1.1*amp ] );
plot( [x(1), x(end)]', [0,0]', 'b:', 'LineWidth', 3 );
plot( x, m1, 'k-', 'LineWidth', 3 );
m1 = (epi/2)*exp(-epi*abs(x));
plot( x, m1, 'r-', 'LineWidth', 3 );
set( gca, 'LineWidth', 3);
m2 = V*exp(-abs(x)/a).*(cos(abs(x)/a)+sin(abs(x)/a));
axis( [x(1), x(end), -1.1*amp, 1.1*amp ] );
plot( [x(1), x(end)]', [0,0]', 'b:', 'LineWidth', 3 );
plot( x, m2, 'k-', 'LineWidth', 3 );
m2 = V*exp(-abs(x)/a).*(cos(abs(x)/a)+sin(abs(x)/a));
plot( x, m2, 'r-', 'LineWidth', 3 );
fprintf('Caption: Smoothing operators. (Top) First derivative, showing narrow (black)\n');
Caption: Smoothing operators. (Top) First derivative, showing narrow (black)
fprintf('wide (red). (Bottom) Second derivative, showing narrow (black) and wide (red).\n');
wide (red). (Bottom) Second derivative, showing narrow (black) and wide (red).
% constrained least squares fit to synthetic data
z = sort(random('Uniform',zmin,zmax,N,1));
dobs = a+b*z+random('Normal',0,sd,N,1);
% constrained least squares fit
A = [ [G'*G, F']', [F, 0]' ];
[emax, iemax] = max(abs(e));
% plot observed and presicted data, constained point
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z, dobs, 'ro', 'LineWidth', 2);
plot( zp, dp, 'bo', 'LineWidth', 4);
plot( z, dpre, 'g-', 'LineWidth', 2);
fprintf('Caption: Constrained least squares. Observed data (red), predicted data (green),\n');
Caption: Constrained least squares. Observed data (red), predicted data (green),
fprintf('constraint (blue)');
% Weighted least squares fit as a check.
% The idea is to set the weight on the
% prior information to a very large number
% so that it functions as a hard constraint.
mest2 = (FF'*FF)\(FF'*ff);
axis( [zmin, zmax, pdmin, pdmax ]' );
plot( z, dobs, 'ro', 'LineWidth', 2);
plot( zp, dp, 'bo', 'LineWidth', 4);
plot( z, dpre, 'g-', 'LineWidth', 3);
plot( z, dpre2, 'y--', 'LineWidth', 1);
fprintf('Caption: Weighted least squares (with strong weighting). Observed data (red),\n');
Caption: Weighted least squares (with strong weighting). Observed data (red),
fprintf('predicted data (green), predicted data from weighted soln (yelloe), constraint (blue)');
predicted data (green), predicted data from weighted soln (yelloe), constraint (blue)
% Explicit version of solution
disp('comparison with explicit solution');
comparison with explicit solution
disp('mest mex mest-mes');
disp(D);
3.8226 3.8226 -0.0000
0.2722 0.2722 0.0000
% two examples of variance
% number of model parameters = number of model data
% 1: sum of first K blocks
% 2: sum of pairs of blocks
G1=toeplitz( ones(N,1), [1, zeros(1,N-1)] );
G2=toeplitz( [1, 1, zeros(1, N-2)]', [1, zeros(1,N-1)] );
% synthetic observed data
d1obs = d1true + random('Normal',0,sd,N,1);
d2obs = d2true + random('Normal',0,sd,N,1);
% least squares solutions
m1est = (G1'*G1)\(G1'*d1obs);
m2est = (G2'*G2)\(G2'*d2obs);
C1 = (sd^2) * inv(G1'*G1);
C2 = (sd^2) * inv(G2'*G2);
axis( [zmin, zmax, pmmin, pmmax ]' );
plot( z, mtrue, 'k-', 'LineWidth', 2 );
plot( [zmin, zmax ]', [0, 0]', 'k-', 'LineWidth', 2 );
plot( z, m2est, 'b-', 'LineWidth', 3 );
plot( z, m1est, 'k-', 'LineWidth', 3 );
plot( z, m1est, 'r-', 'LineWidth', 3 );
axis( [zmin, zmax, psmin, psmax ]' );
plot( z, sm1, 'r-', 'LineWidth', 3 );
plot( z, sm2, 'b-', 'LineWidth', 3 );
fprintf('Caption (Top) Predicted models 1 (red) and blue (2). (Bottom) Posterior\n');
Caption (Top) Predicted models 1 (red) and blue (2). (Bottom) Posterior
fprintf('variance of model 1 (red) and 2 (blue)\n');
variance of model 1 (red) and 2 (blue)
% Examine error surface of intercept and slope in a straight
% line fit to synthetic data
z = sort(random('Uniform',zmin,zmax,N,1));
% PART 1: data evenly spread along interval
dobs = a+b*z+random('Normal',0,sd,N,1);
% populate grid with errors
disp('case 1: data straddles origin');
case 1: data straddles origin
fprintf(' method 1: sm1 %f sm2 %f cov %f\n', sqrt(C1(1,1)), sqrt(C1(2,2)), C1(1,2) );
method 1: sm1 0.093704 sm2 0.035093 cov -0.000369
% curvature of error surface formula
d2Eda2 = (EA(r1+j,c1)-2*EA(r1,c1)+EA(r1-j,c1))/((j*Da)^2);
d2Edb2 = (EA(r1,c1+j)-2*EA(r1,c1)+EA(r1,c1-j))/((j*Db)^2);
d2Edadb = (EA(r1+j,c1+j)-EA(r1+j,c1-j)-EA(r1-j,c1+j)+EA(r1-j,c1-j))/(4*j*Da*j*Db);
fprintf(' method 2: sm1 %f sm2 %f cov %f\n', sqrt(C2(1,1)), sqrt(C2(2,2)), C2(1,2) );
method 2: sm1 0.093704 sm2 0.035093 cov -0.000369
axis( [zmin, zmax, -10, 10] );
plot( z, dobs, 'ro', 'LineWidth', 3);
plot( z, dpre, 'b-', 'LineWidth', 2);
axis( [bmin, bmax, amin, amax] );
imagesc( [bmin, bmax], [amin, amax], EA );
plot( b1, a1, 'wo', 'LineWidth', 2);
DeltaE=(EAmax-EAmin)/100;
contour(X,Y,EA,[EAmin+DeltaE, EAmin+DeltaE],'w-','LineWidth',3);
% PART 2: data bunched up at end of interval
z = sort(random('Uniform',zmin+1*(zmax-zmin)/2,zmax,N,1));
dobs = a+b*z+random('Normal',0,sd,N,1);
% populate grid with errors
disp('case 2: data to one side of origin');
case 2: data to one side of origin
fprintf(' method 1: sm1 %f sm2 %f cov %f\n', sqrt(C1(1,1)), sqrt(C1(2,2)), C1(1,2) );
method 1: sm1 0.228829 sm2 0.068425 cov -0.014358
% curvature of error surface formula
d2Eda2 = (EB(r1+j,c1)-2*EB(r1,c1)+EB(r1-j,c1))/((j*Da)^2);
d2Edb2 = (EB(r1,c1+j)-2*EB(r1,c1)+EB(r1,c1-j))/((j*Db)^2);
d2Edadb = (EB(r1+j,c1+j)-EB(r1+j,c1-j)-EB(r1-j,c1+j)+EB(r1-j,c1-j))/(4*j*Da*j*Db);
fprintf(' method 2: sm1 %f sm2 %f cov %f\n', sqrt(C2(1,1)), sqrt(C2(2,2)), C2(1,2) );
method 2: sm1 0.228829 sm2 0.068425 cov -0.014358
axis( [zmin, zmax, -10, 10] );
plot( z, dobs, 'ro', 'LineWidth', 3);
plot( z, dpre, 'b-', 'LineWidth', 2);
fprintf('Caption: Linear fit (blue) to data (red). (left) Full dataset. (Right) data for z>0, ony')
Caption: Linear fit (blue) to data (red). (left) Full dataset. (Right) data for z>0, ony
axis( [bmin, bmax, amin, amax] );
imagesc( [bmin, bmax], [amin, amax], EB );
plot( b1, a1, 'wo', 'LineWidth', 2);
% note: use same DeltaE as previous plot
contour(X,Y,EB,[EBmin+DeltaE, EBmin+DeltaE],'w-','LineWidth',3);
fprintf('Caption: Linear fit (blue) to data (red). (left) Error surface of full dataset.\n');
Caption: Linear fit (blue) to data (red). (left) Error surface of full dataset.
fprintf('(Right) Errpr for data with z>0, only');
(Right) Errpr for data with z>0, only