-
Notifications
You must be signed in to change notification settings - Fork 0
/
mnmf_Frb.m
110 lines (86 loc) · 2.33 KB
/
mnmf_Frb.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
function [ wrt, H, T, V ] = mnmf_Frb( X, K, Itr )
% time counting start
tic;
exe_time = 0;
% Getting size
[M,~,I,J] = size( X );
% initialization
T = abs(randn( I, K ));
V = abs(randn( K, J ));
H = zeros( M, M, I, K );
Id = eye( M, M ) / M;
for ii=1:I
for kk=1:K
H(:,:,ii,kk) = Id;
end
end
% Scale Fitting
Xf = make_fctrz( H, T, V );
up = X(:)' * Xf(:);
low = Xf(:)' * Xf(:);
coef = sqrt( up / low );
T = T * coef;
V = V * coef;
Xf = Xf * coef * coef;
% Iteration by MU
wrt = zeros( Itr, 2 );
for lp=1:Itr
% create new tmp variables
tmpT = T;
tmpV = V;
tmpH = H;
vX = zeros(M,M,I,K);
vXf = zeros(M,M,I,K);
upperT = zeros(I,K);
lowerT = zeros(I,K);
% Initialize T & update H
for i = 1:I
for k = 1:K
for j = 1:J
vX(:,:,i,k) = vX(:,:,i,k) + V(k,j) * X(:,:,i,j);
vXf(:,:,i,k) = vXf(:,:,i,k) + V(k,j) * Xf(:,:,i,j);
end
upperT(i,k) = vec(H(:,:,i,k))'* vec(vX(:,:,i,k));
lowerT(i,k) = vec(H(:,:,i,k))'* vec(vXf(:,:,i,k));
end
end
% update T
tmpT = T.*(upperT./lowerT);
% InitializeV
upperV = zeros(K,J);
lowerV = zeros(K,J);
for j = 1:J
for k = 1:K
for i = 1:I
upperV(k,j) = upperV(k,j) + T(i,k) * vec(H(:,:,i,k))'* vec(X(:,:,i,j));
lowerV(k,j) = lowerV(k,j) + T(i,k) * vec(H(:,:,i,k))'* vec(Xf(:,:,i,j));
end
end
end
% update V
tmpV = V.*(upperV./lowerV);
% H initialozed
% update H(Not refactored)
for i = 1:I
for k = 1:K
vXfi = inv(vXf(:,:,i,k));
tmp = H(:,:,i,k) * vXfi * vX(:,:,i,k);
tmp = ( tmp + tmp' ) / 2;
[P,L] = eig( tmp );
tmp = real( P * diag( max( diag(L), 0 ) ) * P' );
tmp = tmp / trace( tmp );
tmpH(:,:,i,k) = tmp;
end
end
% Update variables
H = tmpH;
V = tmpV;
T = tmpT;
Xf = make_fctrz( H, T, V );
exe_time = exe_time + toc;
D = reshape( X - Xf, M*M*I*J,1);
% Extension Euclidean
wrt(lp,:) = [ exe_time D'*D ];
tic;
end
end