Code covered by the BSD License  

Highlights from
Statistical Learning Toolbox

from Statistical Learning Toolbox by Dahua Lin
Functions for statistical learning, pattern recognition and computer vision, covering many topics.

Description of slnlda
Home > sltoolbox > subspace > slnlda.m

slnlda

PURPOSE ^

SLNLDA Performs Nullspace-based Linear Discriminant Analysis

SYNOPSIS ^

function T = slnlda(X, nums, varargin)

DESCRIPTION ^

SLNLDA Performs Nullspace-based Linear Discriminant Analysis

 $ Syntax $
   - T = slnlda(X, nums)
   - T = slnlda(X, nums, ...)

 $ Arguments $
   - X:        the training sample matrix
   - nums:     the numbers of samples in all classes
   - T:        the solved transform matrix

 $ Description $
   - T = slnlda(X, nums) performs nullspace LDA on the samples X using 
     default settings.

   - T = slnlda(X, nums, ...) performs nullspace LDA on the samples X
     with the specified properties.
     \*
     \t   Table 1.  The properties of Fisher Discriminant Analysis   \\
     \h     name    &     description                                \\
           'prepca' &  Whether to perform a preamble PCA to first 
                       reduce the dimensions to the samples' rank.
                       default = false.                              \\
           'pdimset' &  The cell containing the arguments for determining
                        the dimension of the principal subspace (that is
                        the orthogonal complement of the nullspace)   \\
           'dimset'  &  The cell containing the arguments for determining
                        the output feature dimension. default = {}.
                        (refer to sldim_by_eigval).                   \\
           'Sb'      &  The pre-computed between-class scattering matrix
                        or the cell containing the arguments for 
                        computing the scatter matrix in the form
                        {type, ...}, which is input to slscatter.     \\
           'Sw'      &  The pre-computed within-class scattering matrix
                        or the cell containing the arguments for 
                        computing the scatter matrix in the form
                        {type, ...}, which is input to slscatter.     \\
         'weights'   &  The sample weights. default = [].             \\
     \*  

 $ Remarks $
   -# The function solves the transform in mainly following stages: 
      First, solve the null space of the between-class scattering, then
      project all samples onto the null space. Finally, a PCA-step is 
      conducted to maximize the between-class scattering on nullspace.
      
   -# If Sw or its computing rule is given, the null space is  directly 
      solved from Sw, otherwise the null space is solved from within class 
      differences. If Sb is given, the between-class scattering on null 
      space is computed by directly applying the null space projection
      to Sb, otherwise, Sb is computed from components on nullspace. If 
      both Sb and Sw are given, then the samples are not used in the 
      function. In this cases, you can simply input an empty X. 

   -# If both Sb and Sw are given, the pre-pca step will not be conducted.
      no matter whether prepca is true or false.

 $ History $
   - Created by Dahua Lin on May 1st, 2006
   - Modified by Dahua Lin on Sep 10th, 2006
       - replace sladd by sladdvec and slmul by slmulvec to increase 
         efficiency

CROSS-REFERENCE INFORMATION ^

This function calls:
  • sladdvec SLADDVEC adds a vector to columns or rows of a matrix
  • slmulvec SLMULVEC multiplies a vector to columns or rows of a matrix
  • slsymeig SLSYMEIG Compute the eigenvalues and eigenvectors for symmetric matrix
  • slmeans SLMEANS Compute the mean vectors
  • sldim_by_eigval SLDIM_BY_EIGVAL Determines the dimension of principal subspace by eigenvalues
  • slnullspace SLRANGESPACE Determines the null-space of the range of X
  • slpca SLPCA Learns a PCA model from training samples
  • slscatter SLSCATTER Compute the scatter matrix
  • raise_lackinput RAISE_LACKINPUT Raises an error indicating lack of input argument
  • slnums2bounds SLNUMS2BOUNDS Compute the index-boundaries from section sizes
  • slparseprops SLPARSEPROPS Parses input parameters
