forked from jcollfont/inverseecg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TSVD_inverse.m
69 lines (51 loc) · 1.8 KB
/
TSVD_inverse.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
function [EGM_sol, lambdaCornerIX,rho,eta] = TSVD_inverse(A, ECG, trunk, frobenius,manualTruncation)
warning off
% comopute svd of forward matrix
[N,M] = size(A);
[T] = size(ECG,2);
% select maximum truncation
maxTrunk = min(trunk, min(N,M));
try
[U,S,V] = svd(A);
catch
[U,S,V] = svds(A,max(N,M));
end
% project data onto left singular vectors
Uy = U'*ECG;
% for all dimensions of svd
EGMtrunk = cell(1,maxTrunk);
rho = zeros(maxTrunk, T);
eta = zeros(maxTrunk, T);
for k = 1:maxTrunk
if k == 1
EGMtrunk{1} = V(:,1) * 1/S(1,1) *Uy(1,:);
else
EGMtrunk{k} = EGMtrunk{k-1} + V(:,k) * 1/S(k,k) * Uy(k,:);
end
rho(k,:) = sum( ( ECG - A*EGMtrunk{k} ).^2 , 1);
eta(k,:) = sum( ( EGMtrunk{k} ).^2 , 1);
end
%% Choose to select independent lambda or single lambda
EGM_sol = zeros(M,T);
if manualTruncation == 0%IF manual truncation option is 0, then use the L curve, otehrwise use predefined truncation value
if frobenius
% compute L-curve and select corner
rho = sum(rho,2)';
eta = sum(eta,2)';
[lambdaCornerIX, kappa] = maxCurvatureLcurve( log([rho;eta]), 1:maxTrunk, maxTrunk);
% return solution
EGM_sol = EGMtrunk{lambdaCornerIX};
else
% for every time instance
for tt = 1:T
% compute L-curve and select corner
[lambdaCornerIX, kappa] = maxCurvatureLcurve(log([rho(:,tt)';eta(:,tt)']), 1:maxTrunk, maxTrunk);
%% return solution
EGM_sol(:,tt) = EGMtrunk{lambdaCornerIX}(:,tt);
end
end
else
EGM_sol = EGMtrunk{manualTruncation};%If a desired trunctation was provided use that
lambdaCornerIX = manualTruncation;
end
end