%[tipo_senyal,patrones,num_senyal] = ClasificaSenyal(senyal,n_tipos,umbral)
%
%Esta función clasifica una señal de entrada en función de distintos patrones
%según su morfología. Para ello emplea el siguiente algoritmo: para cada
%señal de la matriz de entrada, identifica el patrón correspondiente entre
%los patrones detectados hasta el momento. Si no se corresponde con ningún
%patrón conocido, entonces añade un nuevo patrón y lo asigna a la señal.
%En caso contrario, si efectivamente se encuentra entre los patrones
%existentes, actualiza el patrón correspondiente con la señal actual. 
%
%   Entrada:
%       senyal [matriz]: secuencia de señales organizadas en filas
%       n_tipos [nº entero]: nº máximo de tipos de señal a clasificar
%       umbral [-1 a 1]: umbral de correlación para detectar patrones
%
%   Salida:
%       tipo_senyal [vector]: clasificación de cada señal
%       patrones [matriz]: conjunto de patrones detectados (en filas)
%       num_senyal [vector]: número de señales identificados de cada patrón
%
%   Llamadas a otras funciones:
%       IdentificaPatron

function [tipo_senyal,patrones,num_senyal] = ClasificaSenyal(senyal,n_tipos,umbral)
%% Parámetros opcionales
if nargin < 2
    n_tipos = 8;     % Este es el limite de patrones posibles.
    umbral = 0.9;    % Umbral de correlación para parton por defecto.
elseif nargin < 3
    umbral = 0.9;    % Umbral de correlación para parton por defecto.    
else
    % Deja los parámetros que introduce el usuario.
end

%% Clasificación del complejo
patrones = [];       % Inicicliza patrones (Para poder pasárselo a función IdentificaPatron)
num_senyal = [];     % Inicializa el nº de complejos QRS de cada tipo
n_senyal = size(senyal,1); % Obtener el nº de QRS
% Bucle que recorre uno por uno por uno los complejos QRS detectados
for i=1:n_senyal
    % Se selecciona el patrón apropiado con un umbral de correlación de 0.9
    % y un máximo de 3 patrones
    patron_sel = IdentificaPatron(patrones,senyal(i,:),umbral,n_tipos); 
    if patron_sel > 0   % Patrón ya existente -> Se conlabiliza y se actualiza el patrón detectado (robustez)
        tipo_senyal(i) = patron_sel; % Guardar el tipo de patron al que corresponde el QRS
        % Actualización del patrón por media ponderada (tienen más pesos
        % los acumulados que el nuevo (peso unitario)
        num = patrones(patron_sel,:)*num_senyal(patron_sel)+senyal(i,:);
        den = num_senyal(patron_sel)+1;
        patrones(patron_sel,:) = num/den; % Actualización del patrón
        % Actualizar el nº de patrones de un tipo
        num_senyal(patron_sel) = num_senyal(patron_sel) + 1;
    else                % Patrón nuevo detectado
        patrones = [patrones; senyal(i,:)];    % Añadir el nuevo complejo como patron
        tipo_senyal(i) = size(patrones,1);     % Obtener la posición del último patron asignado
        num_senyal = [num_senyal; 1]; % Primer complejo QRS de este patrón
    end
end
end

