% Calculation of gradient and objective for Smooth Hinge Classification
%
% function [obj,grad,lossobj,regobj] = bcls(w,x,y,lambda)
% w - parameter vector [d,1]
% x - examples [n,d]
% y - binary (0/1 or -1/+1) labels [n,1]
% lambda - regularization parameter [scalar]
% obj - objective value at w [scalar]
% gradient - gradient at w [d,1]
% lossobj - loss portion of obj [scalar]
% regobj - regularization penalty portion of obj [scalar]
% 
% Written by Jason Rennie, February 2005
% Last modified: Wed Aug 31 18:05:15 2005

function [obj,grad,lossobj,regobj] = bcsh(w,x,y,lambda)
  fn = mfilename;
  if nargin < 4
  end
  [n,d] = size(x);
  y = y-(y==0);
  if (n ~= length(y))
    error('x and y dimensions don''t match');
  end
  if (d ~= length(w))
    error('x and w dimensions don''t match');
  end
  z = y.*(x*w); % [n,1]
  lossobj = sum(h(z));
  regobj = lambda.*w'*w/2.0;
  obj = lossobj + regobj;
  grad = x'*(y.*hprime(z)) + lambda.*w; % [d,1]
  
function [ret] = h(z)
  ret = (z>0).*(z<1).*((1-z).^2)/2.0 + (z<=0).*(0.5-z);

function [ret] = hprime(z)
  ret = (z>0).*(z<1).*(z-1) - (z<=0);

% ChangeLog:
% 8/31/05 - Convert 1/0 labels to +1/-1
% 2/27/05 - Added objective calculation
