samer@3: % rndseq - Sequence of values sampled from a random variable model samer@3: % samer@3: % rndseq :: samer@3: % model xdom:[[1,XD]] ~ random variable model, data size is xdom, samer@3: % sdom:[[1,SD]], ~ size of sample, samer@3: % -> seq([[xdom sdom]]) ~ size of rndseq is product of xdom and sdom samer@3: % samer@3: % rndseq :: samer@3: % model xdom:[[1,XD]] ~ random variable model, data size is xdom, samer@3: % sdom:[[1,SD]], ~ size of sample, samer@3: % rndstate ~ initial state of generators samer@3: % -> rndseq([[xdom sdom]]) ~ size of rndseq is product of xdom and sdom samer@3: % samer@3: % If an initial rndstate is supplied, rndseq is purely functional samer@3: % and referentially transparent. Otherwise, the initial construction samer@3: % uses the current state of the random generators. After this, the samer@3: % entire sequence is fully determined. samer@3: % samer@3: % EXAMPLE samer@3: % samer@3: % rndseq(gaussian,[2,200]) :: seq [[2,200]] samer@3: % rndseq(dirichlet(3,0.5),6) :: seq [[3,6]] samer@3: function d=rndseq(model,sdom,k) samer@3: if nargin<2, sdom=1; end samer@3: if isa(model,'struct') samer@3: if model.nparams>0, samer@3: error('Model has unbound parameters'); samer@3: end samer@3: gen=sampler(model.sample,sdom); samer@3: elseif iscell(model) samer@3: gen=sampler(model{1},sdom); samer@3: end samer@3: samer@3: if nargin>2, samer@3: if ~iscell(k), s={k,k}; else s=k; end samer@3: else samer@3: s=getrndstate; samer@3: end samer@3: d=unfoldseq(gen,s); samer@3: end samer@3: samer@3: % this creates a rand-state-managed version of g applied to args, samer@3: % ie, samer@3: % sampler :: samer@3: % ((A1,A2,....) -> random B) ~'an action which generates a value' samer@3: % -> (rndstata -> B, rndstate) ~'a deterministic random state transformer'. samer@3: function f=sampler(g,varargin) samer@3: f=@ufn; samer@3: function [x,s]=ufn(s) samer@3: setrndstate(s); x=g(varargin{:}); samer@3: s=getrndstate; samer@3: end samer@3: end samer@3: