That was an uggly uggly G-matrix. When solving inverse problems the truncation-point is not to be selected close to "at double-precision zero". The crucial thing to understand is why we have to truncate (or use "Tichonov-damping"). The problem is that your data will allways have some noise, and we need to control the impact of that noise in the solution. In the ideal case we have:
d_ideal = G*m_true;
[U,S,V] = svd(G);
With U and V being ortho-normal matrices spanning (parts of) the data space and model-space respectively. Therefore we can do (stepwise for clarity):
d = (U*S*V')*m_true;
m_est = V*diag(1./diag(S))*U'*d;
But since your data is not that ideal you will have:
d_ideal = G*m_true;
d_real = (U*S*V')*m_true + noise;
m_est = V*diag(1./diag(S))*U'*d_ideal + V*diag(1./diag(S))*U'*noise;
Since U is an orthonormal eigenvector matrix |U*noise| will be of similar size as |noise|, and typically also rather evenly distributed over all components (I'm not sure this is true in a mathematical sense but in my practical experience it is never much better than that). A direct consequence of this is that:
diag(1./diag(S))*(U'*noise);
leads to a signifficant amplification of noise in the components that are multiplied with the inverse of the very smallest eigenvalues. (ever in the case of no explicit noise you will never have much better relative accuracy in your data than 1e-16 due to double precision representation...)
And that's why we have to regularize.
Your script is OK, but your truncation-point is way-over-ambitious (In my (maybe not so) humble opinion). I sugegst that you do something like this:
truncSVD = @(U,S,V,p) V(:,1:p)*diag(1./diag(S(1:p,1:p)))*U(:,1:p)';
for i1 = 1:10,
m_est = truncSVD(U,S,V,i1);
ph(i1) = plot(m_est);
hold on
pause
end
Then do the same wbut add a little bit of random noise. In your very ugggly case that wont show the problem as clearly - because your eigenvalues are decreasing "rather exponentially" and are all smaller than 1 - for an inverse problem to be nice to work with at least a couple of eigenvalues should be larger than 1 or at least of similar amplitude, then above that number they can start to fall off and you'll have your truncation point. Condition-number of the un-regularized forward matrix is not all that informative, but in this case you will have a "truncated condition-number" of S(1,1)/S(p,p) and with p = 10 you get TCN = 3.0641e+16 - which is not that much better than cond(G). I hope you get "not as degenerate" cases to work with next.
HTH