-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolveOrthonormalV.m
More file actions
83 lines (75 loc) · 1.97 KB
/
solveOrthonormalV.m
File metadata and controls
83 lines (75 loc) · 1.97 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
function [ V ] = solveOrthonormalV( B, X, U, S, init_V )
n = size(X, 1);
L = size(B, 2);
d = size(X, 2);
V = zeros(d, L);
XtB = X'*B; % d*n*L
for k=1:L
tmp = 0;
Ac = cell(L, L);
bc = cell(L, 1);
pre_err = [];
counter = 0;
while (true)
% for iter=1:200
lambda = solveLambda(-S(1), 1000000, (U'*(XtB(:, k) - tmp)).^2, S);
if (lambda == 0)
V = init_V;
return;
end
inv_Xcov = U*diag(1./(S + lambda))*U'; % d^3
for c=1:k-1
inv_XcovV = inv_Xcov*V(:, c); % d*d
for r=1:k-1
Ac{r, c} = V(:, r)'*inv_XcovV; % d
% Ac{c, r} = Ac{r, c};
end
bc{c} = XtB(:, k)'*inv_XcovV; % d
end
tmp = 0;
if (k > 1)
A = cell2mat(Ac(1:k - 1, 1:k - 1));
b = cell2mat(bc(1:k - 1));
phi = A(1:k - 1, 1:k - 1)\b(1:k - 1); % L^3
tmp = sum(repmat(phi', size(V, 1), 1).*V(:, 1:length(phi)), 2);
end
V(:, k) = inv_Xcov*(XtB(:, k) - tmp); % d*d
err = abs(V(:, k)'*V(:, k) - 1);
if (err < 1e-3)
break;
end
if ((counter > 2000) && (err < 1e-2))
break;
end
if (abs(pre_err - err) < 1e-8)
V = init_V;
return;
end
pre_err = err;
counter = counter + 1;
end
end
end
function [lambda] = solveLambda(low, high, VtXtBk2, S)
pre_gap = -1;
while (low < high)
% for iter=1:1000
mid = low + ( high - low )/2;
val = sum(VtXtBk2./((S + mid).^2));
gap = high - low;
if (abs(val - 1) < 1e-4)
break;
end;
if (pre_gap == gap)
lambda = 0;
return;
end;
if (val > 1)
low = mid;
else
high = mid;
end
pre_gap = gap;
end
lambda = mid;
end