-
Notifications
You must be signed in to change notification settings - Fork 1
/
mestreCov.m
60 lines (52 loc) · 1.44 KB
/
mestreCov.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
function [covMtx, estEigVl] = mestreCov(X)
% Estimate covariance matrix using Mestre's method optimizing eigenvalue
% estimation accuracy
% Based on formula from: Mestre (2008) "Improved estimation of eigenvalues
% and eigenvectors of covariance matrices using their sample estimates"
% UNTESTED!
% ----------------------------------------
% X - signal / neural data
% set parameters
N = size(X, 1); % number of samples
M = size(X, 2); % number of dimensions
% compute sample covariance, eigenvalues, and eigenvectors
smplCov = cov(X);
[smplEigVc, smplEigVl] = eig(smplCov);
smplEigVl = diag(smplEigVl);
% solve for mu(m)
x = sym('var');
eq = smplEigVl(1)/(smplEigVl(1)-x);
for m = 2:M
eq = eq + smplEigVl(m)/(smplEigVl(m)-x);
end
eq = eq - N;
mu = double(solve(eq));
mu = real(mu);
mu = sort(mu);
% compute robust eigenvalue estimates
estEigVl = N*(smplEigVl - mu);
% compute theta(m,k)
tmp = zeros(M, M);
for m = 1:M
for k = 1:M
if (k~=m)
tmp(m, k) = smplEigVl(m)/(smplEigVl(k)-smplEigVl(m)) - mu(m)/(smplEigVl(k)-mu(m));
end
end
end
theta = -tmp;
for m = 1:M
theta(m, m) = 1 + sum(tmp(:,m));
end
% compute robust eigenvector projection matrix P(m)
P = zeros(M, M, M);
for m = 1:M
for k = 1:M
P(:, :, m) = P(:,:,m) + theta(m,k)*smplEigVc(:,k)*smplEigVc(:,k)';
end
end
% compute Mestre's robust covariance estimate
covMtx = zeros(M, M);
for m = 1:M
covMtx = covMtx + estEigVl(m)*squeeze(P(:,:,m));
end