This function is called by:
  • sllda SLLDA Trains a Linear Discriminant Model using specified method

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function T = slnlda(X, nums, varargin)
0002 %SLNLDA Performs Nullspace-based Linear Discriminant Analysis
0003 %
0004 % $ Syntax $
0005 %   - T = slnlda(X, nums)
0006 %   - T = slnlda(X, nums, ...)
0007 %
0008 % $ Arguments $
0009 %   - X:        the training sample matrix
0010 %   - nums:     the numbers of samples in all classes
0011 %   - T:        the solved transform matrix
0012 %
0013 % $ Description $
0014 %   - T = slnlda(X, nums) performs nullspace LDA on the samples X using
0015 %     default settings.
0016 %
0017 %   - T = slnlda(X, nums, ...) performs nullspace LDA on the samples X
0018 %     with the specified properties.
0019 %     \*
0020 %     \t   Table 1.  The properties of Fisher Discriminant Analysis   \\
0021 %     \h     name    &     description                                \\
0022 %           'prepca' &  Whether to perform a preamble PCA to first
0023 %                       reduce the dimensions to the samples' rank.
0024 %                       default = false.                              \\
0025 %           'pdimset' &  The cell containing the arguments for determining
0026 %                        the dimension of the principal subspace (that is
0027 %                        the orthogonal complement of the nullspace)   \\
0028 %           'dimset'  &  The cell containing the arguments for determining
0029 %                        the output feature dimension. default = {}.
0030 %                        (refer to sldim_by_eigval).                   \\
0031 %           'Sb'      &  The pre-computed between-class scattering matrix
0032 %                        or the cell containing the arguments for
0033 %                        computing the scatter matrix in the form
0034 %                        {type, ...}, which is input to slscatter.     \\
0035 %           'Sw'      &  The pre-computed within-class scattering matrix
0036 %                        or the cell containing the arguments for
0037 %                        computing the scatter matrix in the form
0038 %                        {type, ...}, which is input to slscatter.     \\
0039 %         'weights'   &  The sample weights. default = [].             \\
0040 %     \*
0041 %
0042 % $ Remarks $
0043 %   -# The function solves the transform in mainly following stages:
0044 %      First, solve the null space of the between-class scattering, then
0045 %      project all samples onto the null space. Finally, a PCA-step is
0046 %      conducted to maximize the between-class scattering on nullspace.
0047 %
0048 %   -# If Sw or its computing rule is given, the null space is  directly
0049 %      solved from Sw, otherwise the null space is solved from within class
0050 %      differences. If Sb is given, the between-class scattering on null
0051 %      space is computed by directly applying the null space projection
0052 %      to Sb, otherwise, Sb is computed from components on nullspace. If
0053 %      both Sb and Sw are given, then the samples are not used in the
0054 %      function. In this cases, you can simply input an empty X.
0055 %
0056 %   -# If both Sb and Sw are given, the pre-pca step will not be conducted.
0057 %      no matter whether prepca is true or false.
0058 %
0059 % $ History $
0060 %   - Created by Dahua Lin on May 1st, 2006
0061 %   - Modified by Dahua Lin on Sep 10th, 2006
0062 %       - replace sladd by sladdvec and slmul by slmulvec to increase
0063 %         efficiency
0064 %
0065 
0066 
0067 %% parse and verify input arguments
0068 
0069 if nargin < 2
0070     raise_lackinput('slfld', 2);
0071 end
0072 
0073 % check size
0074 
0075 if ~isempty(X)    
0076     if ndims(X) ~= 2
0077         error('sltoolbox:invaliddims', ...
0078             'The sample matrix X should be a 2D matrix');
0079     end
0080     [d, n] = size(X);
0081     
0082     k = length(nums);
0083     if ~isequal(size(nums), [1, k]);
0084         error('sltoolbox:invaliddims', ...
0085             'The nums vector should be a row vector');
0086     end
0087     if sum(nums) ~= n
0088         error('sltoolbox:sizmismatch', ...
0089             'The total number in nums is not consistent with that in X');
0090     end
0091 end
0092 
0093 % check options
0094 
0095 opts.prepca = false;
0096 opts.pdimset = {};
0097 opts.dimset = {};
0098 opts.Sb = {'Sb'};
0099 opts.Sw = {'Sw'};
0100 opts.weights = [];
0101 opts = slparseprops(opts, varargin{:});
0102 
0103 has_Sb = ~isempty(opts.Sb) && isnumeric(opts.Sb);
0104 has_Sw = ~isempty(opts.Sw) && isnumeric(opts.Sw);
0105 if has_Sb && has_Sw
0106     use_samples = false;
0107     d = size(opts.Sw, 1);
0108     
0109     if ~isequal(size(opts.Sb), [d, d]) || ~isequal(size(opts.Sw), [d, d])
0110         error('sltoolbox:sizmismatch', ...
0111             'Size consistency in Sb and Sw');
0112     end
0113         
0114 else
0115     if isempty(X)
0116         error('sltoolbox:invalidargs', ...
0117             'The samples cannot be empty when Sb or Sw is not pre-computed');
0118     end
0119     use_samples = true;
0120     if (has_Sb && ~isequal(size(opts.Sb), [d, d])) || (has_Sw && ~isequal(size(opts.Sw), [d, d]))
0121         error('sltoolbox:sizmismatch', ...
0122             'Size consistency in Sb and Sw');
0123     end
0124     
0125 end
0126 w = opts.weights;
0127 
0128 
0129 %% Compute
0130 
0131 %% Step 0: Pre-PCA
0132 pca_computed = false;
0133 if use_samples && opts.prepca
0134     SPCA = slpca(X, 'weights', w);
0135     X = SPCA.P' * sladdvec(X, -SPCA.vmean, 1);
0136     pca_computed = true;
0137 end
0138 
0139 %% Step 1: Solve Null Space
0140 
0141 if has_Sw
0142     PN = slnullspace({'cov', opts.Sw}, opts.pdimset{:});
0143 elseif ~isempty(opts.Sw) && ~isequal(opts.Sw, {'Sw'})
0144     Sw = slscatter(X, opts.Sw{:}, 'sweights', w, 'nums', nums);
0145     PN = slnullspace({'cov', Sw}, opts.pdimset{:});
0146     clear Sw;
0147 else 
0148     PN = slnullspace(make_weighted_withinclass_diffvecs(X, w, nums), ...
0149         opts.pdimset{:});
0150 end
0151 
0152 if pca_computed
0153     T1 = SPCA.P * PN;
0154     clear SPCA PN;
0155 else
0156     T1 = PN;
0157     clear PN;
0158 end
0159 
0160 
0161 %% Step 2: Compute the second-stage transform
0162 
0163 if has_Sb
0164     WSb = T1' * opts.Sb * T1;
0165 else
0166     X = T1' * X;
0167     WSb = slscatter(X, opts.Sb{:}, 'sweights', w, 'nums', nums);
0168 end
0169 [evs, T2] = slsymeig(WSb);
0170 rk2 = sldim_by_eigval(evs, opts.dimset{:});
0171 T2 = T2(:, 1:rk2);
0172 
0173 %% Integrate the transforms
0174 
0175 T = T1 * T2;
0176 
0177 
0178 %% The function for making the weighted difference vectors
0179 function Y = make_weighted_withinclass_diffvecs(X, w, nums)
0180 
0181 mvs = slmeans(X, w, nums);
0182 Y = X;
0183 [sp, ep] = slnums2bounds(nums);
0184 k = length(nums);
0185 for i = 1 : k
0186     Y(:, sp(i):ep(i)) = sladdvec(X(:, sp(i):ep(i)), -mvs(:,i), 1);
0187 end
0188 
0189 if ~isempty(w)
0190     Y = slmulvec(Y, sqrt(max(w, 0)), 2);
0191 end
0192

Generated on Wed 20-Sep-2006 12:43:11 by m2html © 2003

Contact us at files@mathworks.com