/stochasticintegration/simgauss.m (a73d84dba379cd15093acd998994bedf5d56d498) (4640 bytes) (mode 100644) (type blob)

function seq = simgauss(mu,sigma,NT,varargin)
% seq = simgauss(mu,sigma,NT,...)
%
% Simulate a Gaussian random process using eigenvalue
% decomposition (default), Cholesky decomposition or cholcov.
%
% Input arguments:
% - mu = mean (scalar or vector)
% - sigma = covariance matrix (must be symmetric)
% - NT = number of samples
%
% Optional arguments (key/value pairs):
% - 'method', can be either
%    - 'eig' use eigenvalue decomposition
%    - 'chol' use Cholesky decomposition
%    - 'cholcov' use Cholesky covariance decomposition
%    - 'cholinc' use incomplet Cholesky decomposition (default)
% - 'droptol', tolerance for incomplete Cholesky decomposition (default: 1E-15)
% - 'testpos', can be true or false; Issue a warning if resulting covariance matrix
%    is not positive semi-definite
% - 'testdist' can be true or false; apply kstest to each sequence to check if it
%    follows a Gaussian distribution

% Note:
% - sigma must be positive semi-definite. The number of
%   negative eigenvalues can be checked by [~,num] = cholcov(sigma)
% - numerical errors may lead to non positive semi-definiteness
%   - cholinc neglects these errors if smaller than droptol and
%     returns full decomposition
%   - cholcov neglects subspace with negative eigenvalue and
%     returns decomposition in complementary subspace
%   - chol throws error

args = varargin;
nargs = length(args);

% set defaults
method = 'cholinc';
droptol = 1E-15;
checkpos = false;
checkdist = false;
showcdf = false;

% parse varargs
for ii = 1:2:nargs
    switch args{ii}
      case 'method', method = args{ii+1};
      case 'droptol', droptol = args{ii+1};
      case 'testpos', checkpos = args{ii+1};
      case 'testdist', checkdist = args{ii+1};
      case 'showcdf', showcdf = args{ii+1};
      otherwise, warning(['unrecognized argument ' args{ii}])
    end
end

% noise dimension
ss = size(sigma,1);

% if empty covariance is given return empty sequence
if isempty(sigma)
    seq = [];
    return
end

% if mu is scalar, all components
% have the same mean
if length(mu) == 1
    mum = mu;
else
    % Note: the final output is [NT,ss]
    mum = diag(mu)*ones(ss,NT);
end

% check sigma>=0
% (sampling a process which does not observe this will lead to
% negative Kalman estimation variances)
[~,pmark] = cholcov(sigma);
if pmark > 0
    error(['Given covariance matrix is not ' ...
           'positive semi-definite. Smallest eigenvalue is %g'], ...
          eigs(sigma,1,'sa'))
end

% Sample uncorrelated processes and transform
switch method
  case 'eig',
    % using eigenvalue decomposition
    % (see Stengel, p.337)
    % svd would probably be better as it is
    % numerically more stable
    [V,D] = eig(sigma);
    if not(all(diag(D>=0)))
        error(['Given covariance matrix is not positive ' ...
               'semi-definite.'])
    end
    C = V*sqrt(D);
    seq = C*randn(ss,NT)+mum;
  case 'chol',
    % using Cholesky decomposition
    % (see Stengel, p.339)
    C = chol(sigma);
    seq = C'*randn(ss,NT)+mum;
  case 'cholcov',
    % Note: this neglects zero eigenvalues
    % see cholchov help for more info
    C = cholcov(sigma);
    seq = C'*randn(size(C,1),NT)+mum;
  case 'cholinc',
    % obsolete in newer matlab versions
    % use 'ichol' instead
    C = cholinc(sparse(sigma),droptol);
    alpha = max(0,max(sum(abs(sigma),2)./diag(sigma))-2);
    seq = C'*randn(size(C,1),NT)+mum;
  case 'ichol',
    % Note: this is the prefered method as
    % its most robust to numerical errors which
    % lead to non positive definiteness
    % Does NOT work for SEMI-DEFINITE matrices!
    alpha = max(0,max(sum(abs(sigma),2)./diag(sigma))-2);
    C = ichol(sparse(sigma),struct('droptol',droptol,'type','ict'));
    seq = C*randn(size(C,1),NT)+mum;
  otherwise
    error(['unrecognized method ' args{1}])
end

% output sequence as [NT,ss] array
seq = seq.';

% tests
if checkdist
    disp('Kolmogorov-Smirnov test:')
    for mm = 1:size(seq,1)
        % make sure the tabulated values span the full range of x
        xx = (min(seq(mm,:))-1/NT:1/NT:max(seq(mm,:))+1/NT);
        cdff = @(x) [x;normcdf(x,0,sqrt(sigma(mm,mm)))];
        CDF = cdff(xx);                       % tabulate cdf values
        [h,p] = kstest(seq(mm,:),CDF')
        if showcdf
            figure
            cdfplot(seq(mm,:));
            plot(CDF(1,:),CDF(2,:),'r')
        end
    end
    disp('covariance matrix:')
    cm = cov(seq)
    disp('nominal:')
    sigma
end

if checkpos
    [~,pmark] = cholcov(cov(seq));
    if pmark>0
        warning(['Covariance matrix of sample is not ' ...
                 'positive semi-definite'])
    end
end


Mode Type Size Ref File
100644 blob 438 f9f50b6f68c8e89baa28c21553db2f36ec098625 .editorconfig
100644 blob 8 8661a74e3bb9b03feca04e50d8efe2bef1b850cb .gitattributes
100644 blob 120 cca258db030626db0c4ac1e890cc16eaf252108c .gitignore
100644 blob 225 4ab0fc5b00c27ebab1594fdbbaa91da074719ef6 .gitmodules
040000 tree - 9e9427aca55b0fdaf262275ff469e14af9e1dae4 @dac
040000 tree - 6105ca831f28c047b53092410d8348dbd61e0125 @dadac
040000 tree - aadf6ee88075017a2a9e0ddcfef931aa171b62b0 @daddc
040000 tree - 63d778570a3bc31ffc370989af768ed1c441cced @ess
040000 tree - 3912223b5d7d6d884eafaa2c95a54ab2480c669f PXItraces
100644 blob 9760 35b8f790dee4b23110889efba1f24197fc8f536e README.org
100644 blob 3791 813c5e3910317ab2a1458fad0ffd4afaf8ae50cd README.txt
040000 tree - d1dc46b6acce0b92cef345c42756580dde521a28 data_analysis
040000 tree - 5f6d15ef90ef441f941ddf500a4a2ea2554e048a homo_measurements
100644 blob 396 c3a05bd9edfd348cb275e1f57755acf43bc9d44e howto_evaluation.m
040000 tree - 5e9f54418509ae7a931754ea7a9a9025b273f201 kalmanfilter
040000 tree - 94a00a6660e0a3a3a6918e5c8c83d0c2b90bbe4b misc
040000 tree - a96e7cf3890bbe98927df60dcb1f69a8fa4382fd simulations
100644 blob 621 50214a520c35e3f600fe40789181c708967fcb88 startup.m
040000 tree - 3faaea82b680f5dc34950b9429a7bd31ef0a1915 statisticstests
040000 tree - 18501e84a79b4b70363c3bd843ec24e4f885ebdd stochasticintegration
040000 tree - 99d85accbbe17917d68805cdfebebdb33316c176 tests
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