⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perform_homotopy.m

📁 signal procesing toolbox
💻 M
字号:
function [X,lambda_list,sparsity_list] = perform_homotopy(D,y,options)% perform_homotopy - compute the L1 regularization path%%   X = perform_homotopy(D,y,options);%%   Copyright (c) 2008 Gabriel Peyren = size(D,2);niter = getoptions(options, 'niter', min(round(size(D)))/2);lambdaStop = 0;solFreq = 1;verbose = 0;[X, numIters, activationHist] = SolveLasso(D, y, n, 'lasso', niter, lambdaStop, solFreq, verbose);lambda_list = [];sparsity_list = sum(X~=0);return;tol = 1e-15;tol = 1e-3;X = zeros(p,niter);xbp = zeros(p,1);sparsity_list = [];lambda_list = [];for i=1:niter    % correlation    C = D'*(y-D*xbp);    lambda = max(abs(C));    % support for update    S = find( abs(abs(C/lambda)-1)<tol);    I = ones(p,1); I(S)=0;    Sc = find(I);    % update direction    d = zeros(p,1);    d(S) = (D(:,S)'*D(:,S)) \ sign( C(S) );    % useful vector    v = D(:,S)*d(S);    % Compute minimum |gamma| so that situation 1) is in force.    w = ( lambda-C(Sc) ) ./ ( 1 - D(:,Sc)'*v );    gamma1 = min(w(w>0));    % Compute minimum |gamma| so that situation 2) is in force.    w = ( lambda+C(Sc) ) ./ ( 1 + D(:,Sc)'*v );    gamma2 = min(w(w>0));    % Compute minimum |gamma| so that situation 3) is in force.    w = -xbp(S)./d(S);    gamma3 = min(w(w>0));    % any condition is in force    gamma = min([gamma1 gamma2 gamma3]);    % new solution    xbp = xbp + gamma*d;    X(:,i) = xbp;    % record sparsity and lambda    sparsity_list(i) = sum( abs(xbp)>1e-9 );    lambda_list(i) = lambda;endfunction [sols, numIters, activationHist] = SolveLasso(A, y, N, algType, maxIters, lambdaStop, solFreq, verbose, OptTol)% SolveLasso: Implements the LARS/Lasso algorithms% Usage%	[sols, numIters, activationHist] = SolveLasso(A, y, N, algType,%	maxIters, lambdaStop, solFreq, verbose, OptTol)% Input%	A           Either an explicit nxN matrix, with rank(A) = min(N,n) %               by assumption, or a string containing the name of a %               function implementing an implicit matrix (see below for %               details on the format of the function).%	y           vector of length n.%   N           length of solution vector. %   algType     'lars' for the Lars algorithm, %               'lasso' for lars with the lasso modification (default)%	maxIters    maximum number of LARS iterations to perform. If not%               specified, runs to stopping condition (default)%   lambdaStop  If specified (and > 0), the algorithm terminates when the%               Lagrange multiplier <= lambdaStop. %   solFreq     if =0 returns only the final solution, if >0, returns an %               array of solutions, one every solFreq iterations (default 0). %   verbose     1 to print out detailed progress at each iteration, 0 for%               no output (default)%	OptTol      Error tolerance, default 1e-5% Outputs%	sols           solution of the Lasso/LARS problem%	numIters       Total number of steps taken%   activationHist Array of indices showing elements entering and %                  leaving the solution set% Description%   SolveLasso implements the LARS algorithm, as described by Efron et al. in %   "Least Angle Regression". Currently, the original algorithm is%   implemented, as well as the lasso modification, which solves %      min || y - Ax ||_2^2 s.t || x ||_1 <= t%   for all t > 0, using a path following method with parameter t.%   The implementation implicitly factors the active set matrix A(:,I)%   using Choleskly updates. %   The matrix A can be either an explicit matrix, or an implicit operator%   implemented as an m-file. If using the implicit form, the user should%   provide the name of a function of the following format:%     y = OperatorName(mode, m, n, x, I, dim)%   This function gets as input a vector x and an index set I, and returns%   y = A(:,I)*x if mode = 1, or y = A(:,I)'*x if mode = 2. %   A is the m by dim implicit matrix implemented by the function. I is a%   subset of the columns of A, i.e. a subset of 1:dim of length n. x is a%   vector of length n is mode = 1, or a vector of length m is mode = 2.% References%   B. Efron, T. Hastie, I. Johnstone and R. Tibshirani, %   "Least Angle Regression", Annals of Statistics, 32, 407-499, 2004% See Also%   SolveOMP, SolveBP, SolveStOMP%if nargin < 9,    OptTol = 1e-5;endif nargin < 8,    verbose = 0;endif nargin < 7,    solFreq = 0;endif nargin < 6,    lambdaStop = 0;endif nargin < 5,    maxIters = 10*N;endif nargin < 4,    algType = 'lasso';endswitch lower(algType)    case 'lars'        isLasso = 0;    case 'lasso'        isLasso = 1;endexplicitA = ~(ischar(A) || isa(A, 'function_handle'));n = length(y);% Global variables for linsolve functionglobal opts opts_tr machPrecopts.UT = true; opts_tr.UT = true; opts_tr.TRANSA = true;machPrec = 1e-5;x = zeros(N,1);iter = 0;% First vector to enter the active set is the one with maximum correlationif (explicitA)    corr = A'*y;             else    corr = feval(A,2,n,N,y,1:N,N); % = A'*y             endlambda = max(abs(corr));newIndices = find(abs(abs(corr)-lambda) < machPrec)';    % Initialize Cholesky factor of A_IR_I = [];activeSet = [];for j = 1:length(newIndices)    iter = iter+1;    [R_I, flag] = updateChol(R_I, n, N, A, explicitA, activeSet, newIndices(j));    activeSet = [activeSet newIndices(j)];    if verbose        fprintf('Iteration %d: Adding variable %d\n', iter, activeSet(j));    endendactivationHist = activeSet;collinearIndices = [];sols = [];done = 0;while  ~done    % Compute Lars direction - Equiangular vector    dx = zeros(N,1);    % Solve the equation (A_I'*A_I)dx_I = corr_I    z = linsolve(R_I,corr(activeSet),opts_tr);    dx(activeSet) = linsolve(R_I,z,opts);    if (explicitA)        dmu = A'*(A(:,activeSet)*dx(activeSet));    else        dmu = feval(A,1,n,length(activeSet),dx(activeSet),activeSet,N);         dmu = feval(A,2,n,N,dmu,1:N,N);     end    % For Lasso, Find first active vector to violate sign constraint    if isLasso        zc = -x(activeSet)./dx(activeSet);        gammaI = min([zc(zc > 0); inf]);        removeIndices = activeSet(find(zc == gammaI));    else        gammaI = Inf;        removeIndices = [];    end    % Find first inactive vector to enter the active set    if (length(activeSet) >= min(n, N))        gammaIc = 1;    else        inactiveSet = 1:N;        inactiveSet(activeSet) = 0;        inactiveSet(collinearIndices) = 0;        inactiveSet = find(inactiveSet > 0);        lambda = abs(corr(activeSet(1)));        dmu_Ic = dmu(inactiveSet);        c_Ic = corr(inactiveSet);        epsilon = 1e-12;         gammaArr = [(lambda-c_Ic)./(lambda - dmu_Ic + epsilon) (lambda+c_Ic)./(lambda + dmu_Ic + epsilon)]';        gammaArr(gammaArr < machPrec) = inf;        gammaArr = min(gammaArr)';        [gammaIc, Imin] = min(gammaArr);    end    % If gammaIc = 1, we are at the LS solution    if (1-gammaIc) < OptTol        newIndices = [];    else        newIndices = inactiveSet(find(abs(gammaArr - gammaIc) < machPrec));        %newIndices = inactiveSet(Imin);    end    gammaMin = min(gammaIc,gammaI);    % Compute the next Lars step    x = x + gammaMin*dx;    corr = corr - gammaMin*dmu;    % Check stopping condition    if ((1-gammaMin) < OptTol) | ((lambdaStop > 0) & (lambda <= lambdaStop))        done = 1;    end    % Add new indices to active set    if (gammaIc <= gammaI) && (length(newIndices) > 0)        for j = 1:length(newIndices)            iter = iter+1;            if verbose                fprintf('Iteration %d: Adding variable %d\n', iter, newIndices(j));            end            % Update the Cholesky factorization of A_I            [R_I, flag] = updateChol(R_I, n, N, A, explicitA, activeSet, newIndices(j));            % Check for collinearity            if (flag)                collinearIndices = [collinearIndices newIndices(j)];                if verbose                    fprintf('Iteration %d: Variable %d is collinear\n', iter, newIndices(j));                end            else                activeSet = [activeSet newIndices(j)];                activationHist = [activationHist newIndices(j)];            end        end    end    % Remove violating indices from active set    if (gammaI <= gammaIc)        for j = 1:length(removeIndices)            iter = iter+1;            col = find(activeSet == removeIndices(j));            if verbose                fprintf('Iteration %d: Dropping variable %d\n', iter, removeIndices(j));            end            % Downdate the Cholesky factorization of A_I            R_I = downdateChol(R_I,col);            activeSet = [activeSet(1:col-1), activeSet(col+1:length(activeSet))];                        % Reset collinear set            collinearIndices = [];        end        x(removeIndices) = 0;  % To avoid numerical errors        activationHist = [activationHist -removeIndices];    end    if iter >= maxIters        done = 1;    end    if done | ((solFreq > 0) & (~mod(iter,solFreq)))        sols = [sols x];    endendnumIters = iter;clear opts opts_tr machPrec%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [R, flag] = updateChol(R, n, N, A, explicitA, activeSet, newIndex)% 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 machPrecflag = 0;if (explicitA)    newVec = A(:,newIndex);else    e = zeros(N,1);    e(newIndex) = 1;    newVec = feval(A,1,n,N,e,1:N,N); endif length(activeSet) == 0,    R = sqrt(sum(newVec.^2));else    if (explicitA)        p = linsolve(R,A(:,activeSet)'*A(:,newIndex),opts_tr);    else        AnewVec = feval(A,2,n,length(activeSet),newVec,activeSet,N);        p = linsolve(R,AnewVec,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)];    endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function R = downdateChol(R, j)% downdateChol: `Downdates' the cholesky factor R by removing the % column indexed by j.% Remove the j-th columnR(:,j) = [];[m,n] = size(R);% R now has nonzeros below the diagonal in columns j through n.% We use plane rotations to zero the 'violating nonzeros'.for k = j:n    p = k:k+1;    [G,R(p,k)] = planerot(R(p,k));    if k < n        R(p,k+1:n) = G*R(p,k+1:n);    endend% Remove last row of zeros from RR = R(1:n,:);%% Copyright (c) 2006. Yaakov Tsaig and Joshua Sweetkind-Singer%  %% Part of SparseLab Version:100% Created Tuesday March 28, 2006% This is Copyrighted Material% For Copying permissions see COPYING.m% Comments? e-mail sparselab@stanford.edu%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -