-
Notifications
You must be signed in to change notification settings - Fork 5
/
NMP.m
74 lines (61 loc) · 1.79 KB
/
NMP.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
function H = NMP(X,W,G,L,numIterations)
% H = NMP(X,W,G,L,numIterations)
%
% Nonnegative Matching Pursuit.
% Minimizes approximately sum(sum((X - W*H).^2)) w.r.t. H, s.t. all(H(:) >= 0)
% and all(sum(H > 0,1) <= L). This means the columns of X are coded using a
% nonnegative linear combination of maximal L columns out of W.
%
% Input:
% X: DxN data matrix
% W: DxK dictionary matrix
% G: Gram Matrix W'*W (when G=[], G is calculated by the function)
% L: Sparseness Factor (maximal number of nonzero entries in each column of H)
% numIterations: number of NMF iterations for nonnegative least squares (default 10)
%
% Output:
% H (sparse): KxN nonnegative sparse coding matrix
%
%
% see "Sparse Nonnegative Matrix Factorization Using L0-constraints",
% R. Peharz, M. Stark, F. Pernkopf, MLSP 2010.
%
% March 2010, by Robert Peharz
%
[D,N]=size(X);
[D,K]=size(W);
H = sparse(K,N);
if nargin < 5
numIterations = 10;
end
if isempty(G)
G = W'*W;
end
% code each column of X
for k = 1:N
Cidx = [];
C = [];
% residual is first the whole data vector
residual = X(:,k);
projections0 = (X(:,k)' * W)';
% collect L atoms
for l = 1:L
projections = residual' * W;
[maxVal,idx] = max(projections);
if maxVal < 0
break;
end
% insert atom
if ~any(Cidx == idx)
Cidx = [Cidx; idx];
C = [C; maxVal];
end
% this approximates nonnegative least squares (NMF for H)
for n = 1:numIterations
C = C .* projections0(Cidx) ./ (G(Cidx,Cidx) * C + 1e-9);
end
% calculate new residual
residual = X(:,k) - W(:,Cidx) * C;
end
H(Cidx, k) = C;
end