function [alpha,offset,varargout]=svmctrain(K,y,nu,varargin)

%function [alpha,b,varargout]=svmctrain(K,y,nu,varargin)
%
% Computes the dual vector and the offset for support vector machine
% classification.
% Note that this is a naive version, simply making use of matlab's built-in
% qp-solver.
%
%INPUTS
% K = the kernel matrix (ell x ell)
% y = the label vector (ell x 1)
% nu = the regularization parameter
% varargin = a cell array that may be empty or may contain Ktest (ell x
%            elltest), containing the kernel evaluations of the test
%            samples with the training samples; also, the 2nd cell of
%            varargin may contain the true labels (ytrue)
%
%OUTPUTS
% alpha = the dual vector
% offset = the offset
% varargout = only specified if varargin is specified, and contains the
%             estimated labels for the test set, and when ytrue is
%             specified also (in its second cell) the test error
%
%
%For more info, see www.kernel-methods.net
%
%Author: Tijl De Bie, 


n=size(K,1);
H = K.*(y*y');
f=[];
Aeq=[ones(1,n) ; y'];
beq = [1 ; 0];
A=[];
b=[];
LB=zeros(n,1);
UB=ones(n,1)/(nu*n);

alpha = quadprog(H,f,A,b,Aeq,beq,LB,UB);

lambda=1/2*sqrt(alpha'*H*alpha);
i = find(alpha.*y>0.0001);
ipos=i(1);
i = find(alpha.*y<-0.0001);
ineg=i(1);

offset=-lambda*((K(ipos,:)+K(ineg,:))*(alpha.*y));

if length(varargin)==1
    Ktest=varargin{1};
    ytest=sign(Ktest'*(alpha.*y)+b);
    varargout=ytest;
elseif length(varargin)==2
    Ktest=varargin{1};
    ytruetest=varargin{2};
    ntest=length(ytruetest);
    ytest=sign(Ktest'*(alpha.*y)+offset);
    error = sum(abs(ytruetest - ytest))/(2*ntest);
    varargout{1}=ytest;
    varargout{2}=error;
end
