
% combine at most 'ncomp' stumps

function [model] = boost_logistic(X,y,ncomp)

W = ones(size(X,1),1); 
W = W/sum(W);

model = cell(ncomp,1);

H = zeros(size(X,1),1);
for i=1:ncomp,
  stump = build_stump(X,y,W);

  if (stump.werr<0.5),
    h = eval_stump(stump,X);
    alpha = find_alpha(H.*y,h.*y,10);  % 10 is max alpha
    H = H + alpha*h; % update the combined predictions
    
    % insert weight update here
    W = exp(-H.*y)./(1+exp(-H.*y));
    W = W/sum(W);  
  
    model{i} = stump;
    model{i}.alpha = alpha; 
  else  
    i = i-1; break; 
  end;

end;

model = model(1:i); % return only non-empty cells 

% ---------------------------------------
% find optimizing alpha

function [alpha] = find_alpha(Z,z,C)

lb = 0; 
ub = C;
alpha = (ub+lb)/2;

while (ub-lb>1e-6),
  p = logistic(Z+alpha*z);
  J = (1-p)'*z;
  if (J>0), lb = alpha; else ub = alpha; end;
  alpha = (ub+lb)/2;
end;

% ---------------------------------------
function [p] = logistic(z)

p = zeros(size(z));
I = find(z>=0);
p(I) = 1 ./(1+exp(-z(I)));

I = find(z<0);
p(I) = 1 - 1 ./(1+exp(z(I)));
