This repository has been archived by the owner on Aug 15, 2020. It is now read-only.
/
hinftv_regression.m
128 lines (116 loc) · 3.63 KB
/
hinftv_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
function [Y,H,Hh] = hinftv_regression(X, opt)
% hinftv_regression() - Performs automatic EOG artifact correction using
% multiple adaptive regression. The adaptation takes place using the H
% infinity norm time-varying algorithm [1].
%
% Usage:
% >> [Y,H,Hh] = hinftv_regression( X, opt)
%
% Inputs:
% X - Input data matrix (dxN)
% opt - Analysis options:
% 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)
%
% 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 TV algorithm proposed in [1].
%
% References:
% [1] S. Puthusserypady and T. Ratnarajah, IEEE Signal Processing Letters
% 12, 816-819
%
%
%
% See also:
% POP_HINFTV_REGRESSION, EEGLAB
%
% Copyright (C) <2007> German Gomez-Herrero, http://germangh.com
% OVERFLOW
OVERFLOW = 1E12;
if nargin < 1,
help hinftv_regression;
return;
end
if ~exist('opt','var'),
opt = def_hinftv_regression;
else
opt = def_hinftv_regression(opt);
end
if isempty(opt.refdata),
error('(hinftv_regression) I need a reference signal!');
end
rho = opt.rho;
eta = opt.eta;
M = opt.M;
eps = opt.eps;
Xref = opt.refdata;
[deeg,Leeg] = size(X);
[dref,Lref] = size(Xref);
if Leeg~=Lref,
error('(hinftv_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);
Upsilon0 = rho.*eye(M*dref);
Pi0 = eta*eye(M*dref);
P = Pi0;
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(hinftv_regression) '); end
for i = M:Leeg
r = Xref(:,i:-1:(i-M+1));
r = reshape(r', M*dref,1);
P_tilde = inv(inv(P)-eps^(-2)*r*r');
g = (P_tilde*r)./(1+r'*P_tilde*r);
e0 = X(:,i)'-r'*H;
H = H+g*e0;
if nargout > 2, Hh(:,:,i) = H; end
P = inv(inv(P)+(1-eps^(-2))*r*r') + Upsilon0;
update = r'*H;
if ~isempty(find(abs(update(:))>OVERFLOW, 1)),
error('(hinftv_regression) Algorithm became unstable');
end
Y(:,i) = (X(:,i)'-update)';
if opt.verbose && ~mod(i,floor(Leeg/10)), fprintf('.'); end
end
if opt.verbose,fprintf('[OK]\n');end
return;
% sub-function to initialize the default values
% ----------------------------------------------
function [opt] = def_hinftv_regression(opt)
if ~exist('opt','var') || isempty(opt) || ~isfield(opt,'EOGindex'),
opt.EOGindex = [];
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