This repository has been archived by the owner on Aug 15, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathhinfew_regression.m
132 lines (119 loc) · 3.82 KB
/
hinfew_regression.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
function [Y,H,Hh] = hinfew_regression(X, opt)
% hinfew_regression() - Performs automatic EOG artifact correction using
% multiple adaptive regression. The adaptation is made using the H infinity
% exponentially weighted (EW) algorithm [1].
%
% Usage:
% >> [Y,H,Hh] = hinfew_regression(X, opt)
%
% Inputs:
% X - Input data matrix
% opt - Analysis options (see below)
% opt.refdata - Reference signal (s) (dref x N) (default: [])
% opt.M - Order of the adaptive filter (default: 5)
% opt.eta - Factor reflecting a priori knowledge of how close the
% estimated filter weights at t=0 are to their optimal
% value at that time instant (default: 5e-3)
% opt.rho - Factor reflecting a priori knowledge of how rapidly
% the filter coefficients vary with time
% (default: 1e-5)
% opt.eps - Positive constant described in [1] (default: 1.5)
% opt.lambda - Forgetting factor (default:0.9)
%
% Outputs:
% Y - Output data matrix (dxN) (artifact corrected)
% H - Final filter weights (M*dref x d)
% Hh - filter weights evolution (M*dref x d x N)
%
% Notes:
% 1) This function implements the H infinity norm EW algorithm described
% in [1].
%
% References:
% [1] S. Puthusserypady and T. Ratnarajah, IEEE Signal Processing Letters
% 12, 816-819
%
% See also:
% POP_HINFEW_REGRESSION, EEGLAB
%
% Copyright (C) <2007> German Gomez-Herrero, http://germangh.com
% OVERFLOW
OVERFLOW = 1E12;
if nargin < 1,
help hinfew_regression;
return;
end
if ~exist('opt','var'),
opt = def_hinfew_regression;
else
opt = def_hinfew_regression(opt);
end
if isempty(opt.refdata),
error('(hinfew_regression) I need a reference signal!');
end
eta = opt.eta;
M = opt.M;
eps = opt.eps;
lambda = opt.lambda;
Xref = opt.refdata;
[deeg,Leeg] = size(X);
[dref,Lref] = size(Xref);
if Leeg~=Lref,
error('(hinfew_regression) Input data and reference signal must have the same length');
end
% initialization of the adaptation loop
% -----------------------------------------------
H = zeros(dref*M,deeg);
Y = zeros(deeg,Leeg);
r = Xref(:,(M+1):-1:2);
r = reshape(r', M*dref,1);
invP_hat = (1/eta)*eye(M*dref)-eps^(-2)*r*r';
if nargout > 2,
Hh = zeros(dref*M,deeg,Leeg);
Hh(:,:,1:M-1) = repmat(H,[1,1,M-1]);
end
% adaptation loop
% -----------------------------------------------
if opt.verbose, fprintf('\n(hinfew_regression) '); end
for i = M:Leeg-1
r = Xref(:,i:-1:(i-M+1));
r = reshape(r', M*dref,1);
r_next = Xref(:,i+1:-1:(i-M+2));
r_next = reshape(r_next', M*dref,1);
invP_hat = lambda*invP_hat+lambda*r*r'-eps^(-2)*r_next*r_next';
P_hat = inv(invP_hat);
g = (P_hat*r)./(1+r'*P_hat*r);
update = r'*H;
if ~isempty(find(abs(update(:))>OVERFLOW,1)),
error('(hinfew_regression) Algorithm became unstable');
end
Y(:,i) = (X(:,i)'-update)';
e0 = X(:,i)'-r'*H;
H_prev = H;
H = H_prev+g*e0;
if nargout > 2, Hh(:,:,i) = H; end
if opt.verbose && ~mod(i,floor(Leeg/10)), fprintf('.'); end
end
if opt.verbose,fprintf('[OK]\n');end
function [opt] = def_hinfew_regression(opt)
if ~exist('opt','var') || isempty(opt) || ~isfield(opt,'refdata'),
opt.refdata = [];
end
if ~isfield(opt, 'verbose') || isempty(opt.verbose),
opt.verbose = 1;
end
if ~isfield(opt,'eta') || isempty(opt.eta),
opt.eta = 5e-3;
end
if ~isfield(opt,'rho') || isempty(opt.rho),
opt.rho = 1e-5;
end
if ~isfield(opt, 'eps') || isempty(opt.eps),
opt.eps = 1.5;
end
if ~isfield(opt, 'M') || isempty(opt.M),
opt.M = 3;
end
if ~isfield(opt, 'lambda') || isempty(opt.lambda),
opt.lambda = 0.99;
end