Mercurial > hg > ltpda
diff m-toolbox/classes/@ssm/doSimulate.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@ssm/doSimulate.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,145 @@ +% DOSIMULATE simulates a discrete ssm with given inputs +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: DOSIMULATE simulates a discrete ssm with given inputs. +% +% CALL: [x, y, lastX] = doSimulate(SSini, Nsamples, A, Baos, Coutputs, Cstates, Daos, Bnoise, Dnoise, Bcst, Dcst, aos_vect, doTerminate, terminationCond, displayTime, timestep) + +% +% INPUTS: +% +% OUTPUTS: +% +% +% VERSION: $Id: doSimulate.m,v 1.8 2010/09/08 11:39:20 adrien Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% TO DO: Check input aos for the timestep, tsdata, and ssm.timestep +% options to be defined (NL case) +% add check if one input mach no ssm input variable +% allow use of other LTPDA functions to generate white noise + + +function [x, y, lastX] = doSimulate(SSini, Nsamples, A, Baos, Coutputs, Cstates, Daos, Bnoise, Dnoise, Bcst, Dcst, aos_vect, doTerminate, terminationCond, displayTime, timestep, forceComplete) + + % We do a simple simulate if all these are satisfied: + % 1) Bnoise is empty or all zeros + % 2) Cstates is empty + % 3) Dnoise is empty or all zeros + % 4) Bcst is empty or all zeros + % 5) Dcst is empty or all zeros + % 6) doTerminate is false + + if (isempty(Bnoise) || all(all(Bnoise==0))) && ... + isempty(Cstates) && ... + (isempty(Dnoise) || all(all(Dnoise==0))) && ... + (isempty(Bcst) || all(all(Bcst==0))) && ... + (isempty(Dcst) || all(all(Dcst==0))) && ... + ~doTerminate && ... + ~forceComplete + % do a fast simulation + Nstates = numel(SSini); + + if Nstates >= 100 + % except if Matlab is faster + [x,y,lastX] = doSimulateSimple(SSini, Nsamples, A, Baos, Coutputs, Daos, aos_vect); + else + try + % call to the mex file + x = []; + [y,lastX] = ltpda_ssmsim(SSini, A.', Coutputs.', Cstates.', Baos.', Daos.', aos_vect); + catch + % backup if the mex-file is broken + warning('Failed to run mex file ltpda_ssmsim'); + [x,y,lastX] = doSimulateSimple(SSini, Nsamples, A, Baos, Coutputs, Daos, aos_vect); + end + end + else + % the standard old script, more complete (DC and noise inputs) + [x,y,lastX] = doSimulateComplete(SSini, Nsamples, A, Baos, Coutputs, Cstates, Daos, Bnoise, Dnoise, Bcst, Dcst, aos_vect, doTerminate, terminationCond, displayTime, timestep); + end + +end + + +function [x,y,lastX] = doSimulateSimple(lastX, Nsamples, A, Baos, Coutputs, Daos, aos_vect) + + disp('Running simulate simple...'); + % initializing fields + x = []; + y = zeros(size(Coutputs,1), Nsamples); + lastX = A*lastX + Baos*aos_vect(:,1); + % time for displaying remaining time + + % simulation loop + for k = 1:Nsamples + % computing and storing outputs + y(:,k) = Coutputs*lastX + Daos*aos_vect(:,k); + % computing and storing states + lastX = A*lastX + Baos*aos_vect(:,k); + end + +end + +function [x,y,lastX] = doSimulateComplete(lastX, Nsamples, A, Baos, Coutputs, Cstates, Daos, Bnoise, Dnoise, Bcst, Dcst, aos_vect, doTerminate, terminationCond, displayTime, timestep) + + disp('Running simulate complete...'); + + %% converting to sparse matrices + if numel(A)>0; if(sum(sum(A==0))/numel(A))>0.5; A = sparse(A); end, end + if numel(Baos)>0; if(sum(sum(Baos==0))/numel(Baos))>0.5; Baos = sparse(Baos); end, end + if numel(Coutputs)>0; if(sum(sum(Coutputs==0))/numel(Coutputs))>0.5; Coutputs = sparse(Coutputs); end, end + if numel(Cstates)>0; if(sum(sum(Cstates==0))/numel(Cstates))>0.5; Cstates = sparse(Cstates); end, end + if numel(Daos)>0; if(sum(sum(Daos==0))/numel(Daos))>0.5; Daos = sparse(Daos); end, end + if numel(Bnoise)>0; if(sum(sum(Bnoise==0))/numel(Bnoise))>0.5; Bnoise = sparse(Bnoise); end, end + if numel(Dnoise)>0; if(sum(sum(Dnoise==0))/numel(Dnoise))>0.5; Dnoise = sparse(Dnoise); end, end + if numel(Bcst)>0; if(sum(sum(Bcst==0))/numel(Bcst))>0.5; Bcst = sparse(Bcst); end, end + if numel(Dcst)>0; if(sum(sum(Dcst==0))/numel(Dcst))>0.5; Dcst = sparse(Dcst); end, end + + %% initializing fields + x = zeros(size(Cstates,1), Nsamples); + y = zeros(size(Coutputs,1), Nsamples); + Nnoise = size(Bnoise,2); + BLOCK_SIZE = min( [ floor(1e6/(size(Baos,2) + size(Baos,1) + size(Bnoise,2) + 1)) , Nsamples]); + noise_array = randn(Nnoise, BLOCK_SIZE); + lastX = A*lastX + Bcst + Bnoise*noise_array(:,1) + Baos*aos_vect(:,1); + % time for displaying remaining time + time1=time; + + %% simulation loop + for k = 1:Nsamples + %% writing white noise and displaying time + if rem(k,BLOCK_SIZE)==0 + noise_array = randn(Nnoise, BLOCK_SIZE); + if displayTime + display( [' simulation time : ',num2str(k*timestep) ]); + time2 = time; + tloop = floor(time2.utc_epoch_milli-time1.utc_epoch_milli)/1000; + display( ['remaining computing time : ',num2str(tloop*(Nsamples-k+1)/k), 's' ]); + end + end + + %% evaluating differences + knoise = rem(k,BLOCK_SIZE-1)+1; + + %% computing and storing outputs + y(:,k) = Coutputs*lastX + Dcst + Dnoise*noise_array(:,knoise) + Daos*aos_vect(:,k); + + %% computing and storing states + x(:,k) = Cstates*lastX; + lastX = A*lastX + Bcst + Bnoise*noise_array(:,knoise) + Baos*aos_vect(:,k); + + %% checking possible termination condition + if doTerminate + if eval(terminationCond) + x = x(:,1:k); + y = y(:,1:k); + break; + end + end + + end + +end +