zoukankan      html  css  js  c++  java
  • 基于PCA人脸识别算法的Matlab实现(2)

    基于人脸年识别算法PCA的另一个matlab工程

    妈妈再也不用担心我的人脸识别算法,

    但是怎么移植到嵌入式系统上,

    要用C重构的话,

    我选择死亡。

    main.m

    clear all
    clc
    close all
    
    database=[pwd 'ORL'];%使用的人脸库
    train_samplesize=5;%每类训练样本数
    address=[database 's'];
    rows=112;
    cols=92;
    ClassNum=40;
    tol_num=10;
    image_fmt='.bmp';
    
    %------------------------PCA降维
    train=1:train_samplesize;
    test=train_samplesize+1:tol_num;
    
    train_num=length(train);
    test_num=length(test);
    
    train_tol=train_num*ClassNum;
    test_tol=test_num*ClassNum;
    
    [train_sample,train_label]=readsample(address,ClassNum,train,rows,cols,image_fmt);
    [test_sample,test_label]=readsample(address,ClassNum,test,rows,cols,image_fmt);
    
    for pro_dim=40:10:90
        %PCA降维
        [Pro_Matrix,Mean_Image]=my_pca(train_sample,pro_dim);
        train_project=Pro_Matrix'*train_sample;
        test_project=Pro_Matrix'*test_sample;
        
        %单位化
        train_norm=normc(train_project);
        test_norm=normc(test_project);
        
        accuracy=computaccuracy(train_norm,ClassNum,train_label,test_norm,test_label);
        fprintf('投影维数为:%d
    ',pro_dim);
        fprintf('每类训练样本个数为:%d
    ',train_samplesize);
        fprintf(2,'识别率为:%3.2f%%
    
    ',accuracy*100);
    end
    

      

    computaccuracy.m

    function [accuracy,xp,r]=computaccuracy(trainsample,classnum,train_label,testsample,test_label)
    test_tol=size(testsample,2);
    train_tol=size(trainsample,2);
    pre_label=zeros(1,test_tol);
    h = waitbar(0,'Please wait...');
    for i=1:test_tol
        xp = SolveHomotopy_CBM_std(trainsample, testsample(:,i),'lambda', 0.01);
        for j=1:classnum
            mmu=zeros(train_tol,1);
            ind=(j==train_label);
            mmu(ind)=xp(ind);
            r(j)=norm(testsample(:,i)-trainsample*mmu);
        end
        [temp,index]=min(r);
        pre_label(i)=index;
        % computations take place here
        per = i / test_tol;
        waitbar(per, h ,sprintf('%2.0f%%',per*100))
    end
    close(h)
    accuracy=sum(pre_label==test_label)/test_tol;
    

      

    l1eq_pd.m

    % l1eq_pd.m
    %
    % Solve
    % min_x ||x||_1  s.t.  Ax = b
    %
    % Recast as linear program
    % min_{x,u} sum(u)  s.t.  -u <= x <= u,  Ax=b
    % and use primal-dual interior point method
    %
    % Usage: xp = l1eq_pd(x0, A, At, b, pdtol, pdmaxiter, cgtol, cgmaxiter)
    %
    % x0 - Nx1 vector, initial point.
    %
    % A - Either a handle to a function that takes a N vector and returns a K
    %     vector , or a KxN matrix.  If A is a function handle, the algorithm
    %     operates in "largescale" mode, solving the Newton systems via the
    %     Conjugate Gradients algorithm.
    %
    % At - Handle to a function that takes a K vector and returns an N vector.
    %      If A is a KxN matrix, At is ignored.
    %
    % b - Kx1 vector of observations.
    %
    % pdtol - Tolerance for primal-dual algorithm (algorithm terminates if
    %     the duality gap is less than pdtol).
    %     Default = 1e-3.
    %
    % pdmaxiter - Maximum number of primal-dual iterations.
    %     Default = 50.
    %
    % cgtol - Tolerance for Conjugate Gradients; ignored if A is a matrix.
    %     Default = 1e-8.
    %
    % cgmaxiter - Maximum number of iterations for Conjugate Gradients; ignored
    %     if A is a matrix.
    %     Default = 200.
    %
    % Written by: Justin Romberg, Caltech
    % Email: jrom@acm.caltech.edu
    % Created: October 2005
    %
    
    function xp = l1eq_pd(x0, A, At, b, pdtol, pdmaxiter, cgtol, cgmaxiter)
    
    largescale = isa(A,'function_handle');
    
    if (nargin < 5), pdtol = 1e-3;  end
    if (nargin < 6), pdmaxiter = 50;  end
    if (nargin < 7), cgtol = 1e-8;  end
    if (nargin < 8), cgmaxiter = 200;  end
    
    N = length(x0);
    
    alpha = 0.01;
    beta = 0.5;
    mu = 10;
    
    gradf0 = [zeros(N,1); ones(N,1)];
    
    x = x0;
    u = (0.95)*abs(x0) + (0.10)*max(abs(x0));
    
    fu1 = x - u;
    fu2 = -x - u;
    
    lamu1 = -1./fu1;
    lamu2 = -1./fu2;
    if (largescale)
        v = -A(lamu1-lamu2);
        Atv = At(v);
        rpri = A(x) - b;
    else
        v = -A*(lamu1-lamu2);
        Atv = A'*v;
        rpri = A*x - b;
    end
    
    sdg = -(fu1'*lamu1 + fu2'*lamu2);
    tau = mu*2*N/sdg;
    
    rcent = [-lamu1.*fu1; -lamu2.*fu2] - (1/tau);
    rdual = gradf0 + [lamu1-lamu2; -lamu1-lamu2] + [Atv; zeros(N,1)];
    resnorm = norm([rdual; rcent; rpri]);
    
    pditer = 0;
    done = (sdg < pdtol) | (pditer >= pdmaxiter);
    while (~done)
        
        pditer = pditer + 1;
        
        w1 = -1/tau*(-1./fu1 + 1./fu2) - Atv;
        w2 = -1 - 1/tau*(1./fu1 + 1./fu2);
        w3 = -rpri;
        
        sig1 = -lamu1./fu1 - lamu2./fu2;
        sig2 = lamu1./fu1 - lamu2./fu2;
        sigx = sig1 - sig2.^2./sig1;
        
        if (largescale)
            w1p = w3 - A(w1./sigx - w2.*sig2./(sigx.*sig1));
            h11pfun = @(z) -A(1./sigx.*At(z));
            [dv, cgres, cgiter] = cgsolve(h11pfun, w1p, cgtol, cgmaxiter, 0);
            if (cgres > 1/2)
                disp('Primal-dual: Cannot solve system.  Returning previous iterate.');
                xp = x;
                return
            end
            dx = (w1 - w2.*sig2./sig1 - At(dv))./sigx;
            Adx = A(dx);
            Atdv = At(dv);
        else
            H11p = -A*diag(1./sigx)*A';
            w1p = w3 - A*(w1./sigx - w2.*sig2./(sigx.*sig1));
            [dv,hcond] = linsolve(H11p,w1p);
            if (hcond < 1e-14)
                disp('Primal-dual: Matrix ill-conditioned.  Returning previous iterate.');
                xp = x;
                return
            end
            dx = (w1 - w2.*sig2./sig1 - A'*dv)./sigx;
            Adx = A*dx;
            Atdv = A'*dv;
        end
        
        du = (w2 - sig2.*dx)./sig1;
        
        dlamu1 = (lamu1./fu1).*(-dx+du) - lamu1 - (1/tau)*1./fu1;
        dlamu2 = (lamu2./fu2).*(dx+du) - lamu2 - 1/tau*1./fu2;
        
        % make sure that the step is feasible: keeps lamu1,lamu2 > 0, fu1,fu2 < 0
        indp = find(dlamu1 < 0);  indn = find(dlamu2 < 0);
        s = min([1; -lamu1(indp)./dlamu1(indp); -lamu2(indn)./dlamu2(indn)]);
        indp = find((dx-du) > 0);  indn = find((-dx-du) > 0);
        s = (0.99)*min([s; -fu1(indp)./(dx(indp)-du(indp)); -fu2(indn)./(-dx(indn)-du(indn))]);
        
        % backtracking line search
        backiter = 0;
        xp = x + s*dx;  up = u + s*du;
        vp = v + s*dv;  Atvp = Atv + s*Atdv;
        lamu1p = lamu1 + s*dlamu1;  lamu2p = lamu2 + s*dlamu2;
        fu1p = xp - up;  fu2p = -xp - up;
        rdp = gradf0 + [lamu1p-lamu2p; -lamu1p-lamu2p] + [Atvp; zeros(N,1)];
        rcp = [-lamu1p.*fu1p; -lamu2p.*fu2p] - (1/tau);
        rpp = rpri + s*Adx;
        while(norm([rdp; rcp; rpp]) > (1-alpha*s)*resnorm)
            s = beta*s;
            xp = x + s*dx;  up = u + s*du;
            vp = v + s*dv;  Atvp = Atv + s*Atdv;
            lamu1p = lamu1 + s*dlamu1;  lamu2p = lamu2 + s*dlamu2;
            fu1p = xp - up;  fu2p = -xp - up;
            rdp = gradf0 + [lamu1p-lamu2p; -lamu1p-lamu2p] + [Atvp; zeros(N,1)];
            rcp = [-lamu1p.*fu1p; -lamu2p.*fu2p] - (1/tau);
            rpp = rpri + s*Adx;
            backiter = backiter+1;
            if (backiter > 32)
                disp('Stuck backtracking, returning last iterate.')
                xp = x;
                return
            end
        end
        
        
        % next iteration
        x = xp;  u = up;
        v = vp;  Atv = Atvp;
        lamu1 = lamu1p;  lamu2 = lamu2p;
        fu1 = fu1p;  fu2 = fu2p;
        
        % surrogate duality gap
        sdg = -(fu1'*lamu1 + fu2'*lamu2);
        tau = mu*2*N/sdg;
        rpri = rpp;
        rcent = [-lamu1.*fu1; -lamu2.*fu2] - (1/tau);
        rdual = gradf0 + [lamu1-lamu2; -lamu1-lamu2] + [Atv; zeros(N,1)];
        resnorm = norm([rdual; rcent; rpri]);
        
        done = (sdg < pdtol) | (pditer >= pdmaxiter);
        
        %disp(sprintf('Iteration = %d, tau = %8.3e, Primal = %8.3e, PDGap = %8.3e, Dual res = %8.3e, Primal res = %8.3e',...
        % pditer, tau, sum(u), sdg, norm(rdual), norm(rpri)));
        %  if (largescale)
        %   disp(sprintf('                  CG Res = %8.3e, CG Iter = %d', cgres, cgiter));
        % else
        %  disp(sprintf('                  H11p condition number = %8.3e', hcond));
        % end
        
    end
    

      

    my_pca.m

    function [Pro_Matrix,Mean_Image]=my_pca(Train_SET,Eigen_NUM)
    %输入:
    %Train_SET:训练样本集,每列是一个样本,每行一类特征,Dim*Train_Num
    %Eigen_NUM:投影维数
    
    %输出:
    %Pro_Matrix:投影矩阵
    %Mean_Image:均值图像
    
    [Dim,Train_Num]=size(Train_SET);
    
    %当训练样本数大于样本维数时,直接分解协方差矩阵
    if Dim<=Train_Num
        Mean_Image=mean(Train_SET,2);
        Train_SET=bsxfun(@minus,Train_SET,Mean_Image);
        R=Train_SET*Train_SET'/(Train_Num-1);
        
        [eig_vec,eig_val]=eig(R);
        eig_val=diag(eig_val);
        [~,ind]=sort(eig_val,'descend');
        W=eig_vec(:,ind);
        Pro_Matrix=W(:,1:Eigen_NUM);
        
    else
        %构造小矩阵,计算其特征值和特征向量,然后映射到大矩阵
        Mean_Image=mean(Train_SET,2);
        Train_SET=bsxfun(@minus,Train_SET,Mean_Image);
        R=Train_SET'*Train_SET/(Train_Num-1);
        
        [eig_vec,eig_val]=eig(R);
        eig_val=diag(eig_val);
        [val,ind]=sort(eig_val,'descend');
        W=eig_vec(:,ind);
        Pro_Matrix=Train_SET*W(:,1:Eigen_NUM)*diag(val(1:Eigen_NUM).^(-1/2));
    end
    
    end
    

      

    pca.m

    function [newsample,basevector]=pca(patterns,num)
    %主分量分析程序,patterns表示输入模式向量,num为控制变量,当num大于1的时候表示
    %要求去的特征数为num,当num大于0小于等于1的时候表示求取的特征数的能量为num
    %输出:basevector表示求取的最大特征值对应的特征向量,newsample表示在basevector
    %映射下获得的样本表示。
    [u,v]=size(patterns);
    totalsamplemean=mean(patterns);
    for i=1:u
        gensample(i,:)=patterns(i,:)-totalsamplemean;
    end
    sigma=gensample*gensample';
    [U,V]=eig(sigma);
    d=diag(V);
    [d1,index]=dsort(d);
    if num>1
        for i=1:num
            vector(:,i)=U(:,index(i));
            base(:,i)=d(index(i))^(-1/2)* gensample' * vector(:,i);
        end
    else
        sumv=sum(d1);
        for i=1:u
            if sum(d1(1:i))/sumv>=num
                l=i;
                break;
            end
        end
        for i=1:l
            vector(:,i)=U(:,index(i));
            base(:,i)=d(index(i))^(-1/2)* gensample' * vector(:,i);
        end
    end
    newsample=patterns*base;
    basevector=base;
    

      

    readsample.m

    function [sample,label]=readsample(address,ClassNum,data,rows,cols,image_fmt)
    %这个函数用来读取样本。
    %输入:
    %address:要读取的样本的路径
    %ClassNum:代表要读入样本的类别数
    %data:样本索引
    %rows:样本行数
    %cols:样本列数
    %image_fmt:图片格式
    
    %输出:
    %sample:样本矩阵,每列为一个样本,每行为一类特征
    %label:样本标签
    
    allsamples=[];
    label=[];
    ImageSize=rows*cols;
    for i=1:ClassNum
        for j=data
            a=double(imread(strcat(address,num2str(i),'_',num2str(j),image_fmt)));
            a=imresize(a,[rows cols]);
            b=reshape(a,ImageSize,1);
            allsamples=[allsamples,b];
            label=[label,i];
        end
    end
    sample=allsamples;
    

      

    SolveHomotopy_CBM_std.m

    %% This function is modified from Matlab Package: L1-Homotopy
    
    % BPDN_homotopy_function.m
    %
    % Solves the following basis pursuit denoising (BPDN) problem
    % min_x  lambda ||x||_1 + 1/2*||y-Ax||_2^2
    %
    % Inputs:
    % A - m x n measurement matrix
    % y - measurement vector
    % lambda - final value of regularization parameter
    % maxiter - maximum number of homotopy iterations
    %
    % Outputs:
    % x_out - output for BPDN
    % total_iter - number of homotopy iterations taken by the solver
    %
    % Written by: Salman Asif, Georgia Tech
    % Email: sasif@ece.gatech.edu
    %
    %-------------------------------------------+
    % Copyright (c) 2007.  Muhammad Salman Asif
    %-------------------------------------------+
    
    function [x_out, e_out, total_iter] = SolveHomotopy_CBM_std(A, y, varargin)
    
    global N n gamma_x z_x  xk_temp del_x_vec pk_temp dk epsilon isNonnegative
    
    t0 = tic ;
    
    lambda = 1e-6;
    maxiter = 100;
    isNonnegative = false;
    verbose = false;
    xk_1 = [];
    tolerance = 1e-4 ;
    
    STOPPING_TIME = -2;
    STOPPING_GROUND_TRUTH = -1;
    STOPPING_DUALITY_GAP = 1;
    STOPPING_SPARSE_SUPPORT = 2;
    STOPPING_OBJECTIVE_VALUE = 3;
    STOPPING_SUBGRADIENT = 4;
    STOPPING_DEFAULT = STOPPING_OBJECTIVE_VALUE;
    
    stoppingCriterion = STOPPING_DEFAULT;
    
    % Parse the optional inputs.
    if (mod(length(varargin), 2) ~= 0 ),
        error(['Extra Parameters passed to the function ''' mfilename ''' must be passed in pairs.']);
    end
    parameterCount = length(varargin)/2;
    
    for parameterIndex = 1:parameterCount,
        parameterName = varargin{parameterIndex*2 - 1};
        parameterValue = varargin{parameterIndex*2};
        switch lower(parameterName)
            case 'stoppingcriterion'
                stoppingCriterion = parameterValue;
            case 'initialization'
                xk_1 = parameterValue;
                if ~all(size(xk_1)==[n,1])
                    error('The dimension of the initial x0 does not match.');
                end
            case 'groundtruth'
                xG = parameterValue;
            case 'lambda'
                lambda = parameterValue;
            case 'maxiteration'
                maxiter = parameterValue;
            case 'isnonnegative'
                isNonnegative = parameterValue;
            case 'tolerance'
                tolerance = parameterValue;
            case 'verbose'
                verbose = parameterValue;
            case 'maxtime'
                maxTime = parameterValue;
            otherwise
                error(['The parameter ''' parameterName ''' is not recognized by the function ''' mfilename '''.']);
        end
    end
    clear varargin
    
    [K, n] = size(A);
    B = [A eye(K)];
    At = A';
    Bt = B';
    N = K + n;
    
    timeSteps = nan(1,maxiter) ;
    
    % Initialization of primal and dual sign and support
    z_x = zeros(N,1);
    gamma_x = [];       % Primal support
    
    % Initial step
    Primal_constrk = -[At*y; y];
    
    if isNonnegative
        [c i]  = min(Primal_constrk);
        c = max(-c, 0);
    else
        [c i] = max(abs(Primal_constrk));
    end
    
    epsilon = c;
    nz_x = zeros(N,1);
    if isempty(xk_1)
        xk_1 = zeros(N,1);
        gamma_xk = i;
    else
        gamma_xk = find(abs(xk_1)>eps*10);
        nz_x(gamma_xk) = 1;
    end
    f = epsilon*norm(xk_1,1) + 1/2*norm(y - A*xk_1(1:n) - xk_1(n+1:end))^2;
    z_x(gamma_xk) = -sign(Primal_constrk(gamma_xk));
    %Primal_constrk(gamma_xk) = sign(Primal_constrk(gamma_xk))*epsilon;
    
    z_xk = z_x;
    
    % loop parameters
    iter = 0;
    out_x = [];
    old_delta = 0;
    count_delta_stop = 0;
    
    gamma_xkx = gamma_xk(gamma_xk<=n);
    gamma_xke = gamma_xk(gamma_xk>n)-n;
    AtgxAgx = [At(gamma_xkx,:)*A(:,gamma_xkx) At(gamma_xkx,gamma_xke); A(gamma_xke,gamma_xkx) eye(length(gamma_xke))];
    iAtgxAgx = inv(AtgxAgx);
    
    while iter < maxiter
        
        iter = iter+1;
        
        gamma_x = gamma_xk;
        gamma_xx = gamma_x(gamma_x<=n);
        gamma_xe = gamma_x(gamma_x>n)-n;
        z_x = z_xk;
        x_k = xk_1;
        
        %%%%%%%%%%%%%%%%%%%%%
        %%%% update on x %%%%
        %%%%%%%%%%%%%%%%%%%%%
        
        % Update direction
        del_x = iAtgxAgx*z_x(gamma_x);
        del_x_vec = zeros(N,1);
        del_x_vec(gamma_x) = del_x;
        
        Asupported = B(:,gamma_x);
        Agdelx = Asupported*del_x;
        dk = [At*Agdelx; Agdelx];
        
        %%% CONTROL THE MACHINE PRECISION ERROR AT EVERY OPERATION: LIKE BELOW.
        pk_temp = Primal_constrk;
        gammaL_temp = find(abs(abs(Primal_constrk)-epsilon)<min(epsilon,2*eps));
        pk_temp(gammaL_temp) = sign(Primal_constrk(gammaL_temp))*epsilon;
        
        xk_temp = x_k;
        xk_temp(abs(x_k)<2*eps) = 0;
        %%%---
        
        % Compute the step size
        [i_delta, delta, out_x] = update_primal(out_x);
        
        if old_delta < 4*eps && delta < 4*eps
            count_delta_stop = count_delta_stop + 1;
            
            if count_delta_stop >= 500
                if verbose
                    disp('stuck in some corner');
                end
                break;
            end
        else
            count_delta_stop = 0;
        end
        old_delta = delta;
        
        xk_1 = x_k+delta*del_x_vec;
        Primal_constrk = Primal_constrk+delta*dk;
        epsilon_old = epsilon;
        epsilon = epsilon-delta;
        
        if epsilon <= lambda;
            % xk_1 = x_k + (epsilon_old-lambda)*del_x_vec;
            % disp('Reach prescribed lambda in SolveHomotopy_CBM.');
            break;
        end
        
        timeSteps(iter) = toc(t0) ;
        %     if mod(iter, 100) == 0
        %         disp([ 'epsilon = ' num2str(epsilon) ', time =' num2str(timeSteps(iter))]);
        %     end
        
        % compute stopping criteria and test for termination
        keep_going = true;
        if delta~=0
            switch stoppingCriterion
                case STOPPING_GROUND_TRUTH
                    keep_going = norm(xk_1(1:n)-xG)>tolerance;
                case STOPPING_SPARSE_SUPPORT
                    nz_x_prev = nz_x;
                    nz_x = (abs(xk_1)>eps*10);
                    num_nz_x = sum(nz_x(:));
                    num_changes_active = (sum(nz_x(:)~=nz_x_prev(:)));
                    if num_nz_x >= 1
                        criterionActiveSet = num_changes_active / num_nz_x;
                        keep_going = (criterionActiveSet > tolerance);
                    end
                case STOPPING_DUALITY_GAP
                    error('Duality gap is not a valid stopping criterion for Homotopy.');
                case STOPPING_OBJECTIVE_VALUE
                    % continue if not yeat reached target value tolA
                    prev_f = f;
                    f = lambda*norm(xk_1,1) + 1/2*norm(y-Asupported*xk_1(gamma_x))^2;
                    keep_going = (abs((prev_f-f)/prev_f) > tolerance);
                case STOPPING_SUBGRADIENT
                    keep_going = norm(delta*del_x_vec)>tolerance;
                case STOPPING_TIME
                    keep_going = timeSteps(iter) < maxTime ;
                otherwise,
                    error('Undefined stopping criterion');
            end % end of the stopping criteria switch
        end
        
        if ~keep_going
            disp('Maximum time reached!');
            break;
        end
        
        if ~isempty(out_x)
            % If an element is removed from gamma_x
            len_gamma = length(gamma_x);
            outx_index = find(gamma_x==out_x(1));
            gamma_x(outx_index) = gamma_x(end);
            gamma_x = gamma_x(1:end-1);
            gamma_xk = gamma_x;
            
            rowi = outx_index; % ith row of A is swapped with last row (out_x)
            colj = outx_index; % jth column of A is swapped with last column (out_lambda)
            AtgxAgx_ij = AtgxAgx;
            temp_row = AtgxAgx_ij(rowi,:);
            AtgxAgx_ij(rowi,:) = AtgxAgx_ij(len_gamma,:);
            AtgxAgx_ij(len_gamma,:) = temp_row;
            temp_col = AtgxAgx_ij(:,colj);
            AtgxAgx_ij(:,colj) = AtgxAgx_ij(:,len_gamma);
            AtgxAgx_ij(:,len_gamma) = temp_col;
            iAtgxAgx_ij = iAtgxAgx;
            temp_row = iAtgxAgx_ij(colj,:);
            iAtgxAgx_ij(colj,:) = iAtgxAgx_ij(len_gamma,:);
            iAtgxAgx_ij(len_gamma,:) = temp_row;
            temp_col = iAtgxAgx_ij(:,rowi);
            iAtgxAgx_ij(:,rowi) = iAtgxAgx_ij(:,len_gamma);
            iAtgxAgx_ij(:,len_gamma) = temp_col;
            
            AtgxAgx = AtgxAgx_ij(1:len_gamma-1,1:len_gamma-1);
            
            nn = size(AtgxAgx_ij,1);
            %delete columns
            Q11 = iAtgxAgx_ij(1:nn-1,1:nn-1);
            Q12 = iAtgxAgx_ij(1:nn-1,nn);
            Q21 = iAtgxAgx_ij(nn,1:nn-1);
            Q22 = iAtgxAgx_ij(nn,nn);
            Q12Q21_Q22 = Q12*(Q21/Q22);
            iAtgxAgx = Q11 - Q12Q21_Q22;
            
            xk_1(out_x(1)) = 0;
        else
            % If an element is added to gamma_x
            gamma_xk = [gamma_xk; i_delta];
            
            if i_delta>n
                AtgxAnx = Bt(gamma_x,i_delta-n);
                AtgxAgx_mod = [AtgxAgx AtgxAnx; AtgxAnx' 1];
            else
                AtgxAnx = Bt(gamma_x,:)*A(:,i_delta);
                AtgxAgx_mod = [AtgxAgx AtgxAnx; AtgxAnx' A(:,i_delta).'*A(:,i_delta)];
            end
            
            AtgxAgx = AtgxAgx_mod;
            
            %iAtgxAgx = update_inverse(AtgxAgx, iAtgxAgx,1);
            nn = size(AtgxAgx,1);
            % add columns
            iA11 = iAtgxAgx;
            iA11A12 = iA11*AtgxAgx(1:nn-1,nn);
            A21iA11 = AtgxAgx(nn,1:nn-1)*iA11;
            S = AtgxAgx(nn,nn)-AtgxAgx(nn,1:nn-1)*iA11A12;
            Q11_right = iA11A12*(A21iA11/S);
            %     Q11 = iA11+ Q11_right;
            %     Q12 = -iA11A12/S;
            %     Q21 = -A21iA11/S;
            %     Q22 = 1/S;
            iAtgxAgx = zeros(nn);
            %iAtB = [Q11 Q12; Q21 Q22];
            iAtgxAgx(1:nn-1,1:nn-1) = iA11+ Q11_right;
            iAtgxAgx(1:nn-1,nn) = -iA11A12/S;
            iAtgxAgx(nn,1:nn-1) =  -A21iA11/S;
            iAtgxAgx(nn,nn) = 1/S;
            
            xk_1(i_delta) = 0;
        end
        
        z_xk = zeros(N,1);
        z_xk(gamma_xk) = -sign(Primal_constrk(gamma_xk));
        Primal_constrk(gamma_x) = sign(Primal_constrk(gamma_x))*epsilon;
        
    end
    total_iter = iter;
    
    x_out = xk_1(1:n);
    e_out = xk_1(n+1:end);
    
    timeSteps = timeSteps(1:total_iter-1) ;
    
    % Debiasing
    % x_out = zeros(N,1);
    % x_out(intersect(gamma_x,1:n)) = A(:,intersect(gamma_x,1:n))(y-e_out);
    
    % update_primal.m
    %
    % This function computes the minimum step size in the primal update direction and
    % finds change in the primal or dual support with that step.
    %
    % Inputs:
    % gamma_x - current support of x
    % gamma_lambda - current support of lambda
    % z_x - sign sequence of x
    % z_lambda - sign sequence of lambda
    % del_x_vec - primal update direction
    % pk_temp
    % dk
    % epsilon - current value of epsilon
    % out_lambda - element removed from support of lambda in previous step (if any)
    %
    % Outputs:
    % i_delta - index corresponding to newly active primal constraint (new_lambda)
    % out_x - element in x shrunk to zero
    % delta - primal step size
    %
    % Written by: Salman Asif, Georgia Tech
    % Email: sasif@ece.gatech.edu
    
    function [i_delta, delta, out_x] = update_primal(out_x)
    
    global N n gamma_x z_x  xk_temp del_x_vec pk_temp dk epsilon isNonnegative
    
    gamma_lc = setdiff(1:N, union(gamma_x, out_x));
    gamma_lc_nonneg = setdiff(n+1:N, union(gamma_x, out_x));
    
    if isNonnegative
        delta1_constr = (epsilon-pk_temp(gamma_lc_nonneg))./(1+dk(gamma_lc_nonneg));
        delta1_pos_ind = find(delta1_constr>0);
        delta1_pos = delta1_constr(delta1_pos_ind);
        [delta1 i_delta1] = min(delta1_pos);
        if isempty(delta1)
            delta1 = inf;
        end
    else
        delta1_constr = (epsilon-pk_temp(gamma_lc))./(1+dk(gamma_lc));
        delta1_pos_ind = find(delta1_constr>0);
        delta1_pos = delta1_constr(delta1_pos_ind);
        [delta1 i_delta1] = min(delta1_pos);
        if isempty(delta1)
            delta1 = inf;
        end
    end
    
    
    delta2_constr = (epsilon+pk_temp(gamma_lc))./(1-dk(gamma_lc));
    delta2_pos_ind = find(delta2_constr>0);
    delta2_pos = delta2_constr(delta2_pos_ind);
    [delta2 i_delta2] = min(delta2_pos);
    if isempty(delta2)
        delta2 = inf;
    end
    
    if delta1>delta2
        delta = delta2;
        i_delta = gamma_lc(delta2_pos_ind(i_delta2));
    else
        delta = delta1;
        if isNonnegative
            i_delta = gamma_lc_nonneg(delta1_pos_ind(i_delta1));
        else
            i_delta = gamma_lc(delta1_pos_ind(i_delta1));
        end
    end
    
    delta3_constr = (-xk_temp(gamma_x)./del_x_vec(gamma_x));
    delta3_pos_index = find(delta3_constr>0);
    [delta3 i_delta3] = min(delta3_constr(delta3_pos_index));
    out_x_index = gamma_x(delta3_pos_index(i_delta3));
    
    out_x = [];
    if ~isempty(delta3) && (delta3 > 0) && (delta3 <= delta)
        delta = delta3;
        out_x = out_x_index;
    end
    
    %%% THESE ARE PROBABLY UNNECESSARY
    %%% NEED TO REMOVE THEM.
    
    % The following checks are just to deal with degenerate cases when more
    % than one elements want to enter or leave the support at any step
    % (e.g., Bernoulli matrix with small number of measurements)
    
    % This one is ONLY for those indices which are zero. And we don't know where
    % will its dx point in next steps, so after we calculate dx and its in opposite
    % direction to z_x, we will have to remove that index from the support.
    xk_1 = xk_temp+delta*del_x_vec;
    xk_1(out_x) = 0;
    
    wrong_sign = find(sign(xk_1(gamma_x)).*z_x(gamma_x)==-1);
    if isNonnegative
        gamma_x_nonneg = intersect(gamma_x, 1:n);
        wrong_sign = union(wrong_sign, find(xk_1(gamma_x_nonneg)<0));
    end
    if ~isempty(gamma_x(wrong_sign))
        delta = 0;
        % can also choose specific element which became non-zero first but all
        % that matters here is AtA(gx,gl) doesn't become singular.
        [val_wrong_x ind_wrong_x] =  sort(abs(del_x_vec(gamma_x(wrong_sign))),'descend');
        out_x = gamma_x(wrong_sign(ind_wrong_x));
    end
    
    % If more than one primal constraints became active in previous iteration i.e.,
    % more than one elements wanted to enter the support and we added only one.
    % So here we need to check if those remaining elements are still active.
    i_delta_temp = gamma_lc(abs(pk_temp(gamma_lc)+delta*dk(gamma_lc))-(epsilon-delta) >= 10*eps);
    if ~isempty(i_delta_temp)
        
        i_delta_more = i_delta_temp;
        if (length(i_delta_more)>=1) && (~any((i_delta_temp==i_delta)))
            % ideal way would be to check that incoming element doesn't make AtA
            % singular!
            [v_temp i_temp] = max(-pk_temp(i_delta_more)./dk(i_delta_more));
            i_delta = i_delta_more(i_temp);
            delta = 0;
            out_x = [];
        end
    end
    

      

  • 相关阅读:
    SolrCloud阶段总结
    Solr总结
    机器学习算法与Python实践之(六)二分k均值聚类
    机器学习问题方法总结
    浅谈Kmeans聚类
    AVL树的算法思路整理
    Solr4.6从数据库导数据的步骤
    红黑树
    浅谈 Adaboost 算法
    POJ 1836 Alignment
  • 原文地址:https://www.cnblogs.com/MnsterLu/p/5532327.html
Copyright © 2011-2022 走看看