function [model, loo_err, loo_pred] = kls_train_zita_K(model,bias)

%KLS_TRAIN_zita_K    Train a Weighted Kernel Least Square (W-LS-SVM)
%MODEL = KLS_TRAIN_zita_K(MODEL)
%[MODEL, LOO_ERR] = KLS_TRAIN_zita_K(MODEL)
%[MODEL, LOO_ERR, LOO_PRED] = KLS_TRAIN_zita_K(MODEL)
% This code is part of the supplementary material to the CVPR 2010 paper
% "Safety in Numbers: Learning Categories from Few Examples with Multi
% Model Knowledge Trasfer", T. Tommasi, F. Orabona, B. Caputo.

% Copyright (C) 2009-2010, Tatiana Tommasi
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
% Contact the author: ttommasi [at] idiap.ch


if nargin<2
    bias = 1;
end

n = size(model.K,1);

index_p=find(model.Y==1);
l_p=numel(index_p);
index_m=find(model.Y==-1);
l_m=numel(index_m);
zita=zeros(1,numel(model.Y));
zita(index_p)=numel(model.Y)/(2*l_p);
zita(index_m)=numel(model.Y)/(2*l_m);

if bias
        model.K=[model.K ones(n,1); ones(1,n) 0];

        if numel(model.C)==1
        id=1/model.C*diag(1./zita);
        id=[id zeros(n,1)];
        id=[id ; zeros(1,n+1)];
        id(end,end)=0;
    else
        id=diag(1./model.C); id(end+1,end+1)=0;
    end

        G=pinv(model.K+id);
        x=G*[model.Y';0];

        model.beta = x(1:end-1);
        model.b = x(end);

        out=model.K(1:n,:)*x;
        err_cla=1-numel(find(model.Y'==sign(out)))/n;
        err=mean((model.Y'-out).^2);
        dd=diag(G);
        loo_pred=model.Y'-model.beta./dd(1:end-1);
else
        if numel(model.C)==1
        id=1/model.C*eye(n);
    else
        id=diag(1./model.C);
    end

    G=pinv(model.K+id);
        x=G*model.Y';

        model.beta = x;
        model.b = 0;

        out=model.K*x;
        err_cla=1-numel(find(model.Y'==sign(out)))/n;
        err=mean((model.Y'-out).^2);
        dd=diag(G);
        loo_pred=model.Y'-model.beta./dd;
end

err_cla_loo=1-numel(find( model.Y'==sign(loo_pred) ))/n;
err_loo=mean((model.Y'-loo_pred).^2);

loo_err(1)=err_loo;
loo_err(2)=err_cla_loo;
