forked from KyleZhang1118/Voice-Separation-and-Enhancement
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PCA.m
70 lines (61 loc) · 2.12 KB
/
PCA.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
function [E,D] = PCA(vectors, firstEig, lastEig, rankTolerance)
%The step of PCA
%vectors:Num*samples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Default values:
if nargin < 2, firstEig = 1; end
if(nargin >2 && lastEig>size(vectors,1))
lastEig = size(vectors,1);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Calculate PCA
% module = abs(max(max(vectors))); Normalization
module=1;
vectors = vectors./module;
%Calculate the covariance matrix.
% covarianceMatrix = cov(vectors.', 1);
covarianceMatrix = vectors*vectors'/size(vectors,2);
% Calculate the eigenvalues and eigenvectors of covariance matrix.
[E, D] = eig (covarianceMatrix);
%We reserve the eigenvalues which is larger than ranktolerance,to wipe out
%the noise component.
if nargin < 4
rankTolerance = 1e-7;
end
if nargin < 3
lastEig_ada = sum (diag (D) > rankTolerance);
lastEig= lastEig_ada;
end
% Sort the eigenvalues - decending.
[~,order] = sort(diag(D),'descend');
%%%%%%%%%%%%%% Special Use
% if(D(order(lastEig))<D(order(1))*rankTolerance && lastEig==size(vectors,1))
% covarianceMatrix = covarianceMatrix+eye(size(covarianceMatrix))*(max(eig(covarianceMatrix))*10^-2);
% [E, D] = eig (covarianceMatrix);
% [~,order] = sort(diag(D),'descend');
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% See if the user has reduced the dimension enough
% if lastEig < maxLastEig
% fprintf('占쏙옙竪? %d占쏙옙占신븝옙都 \n',...
% lastEig);
% num=lastEig;
% else
% fprintf ('占신븝옙都占쎈눈占쏙옙占쏙옙占쏙옙占쏙옙寧占쏙옙.\n');
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Drop the smaller eigenvalues
if lastEig==0
sprintf('no component!');
E = [];
D = [];
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Select the colums which correspond to the desired range
% of eigenvalues.
E = E(:,order);
D = D(order,order);
E = E(:,firstEig:lastEig);
D = D(firstEig:lastEig,firstEig:lastEig)*module^2;
return;