function model = lda(data,new_dim)
% LDA Linear Discriminant Analysis.
%
% Synopsis:
% model = lda(data)
% model = lda(data,new_dim)
%
% Description:
% This function is implementation of Linear Discriminant Analysis.
% The goal is to train the linear transform which maximizes ratio
% between between-class and within-class scatter matrix of projected
% data.
%
% Input:
% data [struct] Input labeled data:
% .X [dim x num_data] Data sample.
% .y [1 x num_data] Labels (1,2,...,nclass).
%
% new_dim [1x1] Output data dimension (default new_dim = dim).
%
% Ouput:
% model [struct] Linear projection:
% .W [dim x new_dim] Projection matrix.
% .b [new_dim x 1] Biases.
%
% .mean_X [dim x 1] Mean value of data.
% .Sw [dim x dim] Within-class scatter matrix.
% .Sb [dim x dim] Between-class scatter matrix.
% .eigval [dim x 1] Eigenvalues.
%
% Example:
% in_data = load('iris');
% model = lda( in_data, 2 );
% out_data = linproj( in_data, model);
% figure; ppatterns(out_data);
%
% See also
% LINPROJ, PCA.
%
% About: Statistical Pattern Recognition Toolbox
% (C) 1999-2003, Written by Vojtech Franc and Vaclav Hlavac
% <a href="http://www.cvut.cz">Czech Technical University Prague</a>
% <a href="http://www.feld.cvut.cz">Faculty of Electrical Engineering</a>
% <a href="http://cmp.felk.cvut.cz">Center for Machine Perception</a>
% Modifications:
% 05-oct-2006, VF
% 25-may-2004, VF
% 3-may-2004, VF
% 20-may-2001, V.Franc, created
data=c2s(data);
[dim,num_data] = size(data.X);
nclass = max( data.y );
if nargin < 2, new_dim = dim; end
mean_X = mean( data.X, 2);
Sw=zeros(dim,dim);
Sb=zeros(dim,dim);
for i = 1:nclass,
inx_i = find( data.y==i);
X_i = data.X(:,inx_i);
mean_Xi = mean(X_i,2);
Sw = Sw + cov( X_i', 1);
Sb = Sb + length(inx_i)*(mean_Xi-mean_X)*(mean_Xi-mean_X)';
end
[V,D]=eig( inv( Sw )*Sb );
[D,inx] = sort(diag(D),1,'descend');
model.W = V(:,inx(1:new_dim));
model.eigval = diag(D);
model.b = -model.W'*mean_X;
model.Sw = Sw;
model.Sb = Sb;
model.mean_X = mean_X;
model.fun = 'linproj';
return;