Article View: comp.soft-sys.matlab
Article #19SOURCE: randg.m - generate samples from arbitrary PDF
From: Michael Maurer
Date: Sat, 23 Jan 1993 01:06
Date: Sat, 23 Jan 1993 01:06
134 lines
5270 bytes
5270 bytes
Hoping to start a trend, here is an unsolicited matlab m-file.
RANDG generates samples from an arbitrary probability distribution
function, specified symbolically. Suggested improvements are welcome.
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# randg.m
# This archive created: Fri Jan 22 16:56:20 1993
export PATH; PATH=/bin:$PATH
echo shar: extracting "'randg.m'" '(3479 characters)'
if test -f 'randg.m'
then
echo shar: will not over-write existing file "'randg.m'"
else
sed 's/^XX//' << \SHAR_EOF > 'randg.m'
XXfunction x=randg(PDF_,BND_,ICBND_,N_,opts_)
XX
XX%RANDG
XX% Generates samples from arbitrary probability distributions.
XX% X=randg(ICDF,N) uses the inverse cumulative distribution
XX% function ICDF with argument 'y' and result 'x'. For example,
XX% ICDF='x=-log(1-y)' is the inverse CDF for 'y=exp(-x)' (x>0),
XX% which has CDF 'y=1-exp(-x)'. N is the number of samples.
XX%
XX% X=randg(PDF,BND,ICBND,N) works when the CDF is not easily inverted.
XX% PDF is a string like 'yp=exp(-x/2)' that describes the
XX% probability density function 'yp' as a function of 'x'. BND is
XX% another string that defines a function that is everywhere
XX% not less than PDF, for example 'yb=exp(-x/4)' for x>0. ICBND
XX% is the inverse of the CDF of BND, in this case the inverse of
XX% 'y=1-exp(-x/4)' which is 'x=-4*log(1-y)', defined for 0<=y<=1.
XX% Note that the names of the variables must be the same as shown
XX% here (x, y, yp, and yb). Intermediate variables may have any name
XX% that does not end with '_' and which is not a built-in M-file
XX% variable (such as 'nargin').
XX%
XX% X=randg(PDF,BND,ICBND,N,'plot') will plot the algorithm's progress.
XX%
XX% Here is a complicated example of the second method, taken from
XX% Leon-Garcia "Probability and Random Processes for Electrical
XX% Engineering", p. 174. It generates samples X from a gamma pdf with
XX% parameter alpha, 0<alpha<1.
XX%
XX% PDF = 'alpha=0.33;yp=x.^(alpha-1).*exp(-x)/gamma(alpha);'
XX%
XX% BND = [ 'alpha=0.33; ';
XX% 'Ip=find(x>1); In=find(x<=1); ';
XX% 'yb=x; ';
XX% 'yb(In)=x(In).^(alpha-1)/gamma(alpha);';
XX% 'yb(Ip)=exp(-x(Ip))/gamma(alpha); ']
XX% ICBND= ['alpha=0.33; '
XX% 'e=exp(1); '
XX% 'In=find(y<(e/(alpha+e))); '
XX% 'Ip=find(y>=(e/(alpha+e))); '
XX% 'x=y; '
XX% 'x(In)=((alpha+e)*y(In)/e).^(1/alpha); '
XX% 'x(Ip)=-log((alpha+e)*(1-y(Ip))/alpha/e);']
XX
XX% Michael Maurer, 5 May 1991
XX% Copyright (c) 1993 by Michael Maurer
XX
XXdist_=rand('dist');
XXrand('uniform');
XXif nargin==2,
XX ICDF_=PDF_;
XX N_=BND_;
XX y=rand(N_,1);
XX for l_=1:height(ICDF_),
XX eval(ICDF_(l_,:)); % x=ICDF_(y)
XX end
XXelse
XX xf_=zeros(N_,1);
XX fnd_=0;
XX eff_=0.99; % initial guess to efficiency
XX while fnd_<N_,
XX Ntry_=fix((N_-fnd_)/eff_+10); % slightly overestimate misses
XX y=rand(Ntry_,1);
XX for l_=1:height(ICBND_),
XX eval(ICBND_(l_,:)); % x=ICBND_(y)
XX end
XX for l_=1:height(BND_),
XX eval(BND_(l_,:)); % yb=BND_(x)
XX end
XX for l_=1:height(PDF_),
XX eval(PDF_(l_,:)); % yp=PDF_(x)
XX end
XX t_=rand(Ntry_,1);
XX Ifnd_=find(t_.*yb <= yp);
XX Nfnd_=length(Ifnd_);
XX Nfnd_=min([N_-fnd_ Nfnd_]);
XX xf_(fnd_+1:fnd_+Nfnd_)=x(Ifnd_(1:Nfnd_));
XX fnd_=fnd_+Nfnd_;
XX eff_=Nfnd_/Ntry_;
XX
XX if nargin>4, % nifty graphical debugging
XX disp2('Begin loop with ', N_-(fnd_-Nfnd_), ' samples needed.');
XX disp2('Efficiency this iteration was ', eff_);
XX if (fnd_-Nfnd_+length(Ifnd_)>N_),
XX disp2('Computed ', fnd_-Nfnd_+length(Ifnd_)-N_, ' extra samples');
XX end;
XX hold off;
XX axis([min(x) max(x) 0 min(4,max(yp))]);
XX [xx_,ii_]=sort(x);
XX plot(xx_,yb(ii_));
XX hold on;
XX plot(xx_,yp(ii_));
XX tt_=t_.*yb;
XX plot(x(Ifnd_),tt_(Ifnd_),'.')
XX Infnd_=find(tt_>yp);
XX plot(x(Infnd_),tt_(Infnd_),'o')
XX hold off;
XX if fnd_<N_,
XX disp('Hit a key for next iteration')
XX pause
XX end
XX end
XX end
XX x=xf_;
XXend
XXrand(dist_)
SHAR_EOF
if test 3479 -ne "`wc -c < 'randg.m'`"
then
echo shar: error transmitting "'randg.m'" '(should have been 3479 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
______________________________________________________________________
Michael Maurer maurer@nova.stanford.edu (415) 723-1024
Technical Details
Message-ID:
<maurer.727751195@nova.Stanford.EDU>Path:
arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!nntp.Stanford.EDU!forsythe.stanford.edu!nova!maurerShow Full Headers
Complete Article Headers
Newsgroups: comp.soft-sys.matlab Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!nntp.Stanford.EDU!forsythe.stanford.edu!nova!maurer From: Michael Maurer <maurer@nova.stanford.edu> Subject: SOURCE: randg.m - generate samples from arbitrary PDF Message-ID: <maurer.727751195@nova.Stanford.EDU> Sender: news@leland.Stanford.EDU (Mr News) Organization: STAR Lab, Stanford University, California USA Date: 23 Jan 93 01:06:35 GMT Lines: 134