% applied to exemplary curve-fitting problem
% d(x)=g(x, m1, m2) with g = sin(w0*m(1)*x) + m(1)*m(2);
dtrue = sin(w0*mt(1)*x) + mt(1)*mt(2); % true data
dobs = dtrue + random('Normal',0.0,sd,N,1);
axis( [0, xmax, 0, 4 ] );
plot(x,dtrue,'k-','LineWidth',3);
plot(x,dobs,'ro','LineWidth',3);
fprintf('Caption: True data (black curve) and observed data (red circles)\n');
Caption: True data (black curve) and observed data (red circles)
% Define 2D grid (for plotting purposes only)
% tabulate total error E on grid (for plotting purposed only)
% Note m1 varies along rows of E and m2 along columns
dpre = sin(w0*m1a(j)*x) + m1a(j)*m2a(k);
% save best solutions, so far
iterbest = zeros(Niter,1);
m0 = [0.1;0.1]; % start in upepr-left hand corner of plot
dpre0 = sin(w0*m0(1)*x) + m0(1)*m0(2);
% save this solution first solution, the best so far
% randomly select trial solution
m1trial = random('Uniform',m1min,m1max);
m2trial = random('Uniform',m2min,m2max);
mtrial = [m1trial; m2trial];
dtrial = sin(w0*m1trial*x) + m1trial*m2trial;
Etrial = etrial'*etrial/sd2;
% accept trial solution if error decreases
mbest(1:M,Nsaved) = mtrial;
iterbest(Nsaved) = myiter;
% reset best-solution so far to this one
% throw away unused part of arrays
mbest = mbest(1:2,1:Nsaved);
iterbest = iterbest(1:Nsaved);
axis( [m2min, m2max, m1min, m1max] );
imagesc( [m2min, m2max], [m1min, m1max], E);
plot( mbest(2,:), mbest(1,:), 'w*', 'LineWidth',2);
plot( mbest(2,:), mbest(1,:), 'w-', 'LineWidth',2);
plot( mbest(2,end), mbest(1,end), 'ro', 'LineWidth',2);
plot( mt(2), mt(1), 'g*', 'LineWidth', 2);
fprintf('Caption: Error surface, with true solution (green) and progression of solution');
Caption: Error surface, with true solution (green) and progression of solution
fprintf('(white circles and lines) and final solution\n');
(white circles and lines) and final solution
fprintf('(red circle)\n');
plot( iterbest(:), mbest(1,:),'k-','LineWidth',1);
plot( [0,K]',[mt(1),mt(1)]','r:','LineWidth',1);
plot( iterbest(:), mbest(1,:),'k*','LineWidth',3);
fprintf('Caption: Evolution of model parameter 1 with iteration number (black),\n');
Caption: Evolution of model parameter 1 with iteration number (black),
fprintf('with true model parameter depicted by red line\n');
with true model parameter depicted by red line
plot( iterbest(:), mbest(2,:),'k-','LineWidth',1);
plot( [1,K]',[mt(2),mt(2)]','r:','LineWidth',1);
plot( iterbest(:), mbest(2,:),'k*','LineWidth',3);
fprintf('Caption: Evolution of model parameter 2 with iteration number (black),\n');
Caption: Evolution of model parameter 2 with iteration number (black),
fprintf('with true model parameter depicted by red line\n');
with true model parameter depicted by red line
axis( [0, K, min(log10(Ebest)), max(log10(Ebest)) ] );
plot( iterbest(:), log10(Ebest(:)), 'k-','LineWidth',1);
plot( iterbest(:), log10(Ebest(:)), 'k*','LineWidth',3);
fprintf('Caption: Evolution of error with iteration number\n');
Caption: Evolution of error with iteration number
fprintf('%d iterations, %d accepted\n', Niter, Nsaved );
10000 iterations, 10 accepted
% Simulated Annealing search
% applied to exemplary curve-fitting problem
% d(x)=g(x, m1, m2) with g = sin(w0*m(1)*x) + m(1)*m(2);
dtrue = sin(w0*mt(1)*x) + mt(1)*mt(2); % true data
dobs = dtrue + random('Normal',0.0,sd,N,1);
axis( [0, xmax, 0, 4 ] );
plot(x,dtrue,'k-','LineWidth',3);
plot(x,dobs,'ro','LineWidth',3);
fprintf('Caption: True data (black curve) and observed data (red circles)\n');
Caption: True data (black curve) and observed data (red circles)
% Define 2D grid (for plotting purposes only)
% tabulate total error psi on grid.
% Note m1 varies along rows of E and m2 along columns
dpre = sin(w0*m1a(j)*x) + m1a(j)*m2a(k);
% save all solutions and their error
T = exp( log(Tstart)+(log(Tend)-log(Tstart))*[0:Niter-1]'/(Niter-1) );
m0 = [0.2; 0.2]; % start in upepr-left hand corner of plot
d0 = sin(w0*m0(1)*x) + m0(1)*m0(2);
% save this solution first solution, the best so far
% randomly select trial solution
mp = random('Normal',m0,sq,M,1);
dp = sin(w0*mp(1)*x) + mp(1)*mp(2);
logpmp = -0.5*Ep/(T(myiter)*sd2);
logalpha = logpmp - logpm0;
% standard metropolis acceptance test
r = random('Uniform',0.0,1.0);
axis( [m2min, m2max, m1min, m1max] );
imagesc( [m2min, m2max], [m1min, m1max], E);
plot( msave(2,:), msave(1,:), 'w*', 'LineWidth', 2);
plot( msave(2,:), msave(1,:), 'w-', 'LineWidth', 2);
plot( mt(2), mt(1), 'g*', 'LineWidth', 2);
plot( msave(1,Niter), msave(1,Niter), 'r*', 'LineWidth', 2);
fprintf('Caption: Error surface, with true solution (green), starting solution (red star),\n');
Caption: Error surface, with true solution (green), starting solution (red star),
fprintf('progression of solution (white circles and lines) and final solution\n');
progression of solution (white circles and lines) and final solution
fprintf('(red circle)\n');
axis( [0, Niter, 0, 4 ] );
plot( n, msave(1,:)','k-', 'LineWidth', 1);
plot( [1,Niter]',[mt(1),mt(1)]','r:','LineWidth', 1);
fprintf('Caption: Evolution of model parameter 1 with iteration number (black),\n');
Caption: Evolution of model parameter 1 with iteration number (black),
fprintf('with true model parameter depicted by red line\n');
with true model parameter depicted by red line
axis( [0, Niter, 0, 4 ] );
plot( n, msave(2,:)','k-','LineWidth', 1);
plot( [1,Niter]',[mt(2),mt(2)]','r:','LineWidth', 1);
fprintf('Caption: Evolution of model parameter 2 with iteration number (black),\n');
Caption: Evolution of model parameter 2 with iteration number (black),
fprintf('with true model parameter depicted by red line\n');
with true model parameter depicted by red line
axis( [0, Niter, min(log10(Esave)), max(log10(Esave)) ] );
plot( n, log10(Esave), 'k-', 'LineWidth', 1);
fprintf('Caption: Evolution of error with iteration number\n');
Caption: Evolution of error with iteration number
axis( [0, Niter, min(log(T)), max(log(T)) ] );
plot( n, log10(T),'k-','LineWidth', 1);
fprintf('Caption: Decrease in temperture with iteration number\n');
Caption: Decrease in temperture with iteration number
fprintf('%d iterations, %d accepts\n', Niter,Naccept );
4000 iterations, 156 accepts
% Using the Metropolis-Hastings algorithm to sample the likelihood
% associated with the exemplary curve-fitting problem
% variance of prior information
% prior model parameters and their variance
% d(x)=g(x, m1, m2) with g = sin(w0*m(1)*x) + m(1)*m(2);
dtrue = sin(w0*mt(1)*x) + mt(1)*mt(2); % true data
dobs = dtrue + random('Normal',0.0,sd,N,1);
axis( [0, xmax, 0, 4 ] );
plot(x,dtrue,'k-','LineWidth', 3);
plot(x,dobs,'ro','LineWidth', 3);
fprintf('Caption: True data (black) and observed data (red)\n');
Caption: True data (black) and observed data (red)
% tabulate total error psi on grid (for plotting purposes only)
% Note m1 varies along rows of psi and m2 along columns
dpre = sin(w0*m1a(j)*x) + m1a(j)*m2a(k);
l = mA - [m1a(j), m2a(k)]';
Psi(j,k) = e'*e/sd2 + l'*l/sm2;
m1c = (m1min + m1max)/2.0;
m2c = (m2min + m2max)/2.0;
dold = sin(w0*mold(1)*x) + mold(1)*mold(2);
logpold = -0.5*Eold/sd2-0.5*Lold/sm2;
dm = random('Normal',0.0,sn,M,1);
dnew = sin(w0*mnew(1)*x) + mnew(1)*mnew(2);
logpnew = -0.5*Enew/sd2-0.5*Lnew/sm2;
if( (logpnew-logpold) >= 0.0)
alpha = exp( logpnew - logpold );
r = random('Uniform',0.0,1.0);
% keep only values past burn in
m = m(1:M,Nburnt+1:Niter);
% 95% confidence of the mean
Dm95 = 2.0*sqrt(diag(Cm)/Niter);
axis( [m2min, m2max, m1min, m1max] );
imagesc( [m2min, m2max], [m1min, m1max], Psi);
plot( mest(2), mest(1), 'go', 'LineWidth', 3);
plot( [mest(2)-Dm95(2), mest(2)+Dm95(2)]', [mest(1)-Dm95(1), mest(1)+Dm95(1)]', 'g-', 'LineWidth', 1);
plot( [mest(2),mest(2)]',[mest(1)-Dm95(1),mest(1)+Dm95(1)]', 'g-', 'LineWidth', 1);
plot( mA(2), mA(1), 'y*', 'LineWidth', 3);
fprintf('Caption: Generalized error surface with prior model (yellow circle)\n');
Caption: Generalized error surface with prior model (yellow circle)
fprintf('estimated model (green circle) and its 95 percent confident\n');
estimated model (green circle) and its 95 percent confident
fprintf('bounds (green lines) superimposed. The confidence bounds may\n');
bounds (green lines) superimposed. The confidence bounds may
fprintf('be negligibly small\n');
i = floor((mym1-m1min)/Dm)+1; % convert m1 to integer array index
j = floor((mym2-m2min)/Dm)+1; % convert m2 to integer array index
if( (i<1) || (i>L) || (j<1) || (j>L) )
% plot histogram of model
axis( [m2min, m2max, m1min, m1max] );
imagesc( [m2min, m2max], [m1min, m1max], H);
fprintf('Caption: Histogram of model ensemble\n');
Caption: Histogram of model ensemble
% histogram of predicted data
xH=xmax*[1:NHx]'/(NHx-1);
Dv = (vmax-vmin)/(NHv-1);
dH = sin(w0*m(1,myiter)*xH) + m(1,myiter)*m(2,myiter);
j = floor((dH-vmin)/Dv)+1; % convert data to integer array index
k = find((j>=1)&(j<=NHv)); % exclude indices that are out of bound
jg = j(k); % data value indices
ig = n(k); % corresponding x position indices
H(jg(i),ig(i))=H(jg(i),ig(i))+1; % accumulate histogram
axis( [0, xmax, vmin, vmax ] );
imagesc([0, xmax], [vmin, vmax], H);
plot(x,dobs,'wo','LineWidth', 3);
fprintf('Caption: Histogram of predicted data with observed\n');
Caption: Histogram of predicted data with observed
fprintf('data (white circles) superimposed');
data (white circles) superimposed
% Using the Metropolis-Hastings algorithm to sample the likelihood
% associated with the exemplary Laplace transform problem
mtrue = ones(M,1)+sin(2*pi*z/zmax);
% data kernel, exponentially decaying
G(i,1:M) = exp(-c(i)*z');
% prior model parameters and their variance
dobs = dtrue + random('Normal',0.0,sd,N,1);
gda_draw( G, 'caption G', mtrue,'caption m', '=', dobs, 'caption dobs');
fprintf('Caption: Graphical depiction of data equation\n');
Caption: Graphical depiction of data equation
axis( [0, zmax, 0, max(dobs) ] );
plot(z,dtrue,'k-','LineWidth',3);
plot(z,dobs,'ro','LineWidth',3);
fprintf('Caption: True data (black) and observed data (red)\n');
Caption: True data (black) and observed data (red)
mold = random('uniform',0.8,1.0,M,1);
logpold = -0.5*Eold/sd2-0.5*Lold/sm2;
Dm = random('Normal',0.0,sn,M,1);
logpnew = -0.5*Enew/sd2-0.5*Lnew/sm2;
Dlogp = logpnew - logpold;
r = random('Uniform',0.0,1.0);
% keep only values past burn in
m = m(1:M,Nburnt+1:Niter);
% estimate is the mean, variance
% two times std error of mean
Dm95 = 2.0*sqrt(diag(Cm)/Niter);
axis( [0, zmax, 0, 3 ] );
plot(z,mtrue,'k-','LineWidth',3);
plot(z,mest,'r-','LineWidth',2);
plot( z, mest-Dm95, 'g-', 'LineWidth',1);
plot( z, mest+Dm95, 'g-', 'LineWidth',1);
fprintf('Caption: True model (black) and mean (estimated) model (red)\n');
Caption: True model (black) and mean (estimated) model (red)
fprintf('and its 95 percent confidence bounds (green) (confidence\n');
and its 95 percent confidence bounds (green) (confidence
fprintf('bounds may be very close to one another)');
bounds may be very close to one another)
Dbin = (binmax-binmin)/(Nbins-1);
bins = binmin+Dbin*[0:Nbins-1]';
k = floor((m0-binmin)/Dbin)+1;
axis( [0, zmax, binmin, binmax] );
imagesc([0, zmax], [binmin, binmax], Hroot);
plot( z, mtrue, 'y-', 'LineWidth',3);
plot( z, mest, 'w-', 'LineWidth',3);
fprintf('Caption: Histogram of model, with mean (estimated) model (white)\n');
Caption: Histogram of model, with mean (estimated) model (white)
fprintf('and true model (yellow) superimposed\n');
and true model (yellow) superimposed
count=sum( (m(3,:)>m(2,:)) &(m(3,:)>m(4,:)) );
fprintf('%.6f percent have m2>m1 and m2>m3\n', 100.0*count/Niter );
61.482500 percent have m2>m1 and m2>m3
% Using the extended Metropolis-Hastibgs algorith to sample the a
% trans-dimensional Normal pdf with two data types:
% p(m) = [1d Normal with probability beta] + [2d Normal with probability (1-beta)]
beta = 0.2; % probaility of dim 1
% dim-1 pdf is normal with this variance and normalization facto
N1 = beta/sqrt(2.0*pi*sm12);
% dim-2 pdf is normal with this variance and normalization factor
N2 = (1.0-beta)/(2.0*pi*sm22);
Niter=1000000+Nburnt; % length of Markov chain
doswitch=500; % switch dimensions
m = zeros(3,Niter); % m[3,.] 1 or 2 signifies dimension
dimold = 2; % starting dimenion
% assign first link in chain
mold = random('Uniform',-1.0,1.0);
logpold = logN1-0.5*(mold^2)/sm12;
mold = random('Uniform',-1.0,1.0,2,1);
logpold = logN2-0.5*(mold(1)^2+mold(2)^2)/sm22;
% random verctors u are normal with these variance and normlizations
Nu1 = 1/(sqrt(2.0*pi)*su1);
Nu2 = 1/(sqrt(2.0*pi)*su2);
Nu3 = 1/(sqrt(2.0*pi)*su3);
% Transdimensional Metropolis Hastings
% switch dimensions every doswitch iterations
if( mod(myiter,doswitch)==0 )
% three random vectors u1, u2, u3 with transformation
% for the dim-1 to dim-2 transformation
% m1' = [ 1 1 0 0 ] [m1] (m1' = m1 + u1)
% m2' = [ 0 0 0 1 ] [u1] (m2' = u3)
% u1' = [ 0 1 0 0 ] [u2] (u1' = u1)
% u2' = [ 0 0 1 0 ] [u3] (u2' = u2)
% which has a Jacobian of unity
u1 = random('Normal',0.0,su1); % g1
u2 = random('Normal',0.0,su2); % g2
u3 = random('Normal',0.0,su3); % g3
if( (dimold==1) && (dimnew==1) )
logpnew = logN1-0.5*(mnew^2)/sm12;
logalpha=logpnew-logpold;
elseif ( (dimold==1) && (dimnew==2) )
% but since g1=g1' and g2=g2'
% so pnew/pold = p12' / (p1 g3)
logg3 = logNu3-0.5*(u3^2)/su32;
logpnew = logN2-0.5*(mnew(1)^2+mnew(2)^2)/sm22;
logalpha=logpnew-(logpold+logg3);
elseif( (dimold==2) && (dimnew==2) )
logpnew = logN2-0.5*(mnew(1)^2+mnew(2)^2)/sm22;
logalpha=logpnew-logpold;
elseif( (dimold==2) && (dimnew==1) )
logpnew = logN1-0.5*(mnew^2)/sm12;
loggp3 = logNu3-0.5*(up3^2)/su32;
logalpha=(loggp3+logpnew)-logpold;
r = random('Uniform',0.0,1.0);
% keep only values past burn in
m = m(1:3,Nburnt+1:Niter);
Dbin = (binmax-binmin)/(Nbins-1);
hbin = binmin+Dbin*[0:Nbins-1]';
k = floor((m1-binmin)/Dbin)+1;
k1 = floor((m1-binmin)/Dbin)+1;
k2 = floor((m2-binmin)/Dbin)+1;
if( (k1<1) || (k1>Nbins) || (k2<1) || (k2>Nbins) )
fprintf('Caption: Estimated transdimensionl pdf, with\n');
Caption: Estimated transdimensionl pdf, with
fprintf('1-d compoent pdf (left) and 2-d (right)\n');
1-d compoent pdf (left) and 2-d (right)
fprintf("beta: true: %.4f est: %.4f\n", beta, H1count/(H1count+H2count) );
beta: true: 0.2000 est: 0.2028
H1t(i) = N1*exp(-0.5*(hbin(i)^2)/sm12);
H2t = zeros(Nbins,Nbins);
H2t(i,j) = N2*exp(-0.5*(hbin(i)^2+hbin(j)^2)/sm22);
fprintf('Caption: True transdimensionl pdf, with\n');
Caption: True transdimensionl pdf, with
fprintf('1-d compoent pdf (left) and 2-d (right)\n');
1-d compoent pdf (left) and 2-d (right)
H1n = (H1/(H1count+H2count))/(Dbin);
H2n = (H2/(H1count+H2count))/(Dbin^2);
plot(hbin+Dbin/2,H1n,'k-'); % nis-registered by half a bin
fprintf('Caption: 1D component of transdimensionl pdf, true (red), empirical (black)\n');
Caption: 1D component of transdimensionl pdf, true (red), empirical (black)
% Using the extended Metropolis-Hastibgs algorith to sample the a
% trans-dimensional pdf that simultageously fits data to a sinusoid
% p(m|d) = [sinusoid, 1 model parameter] + [bell curve, 2 model parameters]
fprintf(' (with true dimension of 1)\n');
(with true dimension of 1)
% true dimension, can be either 1 or 2
% model 1, sine wave of amplitude m1
dtrue = mtrue*sin(pi*(x-xmin)/(xmax-xmin));
dnottrue = mtrue*exp(-0.5*((x-xmid).^2)/smnt2);
elseif( dimtrue == 2) % model 1, gaussian amplitude mp1 and variance mp2
dtrue = mptrue(1)*exp(-0.5*((x-xmid).^2)/mptrue(2));
dnottrue = mptrue(1)*sin(pi*(x-xmin)/(xmax-xmin));
dobs = dtrue + random('Normal',0.0,sd,Nx,1);
axis( [xmin, xmax, 0, 2 ] );
plot(x,dtrue,'k-','LineWidth', 3);
plot(x,dnottrue,'g-','LineWidth', 3);
plot(x,dobs,'r.','LineWidth', 2);
fprintf('Caption: true data curve (black) and alternative data curve (green)\n');
Caption: true data curve (black) and alternative data curve (green)
fprintf('witn observed data (red) superimposed\n');
witn observed data (red) superimposed
% p(m|d) = p(d|m) pA(m) / p(d)
% pp(mp1,mp2|d) = pp(d|mp1,mp2) ppA(m1,m2) / p(d)
% note that p(d) cancels for all ratios, and can be ignored
% note that normalization p(d|m) and pp(d|mp1,mp2) is the same
% and so cancels for all rations and can be ignored
% pA(m) assumed to be normal
% pA(m) = NA exp(-0.5*(m-mA)**2/sA2) with NA = 1/sqrt(2*pi*sA2)
% ppA(mp1,mp2) asumed to be normal
% ppA(mp1,mp2) = NpA exp(-0.5*((mp1-mpA1)**2+(mp2-mpA2)**2)/spA2)
% with NpA = 1/(2*pi*spA2)
Niter=1000000+Nburnt; % links in Markov chain
doswitch=50; % switch dimensions
m = zeros(3,Niter); % m[3,.] 1 or 2 signifies dimension
dimold = 2; % starting dimension
% assign first link in chain
mold = random('Uniform',0.5,1.5);
dpre = mold*sin(pi*(x-xmin)/(xmax-xmin));
mold(1) = random('Uniform',0.5,1.5);
mold(2) = random('Uniform',0.1,1.0);
dpre = mold(1)*exp(-0.5*((x-xmid).^2)/mold(2));
logpold = logNpA-0.5*psi;
% random verctors u are normal with these variance and normlizations
Nu1 = 1/(sqrt(2.0*pi)*su1);
Nu2 = 1/(sqrt(2.0*pi)*su2);
Nu3 = 1/(sqrt(2.0*pi)*su3);
% patch to avoid variace going negative
% Transdimensional Metropolis Hastings
% switch dimensions every doswitch iterations
if( mod(myiter,doswitch)==0 )
% three random vectors u1, u2, u3 with transformation
% for the dim-1 to dim-2 transformation
% m1' = [ 1 1 0 0 ] [m1] (m1' = m1 + u1)
% m2' = [ 0 0 0 1 ] [u1] (m2' = u3)
% u1' = [ 0 1 0 0 ] [u2] (u1' = u1)
% u2' = [ 0 0 1 0 ] [u3] (u2' = u2)
% which has a Jacobian of unity
u1 = random('Normal',0.0,su1); % g1
u2 = random('Normal',0.0,su2); % g2
u3 = random('Normal',0.0,su3); % g3
if( (dimold==1) && (dimnew==1) )
dpre = mnew*sin(pi*(x-xmin)/(xmax-xmin));
logalpha = logpnew-logpold;
elseif( (dimold==1) && (dimnew==2) )
% but since g1=g1' and g2=g2'
% so pnew/pold = p12' / (p1 g3)
logg3 = logNu3 - 0.5*(u3^2)/su32;
dpre = mnew(1)*exp(-0.5*((x-xmid).^2)/mnew(2));
logpnew = logNpA-0.5*psi;
logalpha = logpnew - (logpold + logg3);
elseif( (dimold==2) && (dimnew==2) )
dpre = mnew(1)*exp(-0.5*((x-xmid).^2)/mnew(2));
logpnew = logNpA - 0.5*psi;
logalpha = logpnew - logpold;
elseif( (dimold==2) && (dimnew==1) )
dpre = mnew*sin(pi*(x-xmin)/(xmax-xmin));
logpnew = logNA - 0.5*psi;
loggp3 = logNu3 - 0.5*(up3^2)/su32;
logalpha = (loggp3+logpnew)-logpold;
r = random('Uniform',0.0,1.0);
% keep only values past burn in
m = m(1:3,Nburnt+1:Niter);
fprintf('true dim=1, m = %.4f\n', mtrue);
elseif( dimtrue == 2) % model 1, gaussian amplitude mp1 and variance mp2
fprintf('true dim=2, m = %.4f %.4f\n', mptrue(1), mptrue(2) );
Dbin = (binmax-binmin)/(Nbins-1);
hbin = binmin+Dbin*[0:Nbins-1]';
k = floor((m1-binmin)/Dbin)+1;
fprintf("dim=1 mest = %.4f\n", m1est );
fprintf("no dim=1 members\n");
Dbin1 = (bin1max-bin1min)/(Nbins-1);
Dbin2 = (bin2max-bin2min)/(Nbins-1);
hbin1 = bin1min+Dbin1*[0:Nbins-1]';
hbin2 = bin2min+Dbin2*[0:Nbins-1]';
k1 = floor((m1-bin1min)/Dbin1)+1;
k2 = floor((m2-bin2min)/Dbin2)+1;
if( (k1<1) || (k1>Nbins) || (k2<1) || (k2>Nbins) )
fprintf('dim=2 mest = %.4f %.4f\n', m1est,m2est );
fprintf('no dim=2 members\n');
end
dim=2 mest = 1.0588 0.0582
fprintf('percent of dim=1 %.4f\n', 100.0*H1count/(H1count+H2count));
fprintf('Caption: Graphical depiction of transdimensional pdf, with component 1-d\n');
Caption: Graphical depiction of transdimensional pdf, with component 1-d
fprintf('pdf at left and component 2-d pdf at right\n');
pdf at left and component 2-d pdf at right
% Using the extended Metropolis-Hastibgs algorith to sample the a
% trans-dimensional pdf that simultageously fits data to a sinusoid
% p(m|d) = [sinusoid, 1 model parameter] + [bell curve, 2 model parameters]
fprintf('gdama12_06a (with true dimension of 2)\n');
gdama12_06a (with true dimension of 2)
% true dimension, can be either 1 or 2
% model 1, sine wave of amplitude m1
dtrue = mtrue*sin(pi*(x-xmin)/(xmax-xmin));
dnottrue = mtrue*exp(-0.5*((x-xmid).^2)/smnt2);
elseif( dimtrue == 2) % model 1, gaussian amplitude mp1 and variance mp2
dtrue = mptrue(1)*exp(-0.5*((x-xmid).^2)/mptrue(2));
dnottrue = mptrue(1)*sin(pi*(x-xmin)/(xmax-xmin));
dobs = dtrue + random('Normal',0.0,sd,Nx,1);
axis( [xmin, xmax, 0, 2 ] );
plot(x,dtrue,'k-','LineWidth', 3);
plot(x,dnottrue,'g-','LineWidth', 3);
plot(x,dobs,'r.','LineWidth', 2);
fprintf('Caption: true data curve (black) and alternative data curve (green)\n');
Caption: true data curve (black) and alternative data curve (green)
fprintf('witn observed data (red) superimposed\n');
witn observed data (red) superimposed
% p(m|d) = p(d|m) pA(m) / p(d)
% pp(mp1,mp2|d) = pp(d|mp1,mp2) ppA(m1,m2) / p(d)
% note that p(d) cancels for all ratios, and can be ignored
% note that normalization p(d|m) and pp(d|mp1,mp2) is the same
% and so cancels for all rations and can be ignored
% pA(m) assumed to be normal
% pA(m) = NA exp(-0.5*(m-mA)**2/sA2) with NA = 1/sqrt(2*pi*sA2)
% ppA(mp1,mp2) asumed to be normal
% ppA(mp1,mp2) = NpA exp(-0.5*((mp1-mpA1)**2+(mp2-mpA2)**2)/spA2)
% with NpA = 1/(2*pi*spA2)
Niter=1000000+Nburnt; % links in Markov chain
doswitch=50; % switch dimensions
m = zeros(3,Niter); % m[3,.] 1 or 2 signifies dimension
dimold = 2; % starting dimension
% assign first link in chain
mold = random('Uniform',0.5,1.5);
dpre = mold*sin(pi*(x-xmin)/(xmax-xmin));
mold(1) = random('Uniform',0.5,1.5);
mold(2) = random('Uniform',0.1,1.0);
dpre = mold(1)*exp(-0.5*((x-xmid).^2)/mold(2));
logpold = logNpA-0.5*psi;
% random verctors u are normal with these variance and normlizations
Nu1 = 1/(sqrt(2.0*pi)*su1);
Nu2 = 1/(sqrt(2.0*pi)*su2);
Nu3 = 1/(sqrt(2.0*pi)*su3);
% patch to avoid variace going negative
% Transdimensional Metropolis Hastings
% switch dimensions every doswitch iterations
if( mod(myiter,doswitch)==0 )
% three random vectors u1, u2, u3 with transformation
% for the dim-1 to dim-2 transformation
% m1' = [ 1 1 0 0 ] [m1] (m1' = m1 + u1)
% m2' = [ 0 0 0 1 ] [u1] (m2' = u3)
% u1' = [ 0 1 0 0 ] [u2] (u1' = u1)
% u2' = [ 0 0 1 0 ] [u3] (u2' = u2)
% which has a Jacobian of unity
u1 = random('Normal',0.0,su1); % g1
u2 = random('Normal',0.0,su2); % g2
u3 = random('Normal',0.0,su3); % g3
if( (dimold==1) && (dimnew==1) )
dpre = mnew*sin(pi*(x-xmin)/(xmax-xmin));
logalpha = logpnew-logpold;
elseif( (dimold==1) && (dimnew==2) )
% but since g1=g1' and g2=g2'
% so pnew/pold = p12' / (p1 g3)
logg3 = logNu3 - 0.5*(u3^2)/su32;
dpre = mnew(1)*exp(-0.5*((x-xmid).^2)/mnew(2));
logpnew = logNpA-0.5*psi;
logalpha = logpnew - (logpold + logg3);
elseif( (dimold==2) && (dimnew==2) )
dpre = mnew(1)*exp(-0.5*((x-xmid).^2)/mnew(2));
logpnew = logNpA - 0.5*psi;
logalpha = logpnew - logpold;
elseif( (dimold==2) && (dimnew==1) )
dpre = mnew*sin(pi*(x-xmin)/(xmax-xmin));
logpnew = logNA - 0.5*psi;
loggp3 = logNu3 - 0.5*(up3^2)/su32;
logalpha = (loggp3+logpnew)-logpold;
r = random('Uniform',0.0,1.0);
% keep only values past burn in
m = m(1:3,Nburnt+1:Niter);
fprintf('true dim=1, m = %.4f\n', mtrue);
elseif( dimtrue == 2) % model 1, gaussian amplitude mp1 and variance mp2
fprintf('true dim=2, m = %.4f %.4f\n', mptrue(1), mptrue(2) );
end
true dim=2, m = 1.0000 0.0400
Dbin = (binmax-binmin)/(Nbins-1);
hbin = binmin+Dbin*[0:Nbins-1]';
k = floor((m1-binmin)/Dbin)+1;
fprintf("dim=1 mest = %.4f\n", m1est );
fprintf("no dim=1 members\n");
Dbin1 = (bin1max-bin1min)/(Nbins-1);
Dbin2 = (bin2max-bin2min)/(Nbins-1);
hbin1 = bin1min+Dbin1*[0:Nbins-1]';
hbin2 = bin2min+Dbin2*[0:Nbins-1]';
k1 = floor((m1-bin1min)/Dbin1)+1;
k2 = floor((m2-bin2min)/Dbin2)+1;
if( (k1<1) || (k1>Nbins) || (k2<1) || (k2>Nbins) )
fprintf('dim=2 mest = %.4f %.4f\n', m1est,m2est );
fprintf('no dim=2 members\n');
end
dim=2 mest = 0.9467 0.0377
fprintf('percent of dim=1 %.4f\n', 100.0*H1count/(H1count+H2count));
fprintf('Caption: Graphical depiction of transdimensional pdf, with component 1-d\n');
Caption: Graphical depiction of transdimensional pdf, with component 1-d
fprintf('pdf at left and component 2-d pdf at right\n');
pdf at left and component 2-d pdf at right
% Using the extended Metropolis-Hastings algorith to sample the
% pdf associated with the Laplace Transform problem, in which the
% model is trans-dimensional, with 1, 2, 4 ... layers.
% The scriot uses a fun transformation and its
% inverse for layered media
% that presumes the nummber of layers is a power of two.
% Each old layer is split into N = 2 or 4 or 8 ... new layers,
% with N=Mnew/Mold and with new layers having same value os old,
% [mp;up] = T [m;u] where m are layer values, u are random variation
% Each group of N old Layers are grouped into one new layer
% with new layer having same value as the mean of the old group,
% [m;u] = Ti [mp;up] where m are layer values, u are random variation
% definitions Mold, Mnew and N=Mnew/Mold, K=Mnew-Mold, J=K/Mold
% the matrix T is 2*Mnew by 2*Mnew and is broken into several blocks
% Block A, in the upper left is Mnew by Mnew, and is broken into 2 sub-blocks
% Block AL on the upper left is Mnew by Mold
% divided into (Mold groups of N rows) and Mold columns
% each group has a column of 1's, moving one place to right
% Block AR on the upper right, is Mnew by K
% it is divided into Mold by Mold sub-blocks that are N by J
% only the diagonal sub-blocks are populated
% the top row of each diagonal sub-block is populated by -1's
% the rest have 1's along their diagonal,starting flush left
% Block B, on the upper right is Mnew by Mnew
% it is the identity matrix
% Block C, on the lower left is Mnew by Mnew and is unpopulated
% Block D, on the lower left is Mnew by Mnew and is an identify matrix
% for no change of dimension, there is only a forward transformation
% with random noise being added to each model parameter
% tunable parameters (beware: they are carefully tuned!)
% sigma of data = sigmad_factor * datamax
% random variation of models
% this codebuilds and checks the transformation
dmax = 4; % maximum dimension, with 0<=dim<=dmax
Mmax = 2^dmax; % maximum number of layers
% transformation and its invere (only dimension changes considered here)
% as the first domension is zero, dimensions are misregisterd by 1
% in the arrays. My convention is that the dimension variable always
% is the actual dimension (0<=dim<=dmax) and that one is added in
T = zeros(dmax+1,dmax+1,2*Mmax,2*Mmax);
Jac = zeros(dmax+1,dmax+1);
for newpower = (oldpower+1:dmax)
% populate top row with -1's
TA((i-1)*N+1,Mold+(i-1)*J+k)=-1.0;
TA((i-1)*N+k+1,Mold+(i-1)*J+k)=1.0;
% T is always 2*Mmax by 2*Mmax
% initialized to diagional matrix
T(oldpower+1,newpower+1,1:2*Mmax,1:2*Mmax) = eye(2*Mmax);
T(newpower+1,oldpower+1,1:2*Mmax,1:2*Mmax) = eye(2*Mmax);
% then set upper-left block
T(oldpower+1,newpower+1,1:2*Mnew,1:2*Mnew) = To;
T(newpower+1,oldpower+1,1:2*Mnew,1:2*Mnew) = Toi;
Jac(newpower+1,oldpower+1) = abs(det(To));
Jac(oldpower+1,newpower+1) = abs(det(Toi));
% check crital part of forward transformation, that it preserve value
m = random('Uniform',0.0,1.0,Mold,1);
e = m(i) - mup((i-1)*N+j);
% check critcal part of inverse transformation, that it preserve mean value
mp = random('Uniform',0.0,1.0,Mnew,1);
% check that the mp-up part of Ti has at least 1 nonzero value per row
% so that the resulting m's have random variation
if (abs(Toi(i,j)) > maxE )
To = zeros(2*Mmax,2*Mmax);
T(pof2+1,pof2+1,1:2*Mmax,1:2*Mmax) = To;
fprintf('Transformations built for dmax=%d Mmax=%d: number of errors: %d\n', dmax, Mmax, Ecount);
Transformations built for dmax=4 Mmax=16: number of errors: 0
fprintf('Example: dold=%d bnew=%d Mold=%d Mnew=%d\n', dold, dnew, Mold, Mnew);
Example: dold=2 bnew=2 Mold=4 Mnew=4
fprintf('Jacobian: %.4f\n', Jac(dold+1,dnew+1) );
fprintf('Transformation:');
mystr = sprintf('%2.0f ', T(dold+1,dnew+1,i,j) );
end
1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
fprintf('Example: dold=%d bnew=%d Mold=%d Mnew=%d\n', dold, dnew, Mold, Mnew);
Example: dold=1 bnew=2 Mold=2 Mnew=4
fprintf('Jacobian: %.4f\n',Jac(dold, dnew));
fprintf('Transformation:');
mystr=sprintf('%2.0f ', T(dold+1,dnew+1,i,j) );
end
1 0 -1 0 1 0 0 0
1 0 1 0 0 1 0 0
0 1 0 -1 0 0 1 0
0 1 0 1 0 0 0 1
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
fprintf('Inverse Transformation:\n')
tmp = T(dnew+1,dold+1,i,j);
mystr=sprintf('%2.0f ', tmp );
end
0 0 0 0 -0 -0 0 0
0 0 0 0 0 0 -0 -0
-0 0 0 0 0 -0 0 0
0 0 -0 0 0 0 0 -0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
fprintf('Transformation * Inverse Transformation\n')
Transformation * Inverse Transformation
P = squeeze(T(dold+1,dnew+1,1:2*Mnew,1:2*Mnew)) * squeeze(T(dnew+1,dold+1,1:2*Mnew,1:2*Mnew));
mystr=sprintf('%2.0f ', P(i,j) );
end
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
% I think this easier to understand if I use labels 's' for small 'b' for big
% then the vectors is [ms, ub] where ms is length Ms and the other [mb, us]
% where mb is length Mb. Also, let K = Mb-Ms.
% Case 1: Small to Big (dold<dnew). The you start with [ms, ub] where you supply ub
% by generating 2*Mb-Ms random numbers. Then you compute [mb, us] via the trasnformation
% [mb, us] = T[dold,dnew,0:2*Mnew,0:2*Mnew] [ms, ub]
% The acceptance function is
% p(mb) Jsb gb(ub_K+1) ... gb(ub_2*Mmax)
% Asb = -------------------------------- ----------------------------
% p(ms) gs(us_1) ... gs(us_K) gs(us_K+1) ... gs(us_2*Mmax)
% where the right hand fraction is unity, as gs(us_i) is literlly the
% same function as gb(ub_i).
% Case 2: Big to Small (dnew<dold). The you start with [mb, us] where you supply us
% by generating Mb random numbers. Then you compute [mb, us] via the trasnformation
% [mb, us] = T[dnew,dold,0:2*Mnew,0:2*Mnew] [ms, ub]
% The acceptance function is
% p(ms) gs(us_1) ... gs(us_K) Jbs gs(us_K+1) ... gs(us_2*Mmax)
% Abs = -------------------------------- ----------------------------
% p(mb) gb(ub_K+1) ... gb(ub_2*Mmax)
% where the right hand fraction is unity. Note that the two A's are exactly
% reciprocals, as Jsb=1/Jbs.
% Case 3: Same dimension (d=dnew=dold). The you start with [m0, u0] where you supply u0
% by generating M=Mb=Ms random numbers. Then you compute [mp, up] via the trasnformation
% [mp, up] = T[d,d,0:2*M,0:2*M] [m0, u0]
% The acceptance function is
% as the Jacobian is unity and all the g's cancel..
% prior for number of dimensions; note misregistration by 1
c = cmax*[0:Mmax-1]'/(Mmax-1);
z = zmax*[0:Mmax-1]'/(Mmax-1);
mtrueext = [mtrue; zeros(Mmax-Mtrue,1)];
To = squeeze(T(dtrue+1,dmax+1,1:Mmax,1:Mmax));
datamax = max(abs(datatrue));
sigmad = sigmad_factor*datamax;
dataobs = datatrue + random('Normal',0.0,sigmad,Mmax,1);
gda_draw(G,'caption G',mint,'caption m','=',datatrue,'caption d');
fprintf('Caption: Graphical depiction of data equation\n');
Caption: Graphical depiction of data equation
mpriext = [mpri; zeros(Mmax-Mtrue,1)];
% random variation of models
moldext = [mold; zeros(Mmax-Mold,1)];
To = squeeze(T(dold+1,dmax+1,1:Mmax,1:Mmax));
eold = dataobs - dataold;
logpEold = -logtwopi-Mmax*logsigmad-0.5*Eold/sigmad2;
Lold = (lold'*lold)/(Mmax/Mold); % (Mmax/Mold) accounts for duplicates
logpLold = -logtwopi-Mold*logsigmam-0.5*Lold/sigmam2;
% Transdimensional Metropolis Hastings
Niter=1000000+Nburnt; % length of chain
doswitch=50; % switch model types every doswitch iterations
msave = zeros(Mmax,Niter);
msave(1:Mmax,1) = moldint; % save interpolated models
dsave(1) = dold; % save dimension
% switch dimensions every doswitch iterations
if( mod(myiter,doswitch)==0 )
% new model from random perturbation of old
uold=random('Normal',0.0,sigmau,2*Mmax-Mold,1);
To = squeeze(T(dold+1,dnew+1,1:2*Mmax,1:2*Mmax));
unew = munew(Mnew+1:2*Mmax);
loggstuff = loggstuff - logtwopi - logsigmau - 0.5*(uold(k)^2)/sigmau2;
% in denominator, so positive
loggstuff = loggstuff + logtwopi + logsigmau + 0.5*(unew(k)^2)/sigmau2;
mnewext = [mnew; zeros(Mmax-Mnew,1)];
To = squeeze(T(dnew+1,dmax+1,1:Mmax,1:Mmax));
enew = dataobs - datanew;
logpEnew = -logtwopi-Mmax*logsigmad-0.5*Enew/sigmad2;
Lnew = (lnew'*lnew)/(Mmax/Mnew); % (Mmax/Mnew) accounts for duplicates
logpLnew = -logtwopi-Mnew*logsigmam-0.5*Lnew/sigmam2;
logalpha = (logpEnew + logpLnew + loggstuff + logPD(dnew+1)) - (logpEold + logpLold + logPD(dold+1));
% error check on reversibility; the loggstuff must be equal and opposite
% (the reveribility condition must be correct for the method to work)
if(RCHECK && (myiter==RCHECKITER))
loggstuffsave = loggstuff;
To = squeeze(T(dold+1,dnew+1,1:2*Mmax,1:2*Mmax));
loggstuff = loggstuff - logtwopi - logsigmau - 0.5*(uold(k)^2)/sigmau2;
% in denominator, so positive
loggstuff = loggstuff + logtwopi + logsigmau + 0.5*(unew(k)^2)/sigmau2;
mnewext = [mnew; zeros(Mmax-Mnew,1)];
To = squeeze(T(dnew+1,dmax+1,1:Mmax,1:Mmax));
enew = dataobs - datanew;
logpEnew = -logtwopi-Mmax*logsigmad-0.5*Enew/sigmad2;
Lnew = (lnew'*lnew)/(Mmax/Mnew); % (Mmax/Mnew) accounts for duplicates
logpLnew = -logtwopi-Mnew*logsigmam-0.5*Lnew/sigmam2;
logalpha = (logpEnew + logpLnew + loggstuff + logPD(dnew+1)) - (logpEold + logpLold + logPD(dold+1));
fprintf('reversibility check 1: should be zero: %e\n',loggstuff+loggstuffsave);
fprintf('reversibility check 2: should be zero: %e\n',logalpha+logalphasave);
% this will only work once, so terminate script
fprintf('Exit Early Due to Error Check Being Activted with RCHECK=1');
% standard acceptance test
r = random('Uniform',0.0,1.0);
msave(1:Mmax,myiter) = moldint; % save interpolated models
dsave(myiter) = dold; % save dimension
msave = msave(1:Mmax,Nburnt+1:Niter);
dsave = dsave(Nburnt+1:Niter);
[Niter, i] = size(dsave);
% Histogram of model dimensions; note misregisered by 1
fprintf('Histogram of model dimensions\n');
Histogram of model dimensions
fprintf('%d %d\n',i,Hdim(i+1));
end
0 1.709500e-01
1 2.811000e-01
2 2.252000e-01
3 1.756990e-01
4 1.470510e-01
fprintf('mean interpolated model\n');
fprintf('%d %d\n',i,mest(i));
end
1 6.053080e-01
2 6.084120e-01
3 6.292330e-01
4 6.300257e-01
5 7.162999e-01
6 7.166941e-01
7 7.203799e-01
8 7.207781e-01
9 1.204280e+00
10 1.204293e+00
11 1.205650e+00
12 1.206190e+00
13 1.217996e+00
14 1.217819e+00
15 1.218373e+00
16 1.218400e+00
% plot histogram of dimensions
axis( [0, dmax, 0, 1 ] );
plot(n,PD,'k-','LineWidth',3);
plot(n,Hdim,'g-','LineWidth',3);
fprintf('Caption: Histogram of dimensions (green)\n');
Caption: Histogram of dimensions (green)
fprintf('together with prior pdf (black)\n')
together with prior pdf (black)
% Histogram of layer probabilities
mint = msave(1:Mmax,myiter);
j = floor((mint(i)-vmin)/Dv)+1;
% plot model probabilities
axis( [0, zmax, vmin, vmax] );
imagesc( [0, zmax], [vmin, vmax], Hv );
plot( z, mest, 'w-', 'LineWidth',3);
fprintf('Caption: Histogram of interpolated moddels, with\n');
Caption: Histogram of interpolated moddels, with
fprintf('mean model superimposed in white\n')
mean model superimposed in white