LPP代码及其注释

function [eigvector, eigvalue] = LPP(W, options, data)
% LPP: Locality Preserving Projections
%
%       [eigvector, eigvalue] = LPP(W, options, data)

%             Input:
%               data       - Data matrix. Each row vector of fea is a data point.
%               W       - Affinity matrix(关联矩阵). You can either call "constructW"
%                         to construct the W, or construct it by yourself.
%               options - Struct value in Matlab. The fields in options
%                         that can be set:
%                           
%                         Please see LGE.m for other options.
%
%             Output:
%               eigvector - Each column is an embedding function, for a new
%                           data point (row vector) x,  y = x*eigvector
%                           will be the embedding result of x.
%               eigvalue  - The sorted eigvalue of LPP eigen-problem. 

%
%    Examples:
%
%       fea = rand(50,70);
%       options = [];
%       options.Metric = 'Euclidean';   //欧氏距离定义: 欧氏距离( Euclidean distance)是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。
%       options.NeighborMode = 'KNN';//Put an edge between two nodes if and only if they are among the k nearst neighbors of each other. You are required to provide the parameter k in the options.                                    [Default One]                                                                       
%       options.k = 5;  //Default
%       options.WeightMode = 'HeatKernel'; //Indicates how to assign  weights for each edge in the
%                                             graph.'HeatKernel'   - If nodes i and j are connected, put weight
%                                             W_ij = exp(-norm(x_i - x_j)/2t^2). You are 
%                                             required to provide the parameter t. [Default One]
%                         
%                                          
%       options.t = 5;
%       W = constructW(fea,options);
%       options.PCARatio = 0.99      //The percentage of principal component
%                                     kept in the PCA step.The percentage is
%                                     calculated based on the eigenvalue.
%       [eigvector, eigvalue] = LPP(W, options, fea);
%       Y = fea*eigvector;
%       
%       
%       fea = rand(50,70);
%                                                 gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4];  //The parameter needed under 'Supervised'NeighborMode.
%                                                                      Colunm vector of the label information for each data point.                                                        
%       options = [];
%       options.Metric = 'Euclidean';
%       options.NeighborMode = 'Supervised'; //k > 0 Put an edge between
%                                             two nodes if they belong to same class and they are among the k nearst neighbors of each other. 
%       options.gnd = gnd;
%       options.bLDA = 1;         //If 1, the graph will be constructed to
%                                  make LPP exactly same as LDA. Default will  be 0.
%       W = constructW(fea,options);      
%       options.PCARatio = 1;  
%                                                    
%       [eigvector, eigvalue] = LPP(W, options, fea);
%       Y = fea*eigvector;


% Note: After applying some simple algebra, the smallest eigenvalue problem:
% data^T*L*data = \lemda data^T*D*data
%      is equivalent to the largest eigenvalue problem:
% data^T*W*data = \beta data^T*D*data
% where L=D-W;  \lemda= 1 - \beta.
% Thus, the smallest eigenvalue problem can be transformed to a largest 
% eigenvalue problem. Such tricks are adopted in this code for the 
% consideration of calculation precision of Matlab.

%
% See also constructW, LGE





if (~exist('options','var'))  %不存在返回1,存在返回0
   options = [];
end


[nSmp,nFea] = size(data); %返回data的行数和列数,分别保存在nSmp和nFea中
if size(W,1) ~= nSmp   %size()返回矩阵的行数
    error('W and data mismatch!');
end




%==========================
% If data is too large, the following centering codes can be commented 
% options.keepMean = 1;
%==========================
if isfield(options,'keepMean') && options.keepMean; %isfield()检查options是否包含由keepMean指定的域,判断输入是否是结构体数组的域。
else
    if issparse(data)
        data = full(data); %把稀疏矩阵转换为全矩阵存储在data
    end
    sampleMean = mean(data);%data是一个向量,mean(A)返回A中元素的平均值,如果是一个矩阵,mean(A)将其中的各列视为向量,求其平均值。
    data = (data - repmat(sampleMean,nSmp,1)); %repmat()是对sampleMean矩阵进行指定的行数nSmp和列数1的复制。
end
%==========================








D = full(sum(W,2)); %sum(W,2)对W的行求和  %*D变成50行1列




if ~isfield(options,'Regu') || ~options.Regu 
    DToPowerHalf = D.^.5;       %*DToPowerHalf为50行1列
    D_mhalf = DToPowerHalf.^-1;   %*D_mhalf为50行1列


    if nSmp < 5000  %nSmp行数
        tmpD_mhalf = repmat(D_mhalf,1,nSmp);  %*将D_mhalf放大到50列,此时tmpD_mhalf是50*50
        W = (tmpD_mhalf.*W).*tmpD_mhalf';
        clear tmpD_mhalf;
    else
        [i_idx,j_idx,v_idx] = find(W); %找出i_idx非0元素所在的行,j_idx非0元素所在的列,v_idx非0元素的值。
        v1_idx = zeros(size(v_idx)); %返回v_idx的行数和列数
        for i=1:length(v_idx)
            v1_idx(i) = v_idx(i)*D_mhalf(i_idx(i))*D_mhalf(j_idx(i));
        end
        W = sparse(i_idx,j_idx,v1_idx);  %转化为稀疏矩阵,把0全去掉
        clear i_idx j_idx v_idx v1_idx
    end
    W = max(W,W');
    
    data = repmat(DToPowerHalf,1,nFea).*data;
    [eigvector, eigvalue] = LGE(W, [], options, data);
else
    options.ReguAlpha = options.ReguAlpha*sum(D)/length(D);


    D = sparse(1:nSmp,1:nSmp,D,nSmp,nSmp); %由1:nSmp,1:nSmp,D组成的nSmp*nSmp的稀疏矩阵
    [eigvector, eigvalue] = LGE(W, D, options, data);
end




eigIdx = find(eigvalue < 1e-3);
eigvalue (eigIdx) = [];
eigvector(:,eigIdx) = [];

































猜你喜欢

转载自blog.csdn.net/qq_35774189/article/details/76560003