==> Due in class on M 10/13 <==
(1). Monte Carlo sampling of an exponential distribution.
The exponential probability density function has frequent applications in radiation transport, queuing theory, etc. As we learned in class, it is straightforward to sample such a distribution, p(x)= exp(-x/lambda)/lambda, (x>0), i.e., to produce x's that are distributed according to the probability density p(x). Here we first write an exponential random number generator that does this sampling, and then measure properties of the sampled x's and compare them with analytic results from p(x).
Below are some Maple codes. Some of what the codes do can be done simply by Maple library packages and made much more fancy. Exploring this possibility is good and encouraged, after you have understood the provided codes. These codes can be run through main, which reads in the other two. It looks like:
#------------------------------- 0 ----------------------------------- # read in the other 2 programs, run & mkhist: read run: read mkhist: with(plots): #------------------------------- 1 ----------------------------------- # set parameters to execute programs: n_mea := 10; # number of measurements # ^^ <-- MODIFY to change accuracy of final results n_smpls_per_mea := 100; # number of samples in each measurement # ^^^ <-- MODIFY to change statistics of measurements lambda := 1.5; # parameter lambda in exponential PDF # ^^^ <-- MODIFY to change PDF being sampled #------------------------------- 2 ------------------------------------ # execute programs: run(lambda, n_mea, n_smpls_per_mea): mkhist(lambda, n_mea, n_smpls_per_mea): #------------------------------- 3 ------------------------------------ # view results: # plot of histogram of sampled distribution vs analytical PDF: display({pex,phi},title=`Sample (pts) vs ext (line) PDF`); # computed <x> from samples and its statistical error: x_avg := sum(xacc[m], m=1..n_mea)/n_mea; x_err := sqrt((sum(xacc[m]^2, m=1..n_mea)/n_mea-x_avg^2)/(n_mea-1));
Download run and mkhist. Please note that there are two blanks you need to fill to make the codes work correctly. One is in the expression for the exponential random number generator ranexp in run; the other is the histogram normalization in mkhist.
run:
# ranxi() gives a random # uniform on (0,1) # We're trusting maple's generic RNG here, which may not be safe! ranxi := () -> (10e-13)*rand(); # ranexp(lambda) should give a random # distributed according to the # exponential probability density function exp[-x/lambda]/lambda # where x is on ( 0, +infinity ) and lambda ( >0 ) is a parameter. ranexp := (lambda) -> ranxi() ; # ^^^^^^^^^^^^ <-- MODIFY -- fill in correct form #### # program that calls ranexp(lambda) to generate a histogram of # distribution and also measures the first momentrun := proc(lambda, n_mea, n_smpls_per_mea) global xacc, hist, bin_range, bin_size, n_bins, bin_size_inv, midpt, bin; local bi, st, m, i, x; # -- define parameters and procedures for histogram: bin_range := 6. *lambda; #NOTE: prefactor can be changed bin_size := 0.1 *lambda; #NOTE: prefactor can be changed n_bins := trunc(bin_range/bin_size)+1; #last bin to store x > bin_range bin_size_inv := 1./bin_size; hist := array(1..n_bins); for bi to n_bins do hist[bi] := 0 od: bin := proc(x) global n_bins, bin_size_inv; min(trunc(x*bin_size_inv)+1,n_bins) end: # bin(x) gives which bin x is in. midpt := proc(i) global bin_size; (i-0.5)*bin_size end: # midpt(i) gives mid-pt of bin i #### # -- xacc[m] stores the m^th measurement of xacc := array(1..n_mea); # -- n_mea measurements [first do loop (with m)], # EACH with n_smpls_per_mea samples [second do loop (with i)] : for m from 1 to n_mea do xacc[m] := 0: for i to n_smpls_per_mea do x := ranexp(lambda): xacc[m] := xacc[m] + x: bi := bin(x): hist[bi] := hist[bi] +1 od; xacc[m] := xacc[m]/n_smpls_per_mea: od; # end:
# program to fix up histogram (normalization, etc) and # prepare plots with both histogram and the analytical PDF # called AFTER a call to 'run' mkhist := proc(lambda, n_mea, n_smpls_per_mea) # global xacc, hist, bin_range, bin_size, n_bins, midpt, phi, pex; local histnorm_inv, bi, hi, exact_pdf; # # normalize histogram (histnorm_inv is INVERSE of normalization): histnorm_inv := 1. : # ^^^^^^^^^^^^^^^^^^^^^^^^^^ <-- MODIFY -- # fill in correct form # Note histnorm_inv appears in the following line: for bi to n_bins do hist[bi] := hist[bi]*histnorm_inv od: # plot histogram: hi := [[midpt(n),hist[n]] $n=1..n_bins]: phi := plot(hi,x=0..bin_range+bin_size,style=point,symbol=circle,color=red): # plot exact probability density function exact_pdf := proc(x) global lambda; exp(-x/lambda)/lambda: end: pex := plot(exact_pdf(x),x=0..bin_range+bin_size,style=line,color=blue): # end:
(2). Random walks with traps, and Green's function.
We consider again the one-dimensional version of the drunkard problem discussed in class. This time he starts out at position x (e.g., x=10), and takes unit steps left or right with equal probability. Suppose at 0 and a (a>x>0, e.g., a=30) are two bars. When he reaches either one, he is trapped forever.