function model = weak_learner2d(data)
% WEAK_LEARNER2D Traines weak classifier for 2D data.
%
% Synopsis:
%  model = weak_learner2d(data)
%
% Description:
%  
% Input:
%  data [struct] Training data:
%   .X [dim x num_data] Training vectors.
%   .y [1 x num_data] Binary labels (1 or 2).
%   .D [1 x num_data] Weights of training data.
% 
% Output:
%  model [struct] Binary linear classifier:
%   .W [dim x 1] Normal vector of hyperplane.
%   .b [1x1] Bias of the hyperplane.
%   .fun = 'linclass'.
%
% Example:
%  data = load('riply_trn');
%  data.D = ones(length(data.y),1)/length(data.y);
%  model = weak_learner2d(data);
%  figure; ppatterns(data); pline(model);
%

% Modifications:
% 24-aug-2004, VF

[dim,num_data] = size(data.X);

proj1 = data.X(1,:);
proj2 = data.X(2,:);
proj3 = data.X(1,:)+data.X(2,:);
proj4 = data.X(1,:)-data.X(2,:);

[b1,Error1,Sign1] = compute_bias(proj1,data.y,data.D);
[b2,Error2,Sign2] = compute_bias(proj2,data.y,data.D);
[b3,Error3,Sign3] = compute_bias(proj3,data.y,data.D);
[b4,Error4,Sign4] = compute_bias(proj4,data.y,data.D);

[dummy,inx] = min([Error1 Error2 Error3 Error4]);
%[dummy,inx] = min([Error1 Error2]);
switch inx
  case 1
    model.W = Sign1*[1;0];
    model.b = b1;
  case 2
    model.W = Sign2*[0;1];
    model.b = b2;
  case 3
    model.W = Sign3*[1;1];
    model.b = b3;
  case 4
    model.W = Sign4*[1;-1];
    model.b = b4;
end

model.fun = 'linclass';

return;


function [b,Error,Sign] = compute_bias(x,y,D)
%-------------------------------------------------------

sort_x = [-inf,sort(unique(x))];
err = []; b = [];
for j=1:length(sort_x)-1,
    
  b(j) = 0.5*(sort_x(j)+sort_x(j+1));

  ypred = ones(1,length(x));
  ypred(find(x < b(j))) = 2;

  err(j) = sum((ypred(:) ~= y(:)).*D(:));
    
end
  
[minerr1,inx1] = min(err);
[minerr2,inx2] = min(1-err);
if minerr1 < minerr2,
  Sign = 1;
  b = -b(inx1);
  Error = minerr1;
else
  Sign = - 1;
  b = b(inx2);
  Error = minerr2;
end

return;
% EOF

