function model = ggradandr( distrib, options, init_model)
% GGRADANDER Gradient method to solve the Generalized Anderson's task.
%
% Synopsis:
% model = ggradandr( distrib)
% model = ggradandr( distrib, options)
% model = ggradandr( distrib, options, init_model)
%
% Description:
% This function is an implementation of the algorithm
% using the generalized gradient optimization to solve
% the the Generalized Anderson's task [SH10].
%
% The goal of the GAT is find the binary linear classification
% rule (g(x)=sgn(W'*x+b) with minimal probability of
% misclassification. The conditional probabilities are known to
% be Gaussians their paramaters belong to a given set of parameters.
% The true parameters are not known. The linear rule which
% guarantes the minimimal classification error for the worst
% possible case (the worst configuration of Gaussains) is
% sought for.
%
% Input:
% distrib [struct] Binary labeled Gaussian distributions:
% .Mean [dim x ncomp] Mean vectors.
% .Cov [dim x dim x ncomp] Covariance matrices.
% .y [1 x ncomp] labels of Gaussians (1 or 2).
%
% options [struct] Defines stopping condition:
% .tmax [1x1] Maximal number of iterations (default 1e4 ).
% .eps [1x1] Minimal change in the optimised criterion (default 0).
%
% init_model [struct] Initial model:
% .W, .b, .t see below.
%
% Output:
% model [struct] Linear classifier:
% .W [dim x 1] Normal vector of the found hypeprlane W'*x + b = 0.
% .b [1x1] Bias of the hyperplane.
%
% .r [1x1] Mahalanobis distance for the cloasest Gaussian.
% .err [1x1] Probability of misclassification.
% .t [1x1] Number of iterations.
% .exitflag [1x1] 0 ... maximal number of iterations exceeded.
% 1 ... condition abs( r - old_r) < eps fulfilled.
%
% Example:
% distrib = load('mars');
% model = ggradandr( distrib );
% figure; pandr( model, distrib );
%
% See also
% ANDRORIG, EANDERS, GANDERS, ANDRERR, LINCLASS.
%
% 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:
% 17-sep-2003, VF
if nargin < 2, options = []; else options=c2s(options); end
if ~isfield(options,'eps'), options.eps=0.0; end
if ~isfield(options,'tmax'), options.tmax=1e4; end
[dim,ncomp]=size(distrib.Mean);
exitflag = 0;
t = 0;
Mu = [distrib.Mean;ones(1,ncomp)];
Mu(:,find(distrib.y==2)) = -Mu(:,find(distrib.y==2));
C = zeros(dim+1,dim+1,ncomp);
C(1:dim,1:dim,:) = distrib.Cov;
if nargin == 3,
W = [ init_model.W; init_model.b];
if isfield( init_model,'t'), t = init_model.t; end
end
if t==0, W = mean(Mu,2); end
[minr,inx] = min_radius(W,Mu,C);
old_minr=minr;
while exitflag==0 & t < options.tmax,
t = t + 1;
x0=Mu(:,inx)-(minr/sqrt(W'*C(:,:,inx)*W))*C(:,:,inx)*W;
W = W + x0;
[minr,inx] = min_radius(W,Mu,C);
if abs(minr-old_minr) < options.eps,
exitflag = 1;
end
old_minr = minr;
end
model.W = W(1:end-1);
model.b = W(end);
model.r = minr;
model.err = 1-cdf('norm',minr,0,1);
model.t = t;
model.exitflag = exitflag;
model.distrib = distrib;
model.options = options;
model.classifier = 'linclass';
return;
function [W,exitflag] = optimal_hyperplane(X)
[dim,num_data]=size(X);
H=eye(dim);
f=zeros(dim,1);
b=-ones(num_data,1);
A=-X';
options=optimset('Display','off','Diagnostics','off','LargeScale','off');
[W,fval,exitflag]=quadprog(H,f,A,b,[],[],[],[],[],options);
return;
function [minr,inx] = min_radius(W,Mu,C);
Radius = zeros(size(Mu,2),1);
for i = 1:size(Mu,2),
Radius(i) = W'*Mu(:,i)/sqrt(W'*C(:,:,i)*W);
end
[minr,inx]=min( Radius );
return;