resize_figure(f10,120,220);
plot(xbin,fX,'k','LineWidth',1);
plot(xbin,fX(xbin==im).*fX_noise_2./(max(fX_noise_2)),'--b');
% plot(xbin,fX(xbin==3).*fX_noise_3./(max(fX_noise_2)));
plot(xbin,fX(xbin==fm).*fX_noise_4./(max(fX_noise_4)),'--r');
% Here the normalization by fX(xbin==im or fm) is crucial, as its
% an important component of the regression to the mean effect.
% The increased probabiliy of occurence of some values X over others,
% is what leads to the truth corresponding a measurement to be
% closer to the more-probable value in comparison to the measurement.
plot([3,3],[0,0.093],'--k');
plot([2,2],[0,0.102],'b');
plot([4,4],[0,0.056],'r');
title('Regression to the mean of the true value given erroneous measurements');
set(gca,'XTick',[-10,-4,0,2,3,4,10]);
exportgraphics(f10,[outputFolder,'Figure2a.png'], ...
%export_fig([outputFolder,'Figure2a.png'], ...
% '-r600','-png','-nocrop',f10);
%export_fig([outputFolder,'Figure2a.pdf'], ...
% '-r600','-pdf','-nocrop',f10);
toc
Elapsed time is 1.324639 seconds.
X = random('Normal',0,3,1,nSamples);
W1 = W + noiseAmp.*random('Normal',0,1,1,nSamples);
XBin = linspace(min(X),max(X),40);
EWgX = create_curve(W',X',XBin);
EW1gX = create_curve(W1',X',XBin);
X1 = X + noiseAmp.*random('Normal',0,1,1,nSamples);
EWgX1 = create_curve(W',X1',XBin);
X1 = X + noiseAmp.*random('Normal',0,1,1,nSamples);
EW1gX1 = create_curve(W1',X1',XBin);
resize_figure(f2,220,150);
plot_type0(X,W,X1,W1,EWgX1,EW1gX,EW1gX1,XBin,'linear');
exportgraphics(f2,[outputFolder,'Figure2b.png'], ...
%export_fig([outputFolder,'Figure2b.png'], ...
% '-r600','-png','-nocrop',f2);
%export_fig([outputFolder,'Figure2b.pdf'], ...
% '-r600','-pdf','-nocrop',f2);
X = random('Lognormal',0.1,0.5,1,nSamples);
W1 = W + noiseAmp.*W.^2.*random('Normal',0,1,1,nSamples);
X1 = X + noiseAmp.*X.^2.*random('Normal',0,1,1,nSamples);
XBin = linspace(min(X),max(X),40);
EWgX = create_curve(W',X',XBin);
EW1gX = create_curve(W1',X',XBin);
EWgX1 = create_curve(W',X1',XBin);
EW1gX1 = create_curve(W1',X1',XBin);
resize_figure(f6,220,150);
plot_type0(X,W,X1,W1,EWgX1,EW1gX,EW1gX1,XBin,'linear');
exportgraphics(f6,[outputFolder,'Figure2c.png'], ...
%export_fig([outputFolder,'Figure2c.png'], ...
% '-r600','-png','-nocrop',f6);
%export_fig([outputFolder,'Figure2c.pdf'], ...
% '-r600','-pdf','-nocrop',f6);
toc
Elapsed time is 6.702287 seconds.
function plot_type0(X,W,X1,W1,EWgX1,EW1gX,EW1gX1,XBin,Scale)
tiledlayout(3,2,'TileSpacing',"compact");
scatter(X,W,0.1,0.5.*[1 1 1],'filled');
set(gca,'XScale',Scale,'YScale',Scale);
plot(mean(X),mean(W),'.g');
text(mean(X),mean(W),' 🠐 mean',"HorizontalAlignment","left");
%% Regression curve with noise only on W
scatter(X,W1,0.1,[0.7 0.7 0.7],'filled',"o");
plot(XBin,XBin,'LineStyle','--','Color','k','LineWidth',1);
plot(mean(X),mean(W),'.g');
set(gca,'XScale',Scale,'YScale',Scale);
title('Noise in dependent variable');
%% Regression curve with noise only on X
scatter(X1,W,0.1,0.5.*[1 1 1],'filled');
plot(XBin,XBin,'LineStyle','--','Color','k','LineWidth',1);
plot(mean(X),mean(W),'.g');
set(gca,'XScale',Scale,'YScale',Scale);
title('X vs. X+\epsilon')
title('Noise in independent variable');
%% Regression curve with noise in X & W
scatter(X1,W1,0.1,0.5.*[1 1 1],'filled');
plot(XBin,XBin,'LineStyle','--','Color','k','LineWidth',1);
plot(mean(X),mean(W),'.g');
set(gca,'XScale',Scale,'YScale',Scale);
title('X+\epsilon vs. X+\epsilon')
title('Noise in both variables');
xlabel('X + \epsilon_1');
ylabel('W + \epsilon_2');
histogram(X,'BinEdges',XBin,'Normalization',"pdf");
title('Probabilty distribution function of X')
scatter(X,(X1-X)./X,0.5,0.5.*[1 1 1],'filled');
EegX = create_curve((X1'-X'),X',XBin);
p1=plot(EegX.XBins,EegX.stdYgX./abs(EegX.XBins),'k');
legend(ax2,p1,'$\sigma(\epsilon)/X$','interpreter','latex','Location','best');
title('% Noise varying with X')
function p = plot_curve(curve, color)
CI1 = interp_nans(curve.CI);
p=plot(curve.XBins, curve.YgX, 'Color', color,'LineWidth',1);
plot_ci(curve.XBins,CI1,color,0.2);
function plot_ci(x,ci,color,alpha)
inBetween = [ci(:,1)', fliplr(ci(:,2)')];
fill(X2,inBetween,color,'LineStyle','none','FaceAlpha',alpha);
function curve = create_curve(Y, X, Ei)
% Y - first variable, X - second variable, Ei - bin array
X1 = X(~isnan(X) & ~isnan(Y));
Y1 = Y(~isnan(X) & ~isnan(Y));
[xindx, E] = discretize(X(:),Ei);
curve.YgX(i) = nanmean(Y(xindx==i));
curve.stdYgX(i) = nanstd(Y(xindx==i));
curve.NSamples(i) = sum(xindx==i & ~isnan(Y));
curve.SEM(i) = nanstd(Y(xindx==i))./sqrt(curve.NSamples(i));
curve.ts(i,:) = tinv([0.025 0.975],curve.NSamples(i)-1);
curve.CI(i,:) = curve.YgX(i) + curve.ts(i,:)*curve.SEM(i);
curve.XBins(i) = 0.5*(E(i)+E(i+1));
function resize_figure( figureHandle, vert, horz )
%% resize_figure.m Resizes figure into a standard paper size
%--------------------------------------------------------------------------
% vert - Vertical page size in mm (Default Letter Size)
% horz - Horizontal page size in mm (Default Letter Size)
if nargin<3 || isempty(horz)
if nargin<2 || isempty(vert)
% Figure size displayed on screen
movegui(figureHandle, 'center');
set(figureHandle,'color','w');
set(figureHandle, 'Units', 'centimeters', 'Position', [0 0 xSize ySize])
function B = interp_nans(A)
%% interp_nans.m This function removes nan by interpolating along altitude
%--------------------------------------------------------------------------
% A - Input altitude vs. time matrix [nh x nT]
%--------------------------------------------------------------------------
% B - Interpolated altitude vs. time matrix, along the altitude directon
% with nans removed [nh x nT]
%--------------------------------------------------------------------------
% Modified: 17th Jan 2018
% Created : 25th Sep 2016
% Author : Nithin Sivadas
%--------------------------------------------------------------------------
if sum(isnan(y))< size(A,1)-2
B(:,ty)=interp1(xi,yi,x,'linear','extrap');
[isThereNAN, totalNAN] = check_nan(B);
function [isThereNAN, totalNAN] = check_nan(thisArray)
%% check_nan.m Check if there is any nan values in the given array
%--------------------------------------------------------------------------
% thisArray : An array or a matrix
%--------------------------------------------------------------------------
% isThereNAN : A boolean variable, True => there is nan values in the
% array, and False => there is no nan values in the array
% totalNAN : The total number of NAN values
%--------------------------------------------------------------------------
% Modified: 22nd Sep 2016
% Created : 22nd Sep 2016
% Author : Nithin Sivadas
%--------------------------------------------------------------------------
thisArrayNAN = isnan(thisArray);
totalNAN = sum(thisArrayNAN(:));
warning(['There are ',num2str(totalNAN),...
' nan values in your data. The results may not be accurate.']);