diff solvers/SMALL_chol.m @ 1:7750624e0c73 version0.5

(none)
author idamnjanovic
date Thu, 05 Nov 2009 16:36:01 +0000
parents
children 524cc3fff5ac
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/solvers/SMALL_chol.m	Thu Nov 05 16:36:01 2009 +0000
@@ -0,0 +1,130 @@
+function [A]=SMALL_chol(Dict,X, m, maxNumCoef, errorGoal, varargin) 
+%%
+%=============================================
+% Sparse coding of a group of signals based on a given 
+% dictionary and specified number of atoms to use. 
+% input arguments: Dict - the dictionary
+%                   X - the signals to represent
+%                   m - number of atoms in Dictionary
+%                   errorGoal - the maximal allowed representation error for
+%                   each signal.
+%
+% optional:         if Dict is function handle then Transpose Dictionary
+%                   handle needs to be specified.
+%
+% output arguments: A - sparse coefficient matrix.
+%
+% based on KSVD toolbox solver found on Miki Elad webpage (finding inverse
+% with pinv() is changed with OMP Cholesky update)
+% Ivan Damnjanovic 2009
+%=============================================
+%%
+% This Dictionary check is based on Thomas Blumensath work in sparsify 0_4 greedy solvers 
+explicitD=0;
+if     isa(Dict,'float')      
+            D =@(z) Dict*z;  
+            Dt =@(z) Dict'*z;
+            explicitD=1;
+elseif isobject(Dict) 
+            D =@(z) Dict*z;  
+            Dt =@(z) Dict'*z;
+elseif isa(Dict,'function_handle') 
+    try
+        DictT=varargin{1};
+        if isa(DictT,'function_handle'); 
+                D=Dict; 
+                Dt=DictT;
+        else
+                error('If Dictionary is a function handle,Transpose Dictionary also needs to be a function handle. ');
+        end
+    catch
+        error('If Dictionary is a function handle, Transpose Dictionary  needs to be specified. Exiting.');
+    end
+else
+    error('Dictionary is of unsupported type. Use explicit matrix, function_handle or object. Exiting.');
+end
+%%
+[n,P]=size(X);
+
+
+
+global opts opts_tr machPrec
+opts.UT = true; 
+opts_tr.UT = true; opts_tr.TRANSA = true;
+machPrec = 1e-5;
+
+A = sparse(m,size(X,2));
+for k=1:1:P,
+    
+    R_I = [];
+    x=X(:,k);
+    residual=x;
+	indx = [];
+	a = zeros(m,1);
+	currResNorm = norm(residual);
+    errorGoal=errorGoal*currResNorm;
+	j = 0;
+    while currResNorm>errorGoal & j < maxNumCoef,
+		j = j+1;
+        dir=Dt(residual);
+        
+        [tmp__, pos]=max(abs(dir));
+        
+        [R_I, flag] = updateChol(R_I, n, m, D, explicitD, indx, pos, Dt);
+        
+       
+            indx(j)=pos;
+            dx=zeros(m,1);
+        
+            z = linsolve(R_I,dir(indx),opts_tr);
+        
+            dx(indx) = linsolve(R_I,z,opts);
+            a(indx) = a(indx) + dx(indx);
+                
+            residual=x-D(a);
+            currResNorm = norm(residual);
+        
+    
+   end;
+   if (~isempty(indx))
+       A(indx,k)=a(indx);
+   end
+end;
+return;
+
+
+function [R, flag] = updateChol(R, n, N, A, explicitA, activeSet, newIndex, varargin)
+
+% updateChol: Updates the Cholesky factor R of the matrix 
+% A(:,activeSet)'*A(:,activeSet) by adding A(:,newIndex)
+% If the candidate column is in the span of the existing 
+% active set, R is not updated, and flag is set to 1.
+
+global opts_tr machPrec
+flag = 0;
+
+if (explicitA)
+    newVec = A(:,newIndex);
+else
+    At=varargin{1};
+    e = zeros(N,1);
+    e(newIndex) = 1;
+    newVec = A(e);%feval(A,1,n,N,e,1:N,N); 
+end
+
+if isempty(activeSet),
+    R = sqrt(sum(newVec.^2));
+else
+    if (explicitA)
+        p = linsolve(R,A(:,activeSet)'*A(:,newIndex),opts_tr);
+    else
+        AnewVec = At(newVec);%feval(A,2,n,length(activeSet),newVec,activeSet,N);
+        p = linsolve(R,AnewVec(activeSet),opts_tr);
+    end
+    q = sum(newVec.^2) - sum(p.^2);
+    if (q <= machPrec) % Collinear vector
+        flag = 1;
+    else
+        R = [R p; zeros(1, size(R,2)) sqrt(q)];
+    end
+end