/@ess/ess.m (fc6df34144afcde236c02bfd25e0a789a36f56e3) (8456 bytes) (mode 100644) (type blob)

classdef ess < ss
% sys = ess(A,B,C,D,L,Q,R,M,...)
% sys = ess(ss,L,Q,R,M,...)
%
% Model for discrete system
% x(k+1) = A x(k) + B u(k) + L w(k)
% z(k)  = C x(k) + D u(k) + n(k)
% Noise statistics
% w~N(0,Q)
% n~N(0,R)
% E[w*n']=M(k)
%
% This class extends ss. See 'help ss' for a list of additional
% arguments.
    
% adapt number of meta-properties in getMetaProperties if
% datastructure is changed!
    properties
        l                               % noise input
        q                               % process noise
        r                               % measurement noise
        m                               % noise correlations
    end

    properties (Hidden = true, SetAccess = protected)
        isnoisy                         % system has noisy input
                                        % (boolean)
    end
    

    methods
        
        %%% constructor
        function obj = ess(varargin)
        % parse arguments
            ssvarlen = 4;
            essvarlen = 8;
            addvarlen = essvarlen-ssvarlen;
            newArgs = cell(1,addvarlen); superArgs = {};
                
            % copy from ss object
            if nargin>0 && isa(varargin{1},'StateSpaceModel') || isa(varargin{1},'tf')
                % create empty ss object and call copy constructor
                switch class(varargin{1})
                  case 'ss'
                    S = varargin{1};
                  case 'tf'
                    S = ss(varargin{1});
                  case 'idss'
                    S = ss(varargin{1});
                  case 'ess'
                    % already ess model
                    S = varargin{1};
                end
                
                superArgs{1} = [];
                [copyNames,copyArgs] = getProperties(S);
                    
                % fields not set in ss object
                if nargin > 1
                    newArgs(1:nargin-1) = varargin(2:nargin);
                end

                if isa(varargin{1},'idss')
                    newArgs{1} = varargin{1}.k; % set l = k
                    newArgs{2} = varargin{1}.NoiseVariance; % set q = NoiseVariance
                    newArgs{3} = 0; % set r = 0 such thats isNoisy is true
                end

            % create ess object from matrices
            else
                copyArgs = [];
                % only old fields
                if nargin == ssvarlen
                    superArgs = varargin;
                % including new fields
                elseif essvarlen >= nargin && nargin > ssvarlen
                    superArgs = varargin(1:ssvarlen);
                    newArgs(1:length(varargin(ssvarlen+1:end))) = varargin(ssvarlen+1:end);
                % new fields + additional args
                elseif nargin > essvarlen
                    % take variables for ss
                    superArgs(1:ssvarlen) = varargin(1:ssvarlen);
                    superArgs(ssvarlen+1:nargin-addvarlen) = varargin(essvarlen+1:end);
                    % take variables for ess only (l,q,r,m)
                    newArgs = varargin(ssvarlen+1:essvarlen);
                end
            end
            
            % call superclass constructor
            obj = obj@ss(superArgs{:});
            
            % copy properties
            clen = length(copyArgs);
            if clen > 0
                for ii = 1:clen
                    obj.(copyNames{ii}) = copyArgs{ii};
                end
            end
            
            % set new fields
            if length(newArgs) > 0
                [obj.l,obj.q,obj.r,obj.m] = newArgs{:};
                if obj.isnoisy() && isempty(obj.m)
                    obj = fillM(obj);
                end
            end
            argC = essdata(obj,'CellOutput');
            h = checkdim(argC{:},[],[],[],[]);

            if ~h
                error('Model dimensions are not valid!')
            end
            
        end
        
        function nobj = cleanNoise(obj)
        % empty all noise matrices if noiseTest fails
            nobj = obj;
            if noiseTest(obj)
                nobj.l = []; nobj.q = []; nobj.r = []; nobj.m = [];
            end
        end
                 
        %% meta-properties 
        % extract object meta-properties = all except matrices
        % adapt number of meta-properties if datastructure is changed!
        function props = getMetaProperties(ssObj)
            nMeta = 10;
            props = struct();
            names = properties(ssObj);
            names = names(nMeta:end);
            for ii=1:length(names)
                props.(names{ii})=ssObj.(names{ii});
            end
        end
        % set object meta-properties
        function ssObjout = setMetaProperties(ssObj,props)
            names = fieldnames(props);
            ssObjout = ssObj;
            for ii = 1:length(names)
                ssObjout.(names{ii}) = props.(names{ii});
            end
        end
        
        
        %% set: these toggle isnoisy if required
        function obj = set.q(obj,Value)
            tmpq = obj.q;
            obj.q = Value;
            obj = toggleIsnoisy(obj);
            if ~checkdim(obj)
                obj.q = tmpq;
                error('Dimension mismatch')
            end
        end

        function obj = set.r(obj,Value)
            tmpr = obj.r;
            obj.r = Value;
            obj = toggleIsnoisy(obj);
            if ~checkdim(obj)
                obj.r = tmpr;
                error('Dimension mismatch')
            end
        end

        function obj = set.l(obj,Value)
            tmpl = obj.l;
            obj.l = Value;
            obj = toggleIsnoisy(obj);
            if ~checkdim(obj)
                obj.l = tmpl;
                error('Dimension mismatch')
            end
        end

        % extend ss saveobj
        function S = saveobj(obj)
        % separately save ss system, extra ess matrices, and all meta
        % properties into struct
            S.ss = ss(obj);             % ss system
            S.ess = localEssData(obj);  % extra ess matrices (l,q,r,m)
            S.prop = getMetaProperties(obj); % meta properties
        end
        
    end
    
    methods (Static)
        % extend ss saveobj
        function obj = loadobj(S)
        % restore ess object from structure saved in saveobj
        % S.ess has to be in correct order to be passed to constructor
            obj = ess(loadobj@ss(S.ss),S.ess{:});
            obj = setMetaProperties(obj,S.prop);
        end
    end

    methods (Access = protected)
        function Value = rnotempty(obj)
        % If r==[] return zero matrix with appropriate dimensions.
        % This is needed as there is no transfer matrix before the
        % measurement noise term in our model.
            if isempty(obj.r)
                Value = zeros(size(obj.c,1));
            else
                Value = obj.r;
            end
        end
    end
end

%% private functions

% toggle isnoisy
% called by set function to set isnoisy if condition is fulfiled
function obj = toggleIsnoisy(obj)
    if noiseTest(obj)
        obj.isnoisy = false;
    else
        obj.isnoisy = true;
        % if m = [] set zero it with appropriate dimensions
        if isempty(obj.m)
            obj = fillM(obj);
        end
    end
end

% test used by toggleIsnoisy
function h = noiseTest(obj)
    h = isempty(obj.q) || isempty(obj.l) || isempty(obj.r);
end

% make m a zero matrix with appropriate dimensions
function obj = fillM(obj)
    obj.m = zeros(size(obj.q,1),size(obj.r,2));
end

% extract object properties
function [names,props] = getProperties(ssObj)
    props={};
    names = properties(ssObj);
    for ii=1:length(names)
        props{ii}=ssObj.(names{ii});
    end
end

% extra ess properties
function c = extraEssProperties(obj)
% return name of properties not in ss, e.g. l,q,r,m
% takes ess obj as input
    sp = properties('ss'); ep = properties(obj);
    % note order of input: ep must be before!!
    % 'stable' is needed such that original order 
    % of arguments is preserved for the ess constructor
    c = setdiff(ep,sp,'stable');                 
end

% local essdata
function c = localEssData(obj)
% only return properties not in ss, e.g. l,q,r,m
    strListC = extraEssProperties(obj);
    extF = @(str) obj.(str);
    % must be in correct order to be passed to constructor
    c = cellfun(extF,strListC,'UniformOutput',false);
end

Mode Type Size Ref File
100644 blob 8 8661a74e3bb9b03feca04e50d8efe2bef1b850cb .gitattributes
100644 blob 120 cca258db030626db0c4ac1e890cc16eaf252108c .gitignore
040000 tree - 5f3320287cc52b8fe00f30aaeb720f4ead041eb4 @dac
040000 tree - 3742083c966615ed5cb083eb2a19af4d29d42016 @dadac
040000 tree - 9de17412e8ee68e0fe653eeab1b4774a97a895ea @daddc
040000 tree - c3e526da8c47c7fad5294dee214bb0befb2c3fd1 @ess
100644 blob 9760 35b8f790dee4b23110889efba1f24197fc8f536e README.org
100644 blob 3791 813c5e3910317ab2a1458fad0ffd4afaf8ae50cd README.txt
040000 tree - d28f3f04e3e1eb132dc3e89683f495183012b3b6 data_analysis
040000 tree - eb34931ccd81545efcd60c9adb209065dadc5cd0 kalmanfilter
040000 tree - 3043e60b6fbf9136eace3a65fb24c42c544c86ae misc
040000 tree - 1dddc962b8ecbf37a997ca89cad3711b3d69cfd8 models
040000 tree - a96e7cf3890bbe98927df60dcb1f69a8fa4382fd simulations
100644 blob 621 50214a520c35e3f600fe40789181c708967fcb88 startup.m
040000 tree - 86ca0a9d5bf2ede090afb7139b2f2d9d7a0af1db statisticstests
040000 tree - 3cf29c8555988b4e2f59b54f29a64facc143697a stochasticintegration
040000 tree - 7db02f73f80ee728bfacb21b724ba422ed617df9 tests
040000 tree - d4417b0e6958152f3591a8335f126bf84ff5ae5d thirdparty
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/gutc61/Membrane

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/gutc61/Membrane

Clone this repository using git:
git clone git://git.rocketgit.com/user/gutc61/Membrane

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main