-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfit_ols_ESD.m
executable file
·65 lines (57 loc) · 1.56 KB
/
fit_ols_ESD.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
%% Ordinary linear least squares fit with outlier removal
function [pp, varargout] = fit_ols_ESD(X, Y, varargin)
%%
% Generalized ESD test for outliers:
% (http://www.itl.nist.gov/div898/handbook/eda/section3/eda35h3.htm)
n = numel(Y);
outliers = false(n, 1);
k = 0;
pp = NaN(1,2);
if nargin > 2
alpha = varargin{1};
else
alpha = 0.001;
end
while k < numel(Y)-3
k = k+1;
%%%
% Total least squares:
[pp_scaled, SS, mu] = polyfit(X(~outliers), Y(~outliers), 1);
%%%
% Compute test statistic:
residuals = abs(Y(~outliers) - polyval(pp_scaled, X(~outliers),[],mu));
%residuals = abs(Y - polyval(pp, X,[],mu));
[R, I] = max(residuals);
R = R/nanstd(residuals);
%%%
% Compute critical value:
p = 1 - alpha/(2*(n-k+1));
tp = tinv(p, n-k-1);
lambda = (n-k)*tp/sqrt((n-k-1+tp^2)*(n-k+1));
%%%
% Test for outlier:
outlier = R > lambda;
if outlier
tmp = find(~outliers);
outliers(tmp(I)) = true;
n = n-1;
else
break;
end
end
pp(2)=pp_scaled(2) - (pp_scaled(1)*mu(1)/mu(2));% offset, m
pp(1)=pp_scaled(1)/mu(2);% slope , k
%
% P(2)= P_scaled(2)-(P_scaled(1)*mu(1)/mu(2)); % offset, m
% P(1) = P_scaled(1)/mu(2);% slope , k
SS.sigma = sqrt(diag(inv(SS.R)*inv(SS.R')).*SS.normr.^2./SS.df); % the std errors in the slope and y-crossing
SS.sigma(1)=SS.sigma(1)/mu(2);
%% Give output:
if nargout == 2
varargout{1} = outliers;
end
if nargout == 3
varargout{1} = outliers;
varargout{2} = SS;
end
end