% APRENDIZAJE AUTOMÁTICO (G. Pajares y J. M. de la Cruz, Eds.)
% Editorial: RA-MA
% Capítulo 5: Máquinas de Vectores Soporte
% Autores: Jesús Antonio Vega Sánchez y Sebastián Dormido Canto

function  [svmC,nsvC,bC]=training(numeroclases,numero_muestras,XX,C,kernel,param);



% La función TRAINING realiza el entrenamiento de las máquinas utilizadas en la técnica SVM.
%
% Los parámetros de entrada son:
%                - numeroclases: es un escalar y representa el número de clases entre las que se
%                                desea clasificar. Por ej. si se tiene {BOL5,ECE7,RX306} el valor de
%                                numeroclases sería 3.
%
%                - numero_muestras: es un vector donde cada elemento representa el número de muestras 
%                                   que hay por clase. Por ej. si se tiene BOL5_1, BOL5_2, ECE7_1, ECE7_2, ECE7_3,
%                                   y RX306_1, numero_muestras=[2 3 1]
%
%                - XX: es la matriz de los vectores de entrenamiento (se genera con el programa norm_svm). Ver 
%                      norm_svm para observar el formato.
%
%                -  C: es un vector que almacena el parámetro de regularización (límite superior de los alphas).
%                      Cada elemento representa el límite para cada clase. Ej. C=[Inf Inf 1];
%
%                - kernel: es un string donde se introduce la función de transformación a utilizar.                  
%                          Los valores para kernel pueden ser: 
%                                                           'linear'  -
%                                                           'poly'    - [1,p1] p1 is degree of polynomial
%                                                           'erfb'    - [1,p1] p1 is width of rbfs (sigma)
%                                                           'rbf'     - [1,p1] p1 is width of rbfs (sigma)
%                                                           'sigmoid' - [p1,p2] p1 is scale, p2 is offset

%
%                - param: es un vector de dimensión 2 que almacena los parámetros de las funciones kernel que
%                         se pueden utilizar. Por ejemplo param=[2 1]; 
%
% Los parámetros de salida son:
%                - svmC: almacena los vectores soporte de todas las máquinas (se almacenan en filas), la penúltima
%                       columna almacena el valor de la etiqueta {1,-1} para saber si pertenece a la clase k ó
%                       al resto y en la última columna el valor de alpha
%
%                - nsvC: almacena el número de vectores soporte de cada una de las k máquinas
%
%                - bC: alamcena el término bias de las k máquinas


%Ejemplo Multiclase SVM
%Entrenar Máquina
%----------------------------------------

%clc;
%Inicialización de variables que se necesitan en la función
senalC=[];
wC=[];
bC=[];
z=[];
p=0;
svmC=[];
nsvC=[];
bC=[];

  
%disp('Preparando Entrenamiento');

%Entrena una máquina contra todas
cont=1;
for k=1:numeroclases
   waux=[];
   baux=[];
   psv=[];
   svm=[];
   
  % disp(['Entrenando Maquina ',num2str(k)]);
  % disp('---------------------------------');
   
   % En Clase (vector columna) se almacenan las etiquetas {1,-1} que identifican si los vectores de entrenamiento
   % pertenecen a la clase considerada {1} ó no (es decir, pertenecen al resto) {-1}
   clase=-1*ones(size(XX,1),1);
   clase(cont:cont+numero_muestras(k)-1)=1;
   
     
   cont=cont+numero_muestras(k);

     
%   disp([' 1:   Clase ',num2str(k)]);
%   disp(['-1:No Clase ',num2str(k)]);
   
  % Se almacena en c el valor del límite de los alphas de la máquina k 
   c=C(k);
   
   % Se llama a la función que realiza el entrenamiento de la máquina k
   %
   % svm almacena los vectores soporte de la máquina k (se almacenan en filas), la penúltima columna almacena el valor
   % de la etiqueta {1,-1} para saber si pertenece a la clase k ó al resto y en la última columna el valor de alpha
   %
   % psv es una matriz de dos columnas, en la primera se almacenan los índices absolutos de los vectores soporte y
   % en la segunda se almacena una etiqueta {1,-1} que identifica si el vector soporte corresponde a la clase k {1}
   % ó al resto {-1}
   %
   % En b0 se almacena el valor del parámetro de bias y en nsv el número de vectores soporte para la máquina k
   [svm psv b0 nsv]=wsvm(XX,clase,kernel,c,param);
   
   %disp(['Se obtuvieron ',num2str(size(psv,1)),' vectores soporte de un total de ',num2str(length(clase))]);
   %disp(['Los vectores soporte de la Clase ',num2str(k),' son:']);
	%disp(psv(find(psv(:,2)==1),1));
	%disp(['Los vectores soporte que no pertenecen a la Clase ',num2str(k),' son:']);
	%disp(psv(find(psv(:,2)==-1),1));
   
   
   % En svmC se van almacenando todas las matrices de las k máquinas 
   svmC=[svmC;svm];
   
   % En nsvC se van almacenando el número de vectores soporte de cada una de las k máquinas 
   nsvC=[nsvC;nsv];
   
   % En bC se va almacenando el término bias de cada máquina
   bC(k)=b0;
  
end;

return
