% upper/lower bounds on localized average using linear programming
% data kernel G composed of arithmetic average of model parameters
% data equation: mean of d
mtrue = random('Uniform',-1,1,M,1);
mtrue = mtrue - mean(mtrue);
options = optimset('linprog');
options.Display = 'off'; % this option turns off annoying messages
% averageing vector centered at N/2 of width 2*i+1
[mest1, fmin(L)] = linprog( f, [], [], G, dobs, lb, ub, options );
[mest2, fmax(L)] = linprog( -f, [], [], G, dobs, lb, ub, options );
plot(I,-fmax, 'k-', 'LineWidth', 2);
plot(I,-fmax, 'ko', 'LineWidth', 4);
ylabel('bound on |<m>|');
fprintf('Caption: Lower bound on the mean of several adacent model parameters,\n');
Caption: Lower bound on the mean of several adacent model parameters,
fprintf('as a function of the width of the averaging kernel.\n');
as a function of the width of the averaging kernel.
% upper/lower bounds on localized average using linear programming
% data kernel G composed of decaying exponentials
% model, m(z), moztly zero but a few spikes
% experiment: exponential smoothing of model
G(i,1:j)=[j:-1:1]/j+random('Normal',0,0.15,1,j);
fprintf('det %f\n',det(G*G'));
% observed data is true data plus noise
dobs = dtrue + random('Normal',0,sd,N,1);
gda_draw(dtrue,'caption d','=',G,'caption G',mtrue,'caption m');
fprintf('Caption: Graphical depiction of the equation dtrue = G mtrue\n');
Caption: Graphical depiction of the equation dtrue = G mtrue
% minimum length solution
GMG = G'/(G*G'+epsilon*eye(N,N));
% plto the true model and the minimum length estimate
axis( [zmin, zmax, pmmin, pmmax ]' );
plot( z, mtrue, 'r-', 'LineWidth', 2);
plot( z, mest, 'b-', 'LineWidth', 2);
% half width of averaging kernel
options = optimset('linprog');
options.Display = 'off'; % this option turns off annoying messages
% compute upper, lower bounds on average
% averageing vector centered at M of width w
[mest1, amin(i)] = linprog( a, [], [], G, dobs, mlb, mub, options );
[mest2, amax(i)] = linprog( -a, [], [], G, dobs, mlb, mub, options );
plot( z, amin, 'k-', 'LineWidth', 2);
plot( z, amax, 'k-', 'LineWidth', 2);
fprintf('Caption: Exemplary inverse problem with model parameters m(z), showing\n');
Caption: Exemplary inverse problem with model parameters m(z), showing
fprintf('true solution (red), damped least squares solution (blue), and\n');
true solution (red), damped least squares solution (blue), and
fprintf('upper and lower bounds (black)\n');
upper and lower bounds (black)
% The data kernel is a series of decaying exponentials in
% an auxillary variable z and is underdetermined. Three
% models, all that fit the data to similar accuracy, are
% constructed: Simple damped least squares; solution
% squeezed shallow ("up"), solution squeezed deep ("dn")
% Note: Becaue the data are noisy with noise that randomly
% varies between runs, you may have to run the scipt a few
% times until the least squares solution (black curve in
% figure 2 (top) is a good approximation to the true
% true solution is a boxcar
% data kernel is declining exponentials, normalized
% so that they compute a weighted average of the model
fprintf('Caption: Graphical depiction of the data kernel G\n');
Caption: Graphical depiction of the data kernel G
% create synthetic data by adding random noise to the
dobs = dtrue + random('Normal',0,sd,N,1);
mest0 = (G'*G + epsilon2*W)\(G'*dobs);
Ed = (dobs'*dobs); % energy in data, for comparison
% squeeze up; the weights are low to the left
% of z=zc and high to the right of it. The error
% function erf(z) ramps up smoothly from -1 for
% z<<0 to +1 for z>>0, so I can use a scaled
% and shifted version of it to achieve weights
% that smoothly ramp up/down from one constant
% value to another at the point z0. (Any
% "sigmoidal" shaped function would have sufficed;
% Matlab's sigmf() would be fine, too.
Wup = diag((B+1)+B*erf((z-zc)/A)); % weights grow with z
mest_up = (G'*G + epsilon2*Wup)\(G'*dobs);
Wdn = diag((B+1)-B*erf((z-zc)/A)); % weights decline with z
mest_dn = (G'*G + epsilon2*Wdn)\(G'*dobs);
% I have adusted all the coefficients by trial and error
% so that E0/Ed is about 10-6 (a very good fit)
% Eup/E0 and Edn/E0 are both about 1.05 (almost as good)
fprintf('Normalized error %.2e ratio: up %.3f dn %.3f\n', E0/Ed, Eup/E0, Edn/E0 );
Normalized error 4.21e-07 ratio: up 1.081 dn 1.101
% plot true and unsqueezed models
axis( [zmin, zmax, -1.2, 1.2] );
plot( [zmin, zmax]', [0, 0]', 'k:', 'LineWidth', 2 );
plot( z, mtrue, 'b-', 'LineWidth', 3 );
plot( z, mest0, 'k-', 'LineWidth', 2 );
% plot unsqueezed and squeezed models
axis( [zmin, zmax, -1.2, 1.2] );
plot( [zmin, zmax]', [0, 0]', 'k:', 'LineWidth', 2 );
plot( z, mest_up, 'r-', 'LineWidth', 2 );
plot( z, mest_dn, 'g-', 'LineWidth', 2 );
axis( [zmin, zmax, 0, 1.1*max(w)] );
plot( z, w, 'r-', 'LineWidth', 2 );
plot( z, w, 'g-', 'LineWidth', 2 );
fprintf('Caption: (Top) True solution m(z) (blue) and damped least squares solution (blue).\n');
Caption: (Top) True solution m(z) (blue) and damped least squares solution (blue).
fprintf('(Middle) Upward squeezed solution (red) and downward squeezed solution (green)\n');
(Middle) Upward squeezed solution (red) and downward squeezed solution (green)
fprintf('(Bottom) Weighting frunction for upward squeeze (green) and downward squeese (red)\n');
(Bottom) Weighting frunction for upward squeeze (green) and downward squeese (red)