-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathlimo_WLS.m
78 lines (65 loc) · 2.48 KB
/
limo_WLS.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
66
67
68
69
70
71
72
73
74
75
76
77
function [b,W,rf] = limo_WLS(X,Y)
% LIMO_WLS Limo Weighted Least Squares (WLS)
% WLS is used to find the maximum likelihood estimates of a generalized
% linear model, and in robust regression to find an M-estimator, as a way
% of mitigating the influence of outliers in an otherwise
% normally-distributed data set.
%
% Weights are obtained using a Principal Components Projection
%
% FORMAT: [b,W,rf] = limo_WLS(X,Y)
%
% INPUTS:
% X = the design matrix
% Y = 2D matrix of EEG data (dim trials x frames)
%
% OUTPUTS:
% b = betas (dim parameters * time frames) the parameters of the GLM
% W = weights (dim trials) to apply for each trial
% rf = the number of dimensions (compoments) removed to get W
%
% References:
% P. Filzmoser, R. Maronna, M. Werner (2007). Outlier identification in
% high dimensions, Computational Statistics and Data Analysis.
%
% see also LIMO_PCOUT LIMO_IRLS
%
% Cyril Pernet v2 January 2014
% ------------------------------
% Copyright (C) LIMO Team 2019
%% input check
if nargin < 2
error(message('Too Few Inputs'));
end
[rows,cols] = size(X);
if (rows <= cols)
error('WLS cannot be computed, there is not enough trials for this design');
end
if isempty(Y(:,median(abs(Y-median(Y))) > 1e-6)) % time points for which medians of trials > 1e-6
error('WLS cannot be computed, for at least 1 condition, all trials have the same values')
end
%% get the weights from PC on adjusted residuals
% Hat matrix; Leverages for each observation
H = diag(X*pinv(X'*X)*X');
H(H>1) = 1; % numerical error instead of H=1 we can obtain 1.000000..... because of pinv
% Adjustment factor
adjfactor = 1 ./ sqrt(1-H);
adjfactor(isinf(adjfactor)) = 1; % if H = 1, no adjustment
% OLS solution
b = pinv(X)*Y;
% tuning function for the bisquare see also limo_IRLS
tune = 4.685;
% Get residuals from previous fit
res = Y - X*b;
resadj = res .* repmat(adjfactor, 1, size(Y,2));
% re - Robust Estimator
% 0.6745 is the 0.75- quantile of the standard normal distribution
% (makes the estimate unbiased)
re = median(abs(resadj)) ./ 0.6745;
re(find(re < 1e-5)) = 1e-5;
r = resadj ./ repmat(tune.*re, size(Y,1),1);
%% do the computation
[W,~,rf] = limo_pcout(r,'figure','off'); % 'new'
WY = Y .* repmat(W,1,size(Y,2));
WX = X .* repmat(W,1,size(X,2));
b = pinv(WX)*WY;