Code covered by the BSD License  

Highlights from
Bayesian robust hidden Markov model

image thumbnail

Bayesian robust hidden Markov model

by

 

25 Sep 2013 (Updated )

MatLab object for segmenting sequences of real-valued data with noise, outliers and missing values.

(ConstructOnLoad) BRHMM %#ok
classdef (ConstructOnLoad) BRHMM %#ok<*MCSUP,*PROP>
%BRHMM    Construct Bayesian robust hidden Markov model
%   
%   BRHMM constructs a Bayesian robust hidden Markov model with a given
%   number of hidden states, symbols and real-valued features.
%   
%   Usage:   Obj=BRHMM(M,K,D)
%   
%   Inputs:  M   - Number of states
%            K   - Number of symbols
%            D   - Number of features
%   
%   Outputs: Obj - Bayesian robust hidden Markov model
%   
%   Input arguments M, K and D should be positive integer scalars.
%   
%   See also BRHMM.SIM and BRHMM.ESTIM.
%   
%   Copyright (c) 2013 Gabriel Agamennoni.
    
    % Number of states, symbols and features.
    properties (SetAccess=private)
        NumState
        NumSym
        NumFeat
    end
    
    % Hyper-parameters.
    properties
        TransWeight
        TransStren
        EmissWeight
        EmissStren
        CompLoc
        CompScale
        CompDisp
        CompPrec
    end
    
    % Constructor.
    methods
        function Obj=BRHMM(NumState,NumSym,NumFeat)
            if nargin()>0
                
                % Check number of arguments.
                if nargin()<3
                    error('BRHMM:NotEnoughInputs', ...
                        'Not enough inputs.')
                end
                if nargin()>3
                    error('BRHMM:TooManyInputs', ...
                        'Too many inputs.')
                end
                if nargout()>1
                    error('BRHMM:TooManyOutputs', ...
                        'Too many outputs.')
                end
                
                % Check input arguments.
                CheckArg(NumState,NumSym,NumFeat)
                
                % Set number of states, symbols and features.
                Obj.NumState=NumState;
                Obj.NumSym=NumSym;
                Obj.NumFeat=NumFeat;
                
                % Set default hyper-parameters.
                Obj.TransWeight=ones(NumState,NumState)/NumState;
                Obj.TransStren=ones(NumState,1);
                Obj.EmissWeight=ones(NumSym,NumState)/NumSym;
                Obj.EmissStren=ones(NumState,1);
                Obj.CompLoc=zeros(NumFeat,NumSym);
                Obj.CompScale=ones(NumSym,1);
                Obj.CompDisp=RepVal(eye(NumFeat),3,NumSym);
                Obj.CompPrec=NumFeat*ones(NumSym,1);
                
            end
        end
    end
    
    % Access methods.
    methods
        function Obj=set.TransWeight(Obj,TransWeight)
            
            % Store number of states.
            NumState=Obj.NumState;
            
            % Check transition weights.
            if ~isnumeric(TransWeight)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(TransWeight)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(TransWeight)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(TransWeight)>2
                error('BRHMM:BadInputSize', ...
                    'Input must be a matrix.')
            end
            if size(TransWeight,1)~=NumState
                error('BRHMM:BadInputSize', ...
                    'Input must have %d row(s).',NumState)
            end
            if size(TransWeight,2)~=NumState
                error('BRHMM:BadInputSize', ...
                    'Input must have %d column(s).',NumState)
            end
            if any(isnan(TransWeight(:))|isinf(TransWeight(:)))
                error('BRHMM:BadInputValue', ...
                    'Input must contain finite numbers.')
            end
            for i=1:NumState
                if any(TransWeight(:,i)<=0|abs(sum(TransWeight(:,i))-1)>...
                        eps()*NumState)
                    error('BRHMM:BadInputValue', ...
                        ['Column %d of input must contain numbers ',...
                            'on the unit simplex.'],i)
                end
            end
            
            % Set transition weights.
            Obj.TransWeight=TransWeight;
            
        end
        function Obj=set.TransStren(Obj,TransStren)
            
            % Store number of states.
            NumState=Obj.NumState;
            
            % Check transition strengths.
            if ~isnumeric(TransStren)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(TransStren)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(TransStren)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(TransStren)>2||min(size(TransStren))>1
                error('BRHMM:BadInputSize', ...
                    'Input must be a vector.')
            end
            if numel(TransStren)~=NumState
                error('BRHMM:BadInputSize', ...
                    'Input must have %d element(s).',NumState)
            end
            if any(isnan(TransStren)|isinf(TransStren)|TransStren<=0)
                error('BRHMM:BadInputValue', ...
                    'Input must contain positive finite numbers.')
            end
            
            % Set transition strengths.
            Obj.TransStren=TransStren;
            
        end
        function Obj=set.EmissWeight(Obj,EmissWeight)
            
            % Store number of states and symbols.
            NumState=Obj.NumState;
            NumSym=Obj.NumSym;
            
            % Check emission weights.
            if ~isnumeric(EmissWeight)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(EmissWeight)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(EmissWeight)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(EmissWeight)>2
                error('BRHMM:BadInputSize', ...
                    'Input must be a matrix.')
            end
            if size(EmissWeight,1)~=NumSym
                error('BRHMM:BadInputSize', ...
                    'Input must have %d row(s).',NumSym)
            end
            if size(EmissWeight,2)~=NumState
                error('BRHMM:BadInputSize', ...
                    'Input must have %d column(s).',NumState)
            end
            if any(isnan(EmissWeight(:))|isinf(EmissWeight(:)))
                error('BRHMM:BadInputValue', ...
                    'Input must contain finite numbers.')
            end
            for i=1:NumState
                if any(EmissWeight(:,i)<=0|abs(sum(EmissWeight(:,i))-1)>...
                        eps()*NumSym)
                    error('BRHMM:BadInputValue', ...
                        ['Column %d of input must contain numbers ',...
                            'on the unit simplex.'],i)
                end
            end
            
            % Set emission weights.
            Obj.EmissWeight=EmissWeight;
            
        end
        function Obj=set.EmissStren(Obj,EmissStren)
            
            % Store number of states.
            NumState=Obj.NumState;
            
            % Check emission strengths.
            if ~isnumeric(EmissStren)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(EmissStren)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(EmissStren)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(EmissStren)>2||min(size(EmissStren))>1
                error('BRHMM:BadInputSize', ...
                    'Input must be a vector.')
            end
            if numel(EmissStren)~=NumState
                error('BRHMM:BadInputSize', ...
                    'Input must have %d element(s).',NumState)
            end
            if any(isnan(EmissStren)|isinf(EmissStren)|EmissStren<=0)
                error('BRHMM:BadInputValue', ...
                    'Input must contain positive finite numbers.')
            end
            
            % Set emission strengths.
            Obj.EmissStren=EmissStren;
            
        end
        function Obj=set.CompLoc(Obj,CompLoc)
            
            % Store number of symbols and features.
            NumSym=Obj.NumSym;
            NumFeat=Obj.NumFeat;
            
            % Check component locations.
            if ~isnumeric(CompLoc)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(CompLoc)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(CompLoc)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(CompLoc)>2
                error('BRHMM:BadInputSize', ...
                    'Input must be a matrix.')
            end
            if size(CompLoc,1)~=NumFeat
                error('BRHMM:BadInputSize', ...
                    'Input must have %d row(s).',NumFeat)
            end
            if size(CompLoc,2)~=NumSym
                error('BRHMM:BadInputSize', ...
                    'Input must have %d column(s).',NumSym)
            end
            if any(isnan(CompLoc(:))|isinf(CompLoc(:)))
                error('BRHMM:BadInputValue', ...
                    'Input must contain finite numbers.')
            end
            
            % Set component locations.
            Obj.CompLoc=CompLoc;
            
        end
        function Obj=set.CompScale(Obj,CompScale)
            
            % Store number of symbols.
            NumSym=Obj.NumSym;
            
            % Check component scales.
            if ~isnumeric(CompScale)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(CompScale)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(CompScale)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(CompScale)>2||min(size(CompScale))>1
                error('BRHMM:BadInputSize', ...
                    'Input must be a vector.')
            end
            if numel(CompScale)~=NumSym
                error('BRHMM:BadInputSize', ...
                    'Input must have %d element(s).',NumSym)
            end
            if any(isnan(CompScale)|isinf(CompScale)|CompScale<=0)
                error('BRHMM:BadInputValue', ...
                    'Input must contain positive finite numbers.')
            end
            
            % Set component scales.
            Obj.CompScale=CompScale;
            
        end
        function Obj=set.CompDisp(Obj,CompDisp)
            
            % Store number of symbols and features.
            NumSym=Obj.NumSym;
            NumFeat=Obj.NumFeat;
            
            % Check component dispersions.
            if ~isnumeric(CompDisp)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(CompDisp)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(CompDisp)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(CompDisp)>3
                error('BRHMM:BadInputSize', ...
                    'Input must be a cube.')
            end
            if size(CompDisp,1)~=NumFeat
                error('BRHMM:BadInputSize', ...
                    'Input must have %d row(s).',NumFeat)
            end
            if size(CompDisp,2)~=NumFeat
                error('BRHMM:BadInputSize', ...
                    'Input must have %d column(s).',NumFeat)
            end
            if size(CompDisp,3)~=NumSym
                error('BRHMM:BadInputSize', ...
                    'Input must have %d page(s).',NumSym)
            end
            if any(isnan(CompDisp(:))|isinf(CompDisp(:)))
                error('BRHMM:BadInputValue', ...
                    'Input must contain finite numbers.')
            end
            for i=1:NumSym
                Asymm=abs(CompDisp(:,:,i)-CompDisp(:,:,i)');
                if any(Asymm(:)>eps()*NumFeat)
                    error('BRHMM:BadInputValue', ...
                        'Input must contain symmetric matrices.')
                end
                [~,NumSing]=chol(CompDisp(:,:,i));
                if NumSing>0
                    error('BRHMM:BadInputValue', ...
                        'Input must contain positive-definite matrices.')
                end
            end
            
            % Set component dispersions.
            Obj.CompDisp=CompDisp;
            
        end
        function Obj=set.CompPrec(Obj,CompPrec)
            
            % Store number of symbols and features.
            NumSym=Obj.NumSym;
            NumFeat=Obj.NumFeat;
            
            % Check component precisions.
            if ~isnumeric(CompPrec)
                error('BRHMM:BadInputClass', ...
                    'Input must be numeric.')
            end
            if ~isreal(CompPrec)
                error('BRHMM:BadInputClass', ...
                    'Input must be real.')
            end
            if isempty(CompPrec)
                error('BRHMM:BadInputSize', ...
                    'Input must be non-empty.')
            end
            if ndims(CompPrec)>2||min(size(CompPrec))>1
                error('BRHMM:BadInputSize', ...
                    'Input must be a vector.')
            end
            if numel(CompPrec)~=NumSym
                error('BRHMM:BadInputSize', ...
                    'Input must have %d element(s).',NumSym)
            end
            if any(isnan(CompPrec)|isinf(CompPrec))
                error('BRHMM:BadInputValue', ...
                    'Input must contain finite numbers.')
            end
            if any(CompPrec<=NumFeat-1)
                error('BRHMM:BadInputValue', ...
                    'Input must contain numbers greater than %d.',NumFeat-1)
            end
            
            % Set component precisions.
            Obj.CompPrec=CompPrec;
            
        end
    end
    
    % Main methods.
    methods
        [State,Sym,Weight,Feat]=Sim(Obj,NumPoint,varargin)
        [Obj,Bound,varargout]=Estim(Obj,Feat,varargin)
    end
    
end



function CheckArg(varargin)

% Check input arguments.
for i=1:numel(varargin)
    if ~isnumeric(varargin{i})
        error('BRHMM:BadInputClass', ...
            'Input %d must be numeric.',i)
    end
    if ~isreal(varargin{i})
        error('BRHMM:BadInputClass', ...
            'Input %d must be real.',i)
    end
    if isempty(varargin{i})
        error('BRHMM:BadInputSize', ...
            'Input %d must be non-empty.',i)
    end
    if ndims(varargin{i})>2||numel(varargin{i})>1
        error('BRHMM:BadInputSize', ...
            'Input %d must be a scalar.',i)
    end
    if isnan(varargin{i})||isinf(varargin{i})
        error('BRHMM:BadInputValue', ...
            'Input %d must contain a finite number.',i)
    end
    if round(varargin{i})~=varargin{i}||varargin{i}<=0
        error('BRHMM:BadInputValue', ...
            'Input %d must contain a positive integer.',i)
    end
end

end

Contact us