[422372]: / functions / sigprocfunc / acsobiro.m

Download this file

146 lines (133 with data), 5.1 kB

  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
133
134
135
136
137
138
139
140
141
142
143
144
function [H,S,D]=acsobiro(X,n,p)
% ACSOBIRO - A. Chickocki's robust Second-Order Blind Identification (SOBI)
% by joint diagonalization of the time-delayed covariance matrices.
% NOTE: THIS CODE ASSUMES TEMPORALLY CORRELATED SIGNALS.
% Thus, the estimated time-delayed covariance matrices
% for at least some time delays must be nonsingular.
%
% Usage: >> [H] = acsobiro(X);
% >> [H,S] = acsobiro(X,n,p);
% Inputs:
% X - data matrix of dimension [m,N] where
% m is the number of sensors
% N is the number of samples
% n - number of sources {Default: n=m}
% p - number of correlation matrices to be diagonalized {default: 100}
% For noisy data, use at least 100 time delays.
% Outputs:
% H - matrix of dimension [m,n] an estimate of the *mixing* matrix
% S - matrix of dimension [n,N] an estimate of the source activities
% where >> X [m,N] = H [m,n] * S [n,N]
%
% Authors: Implemented and improved by A. Cichocki on the basis of
% the classical SOBI algorithm of Belouchrani and publications of:
% A. Belouchrani et al., F. Cardoso et al.,
% S. Choi, S. Cruces, S. Amari, and P. Georgiev
% For references: see function body
%
% Note: Extended by Arnaud Delorme and Scott Makeig to process data epochs
% (computes the correlation matrix respecting epoch boundaries).
% REFERENCES:
% A. Belouchrani, K. Abed-Meraim, J.-F. Cardoso, and E. Moulines, ``Second-order
% blind separation of temporally correlated sources,'' in Proc. Int. Conf. on
% Digital Sig. Proc., (Cyprus), pp. 346--351, 1993.
%
% A. Belouchrani, and A. Cichocki,
% Robust whitening procedure in blind source separation context,
% Electronics Letters, Vol. 36, No. 24, 2000, pp. 2050-2053.
%
% A. Cichocki and S. Amari,
% Adaptive Blind Signal and Image Processing, Wiley, 2003.
if nargin<1 || nargin > 3
help acsobiro
return;
end
[m,N,ntrials]=size(X);
if nargin==1,
DEFAULT_LAGS = 100;
n=m; % source detection (hum...)
p=min(DEFAULT_LAGS,ceil(N/3)); % number of time delayed correlation matrices to be diagonalized
% Note: For noisy data, use at least p=100.
elseif nargin==2,
DEFAULT_LAGS = 100;
p=min(DEFAULT_LAGS,ceil(N/3)); % number of correlation matrices to be diagonalized
end
X(:,:)=X(:,:)-(mean(X(:,:),2)*ones(1,N*ntrials)); % Remove data means
for t = 1:ntrials
if t == 1
Rxx=(X(:,1:N-1,t)*X(:,2:N,t)')/(N-1)/ntrials; % Estimate the sample covariance matrix
% for the time delay p=1, to reduce influence
% of white noise.
else
Rxx=Rxx+(X(:,1:N-1,t)*X(:,2:N,t)')/(N-1)/ntrials; % Estimate the sample covariance matrix
% for the time delay p=1, to reduce influence
% of white noise.
end
end
[Ux,Dx,Vx]=svd(Rxx);
Dx=diag(Dx);
if n<m, % under assumption of additive white noise and when the number
% of sources is known, or can be estimated a priori
Dx=Dx-real((mean(Dx(n+1:m))));
Q= diag(real(sqrt(1./Dx(1:n))))*Ux(:,1:n)';
else % under assumption of no additive noise and when the
% number of sources is unknown
n=max(find(Dx>1e-99)); % detect the number of sources
fprintf('acsobiro(): Estimated number of sources is %d\n',n);
Q= diag(real(sqrt(1./Dx(1:n))))*Ux(:,1:n)';
end
Xb = zeros(size(X));
Xb(:,:)=Q*X(:,:); % prewhitened data
% Estimate the time delayed covariance matrices:
k=1;
pn=p*n; % for convenience
for u=1:m:pn,
k=k+1;
for t = 1:ntrials
if t == 1
Rxp=Xb(:,k:N,t)*Xb(:,1:N-k+1,t)'/(N-k+1)/ntrials;
else
Rxp=Rxp+Xb(:,k:N,t)*Xb(:,1:N-k+1,t)'/(N-k+1)/ntrials;
end
end
M(:,u:u+m-1)=norm(Rxp,'fro')*Rxp; % Frobenius norm =
end; % sqrt(sum(diag(Rxp'*Rxp)))
% Approximate joint diagonalization:
eps=1/sqrt(N)/100; encore=1; U=eye(n);
while encore, encore=0;
for p=1:n-1,
for q=p+1:n,
% Givens rotations:
g=[ M(p,p:n:pn)-M(q,q:n:pn) ;
M(p,q:n:pn)+M(q,p:n:pn) ;
i*(M(q,p:n:pn)-M(p,q:n:pn))];
[Ucp,D] = eig(real(g*g')); [la,K]=sort(diag(D));
angles=Ucp(:,K(3));angles=sign(angles(1))*angles;
c=sqrt(0.5+angles(1)/2);
sr=0.5*(angles(2)-j*angles(3))/c; sc=conj(sr);
asr = abs(sr)>eps ;
encore=encore | asr ;
if asr , % Update the M and U matrices:
colp=M(:,p:n:pn);
colq=M(:,q:n:pn);
M(:,p:n:pn)=c*colp+sr*colq;
M(:,q:n:pn)=c*colq-sc*colp;
rowp=M(p,:);
rowq=M(q,:);
M(p,:)=c*rowp+sc*rowq;
M(q,:)=c*rowq-sr*rowp;
temp=U(:,p);
U(:,p)=c*U(:,p)+sr*U(:,q);
U(:,q)=c*U(:,q)-sc*temp;
end %% if
end %% q loop
end %% p loop
end %% while
% Estimate the mixing matrix H
H= pinv(Q)*U(1:n,1:n);
% Estimate the source activities S
if nargout>1
S=[];
W=U(1:n,1:n)'*Q;
S= W*X(:,:);
end