idamnjanovic@1
|
1 function [A]=SMALL_chol(Dict,X, m, maxNumCoef, errorGoal, varargin)
|
idamnjanovic@1
|
2 %%
|
idamnjanovic@22
|
3 %
|
idamnjanovic@22
|
4 % Centre for Digital Music, Queen Mary, University of London.
|
idamnjanovic@22
|
5 % This file copyright 2009 Ivan Damnjanovic.
|
idamnjanovic@22
|
6 %
|
idamnjanovic@22
|
7 % This program is free software; you can redistribute it and/or
|
idamnjanovic@22
|
8 % modify it under the terms of the GNU General Public License as
|
idamnjanovic@22
|
9 % published by the Free Software Foundation; either version 2 of the
|
idamnjanovic@22
|
10 % License, or (at your option) any later version. See the file
|
idamnjanovic@22
|
11 % COPYING included with this distribution for more information.
|
idamnjanovic@22
|
12 %
|
idamnjanovic@1
|
13 % Sparse coding of a group of signals based on a given
|
idamnjanovic@1
|
14 % dictionary and specified number of atoms to use.
|
idamnjanovic@1
|
15 % input arguments: Dict - the dictionary
|
idamnjanovic@1
|
16 % X - the signals to represent
|
idamnjanovic@1
|
17 % m - number of atoms in Dictionary
|
idamnjanovic@1
|
18 % errorGoal - the maximal allowed representation error for
|
idamnjanovic@1
|
19 % each signal.
|
idamnjanovic@1
|
20 %
|
idamnjanovic@1
|
21 % optional: if Dict is function handle then Transpose Dictionary
|
idamnjanovic@1
|
22 % handle needs to be specified.
|
idamnjanovic@1
|
23 %
|
idamnjanovic@1
|
24 % output arguments: A - sparse coefficient matrix.
|
idamnjanovic@1
|
25 %
|
idamnjanovic@1
|
26 %%
|
idamnjanovic@1
|
27 % This Dictionary check is based on Thomas Blumensath work in sparsify 0_4 greedy solvers
|
idamnjanovic@1
|
28 explicitD=0;
|
idamnjanovic@1
|
29 if isa(Dict,'float')
|
idamnjanovic@1
|
30 D =@(z) Dict*z;
|
idamnjanovic@1
|
31 Dt =@(z) Dict'*z;
|
idamnjanovic@1
|
32 explicitD=1;
|
idamnjanovic@1
|
33 elseif isobject(Dict)
|
idamnjanovic@1
|
34 D =@(z) Dict*z;
|
idamnjanovic@1
|
35 Dt =@(z) Dict'*z;
|
idamnjanovic@1
|
36 elseif isa(Dict,'function_handle')
|
idamnjanovic@1
|
37 try
|
idamnjanovic@1
|
38 DictT=varargin{1};
|
idamnjanovic@1
|
39 if isa(DictT,'function_handle');
|
idamnjanovic@1
|
40 D=Dict;
|
idamnjanovic@1
|
41 Dt=DictT;
|
idamnjanovic@1
|
42 else
|
idamnjanovic@1
|
43 error('If Dictionary is a function handle,Transpose Dictionary also needs to be a function handle. ');
|
idamnjanovic@1
|
44 end
|
idamnjanovic@1
|
45 catch
|
idamnjanovic@1
|
46 error('If Dictionary is a function handle, Transpose Dictionary needs to be specified. Exiting.');
|
idamnjanovic@1
|
47 end
|
idamnjanovic@1
|
48 else
|
idamnjanovic@1
|
49 error('Dictionary is of unsupported type. Use explicit matrix, function_handle or object. Exiting.');
|
idamnjanovic@1
|
50 end
|
idamnjanovic@1
|
51 %%
|
idamnjanovic@1
|
52 [n,P]=size(X);
|
idamnjanovic@1
|
53
|
idamnjanovic@1
|
54
|
idamnjanovic@1
|
55
|
idamnjanovic@1
|
56 global opts opts_tr machPrec
|
idamnjanovic@1
|
57 opts.UT = true;
|
idamnjanovic@1
|
58 opts_tr.UT = true; opts_tr.TRANSA = true;
|
idamnjanovic@1
|
59 machPrec = 1e-5;
|
idamnjanovic@1
|
60
|
idamnjanovic@1
|
61 A = sparse(m,size(X,2));
|
idamnjanovic@1
|
62 for k=1:1:P,
|
idamnjanovic@1
|
63
|
idamnjanovic@1
|
64 R_I = [];
|
idamnjanovic@1
|
65 x=X(:,k);
|
idamnjanovic@1
|
66 residual=x;
|
idamnjanovic@1
|
67 indx = [];
|
idamnjanovic@1
|
68 a = zeros(m,1);
|
idamnjanovic@1
|
69 currResNorm = norm(residual);
|
idamnjanovic@1
|
70 errorGoal=errorGoal*currResNorm;
|
idamnjanovic@1
|
71 j = 0;
|
idamnjanovic@1
|
72 while currResNorm>errorGoal & j < maxNumCoef,
|
idamnjanovic@1
|
73 j = j+1;
|
idamnjanovic@1
|
74 dir=Dt(residual);
|
idamnjanovic@1
|
75
|
idamnjanovic@1
|
76 [tmp__, pos]=max(abs(dir));
|
idamnjanovic@1
|
77
|
idamnjanovic@1
|
78 [R_I, flag] = updateChol(R_I, n, m, D, explicitD, indx, pos, Dt);
|
idamnjanovic@1
|
79
|
idamnjanovic@1
|
80
|
idamnjanovic@1
|
81 indx(j)=pos;
|
idamnjanovic@1
|
82 dx=zeros(m,1);
|
idamnjanovic@1
|
83
|
idamnjanovic@1
|
84 z = linsolve(R_I,dir(indx),opts_tr);
|
idamnjanovic@1
|
85
|
idamnjanovic@1
|
86 dx(indx) = linsolve(R_I,z,opts);
|
idamnjanovic@1
|
87 a(indx) = a(indx) + dx(indx);
|
idamnjanovic@1
|
88
|
idamnjanovic@1
|
89 residual=x-D(a);
|
idamnjanovic@1
|
90 currResNorm = norm(residual);
|
idamnjanovic@1
|
91
|
idamnjanovic@1
|
92
|
idamnjanovic@1
|
93 end;
|
idamnjanovic@1
|
94 if (~isempty(indx))
|
idamnjanovic@1
|
95 A(indx,k)=a(indx);
|
idamnjanovic@1
|
96 end
|
idamnjanovic@1
|
97 end;
|
idamnjanovic@1
|
98 return;
|
idamnjanovic@1
|
99
|
idamnjanovic@1
|
100
|
idamnjanovic@1
|
101 function [R, flag] = updateChol(R, n, N, A, explicitA, activeSet, newIndex, varargin)
|
idamnjanovic@1
|
102
|
idamnjanovic@1
|
103 % updateChol: Updates the Cholesky factor R of the matrix
|
idamnjanovic@1
|
104 % A(:,activeSet)'*A(:,activeSet) by adding A(:,newIndex)
|
idamnjanovic@1
|
105 % If the candidate column is in the span of the existing
|
idamnjanovic@1
|
106 % active set, R is not updated, and flag is set to 1.
|
idamnjanovic@1
|
107
|
idamnjanovic@1
|
108 global opts_tr machPrec
|
idamnjanovic@1
|
109 flag = 0;
|
idamnjanovic@1
|
110
|
idamnjanovic@1
|
111 if (explicitA)
|
idamnjanovic@1
|
112 newVec = A(:,newIndex);
|
idamnjanovic@1
|
113 else
|
idamnjanovic@1
|
114 At=varargin{1};
|
idamnjanovic@1
|
115 e = zeros(N,1);
|
idamnjanovic@1
|
116 e(newIndex) = 1;
|
idamnjanovic@1
|
117 newVec = A(e);%feval(A,1,n,N,e,1:N,N);
|
idamnjanovic@1
|
118 end
|
idamnjanovic@1
|
119
|
idamnjanovic@1
|
120 if isempty(activeSet),
|
idamnjanovic@1
|
121 R = sqrt(sum(newVec.^2));
|
idamnjanovic@1
|
122 else
|
idamnjanovic@1
|
123 if (explicitA)
|
idamnjanovic@1
|
124 p = linsolve(R,A(:,activeSet)'*A(:,newIndex),opts_tr);
|
idamnjanovic@1
|
125 else
|
idamnjanovic@1
|
126 AnewVec = At(newVec);%feval(A,2,n,length(activeSet),newVec,activeSet,N);
|
idamnjanovic@1
|
127 p = linsolve(R,AnewVec(activeSet),opts_tr);
|
idamnjanovic@1
|
128 end
|
idamnjanovic@1
|
129 q = sum(newVec.^2) - sum(p.^2);
|
idamnjanovic@1
|
130 if (q <= machPrec) % Collinear vector
|
idamnjanovic@1
|
131 flag = 1;
|
idamnjanovic@1
|
132 else
|
idamnjanovic@1
|
133 R = [R p; zeros(1, size(R,2)) sqrt(q)];
|
idamnjanovic@1
|
134 end
|
idamnjanovic@1
|
135 end
|