Algorithm 2.1 Invert Multi-outcome Discrete Density N = 4 # number of outcomes oc = [2,3,4,5] # list the outcomes, 2 through 5 eggs op = [0.15,0.2,0.6,0.05] # list of outcome probabilities bp = [0]*N # set up the breakpoints bp[0]=op[0] for i in range(1,N): bp[i] = bp[i-1] + op[i] # end of set up, go here to get samples U=random.random(); k=0; while( U >= bp[k]): k=k+1; selected = oc[k] print(selected)
Algorithm 2.2 Roulette Wheel Selection import random N = 4 tabLen = 100 oc = [2,3,4,5] op = [0.15,0.2,0.6,0.05] # event probabilities op =[int(op[i]*tabLen) for i in range(len(op))] # 15,20,60,5 # set up: assign fractions of 100 according to the probabilities rv = [] # for return values for i in range(len(op)): for j in range(op[i]): rv.append(oc[i]) # end of setup, go here to get samples k = random.randint(0,99) # rv[k] is selected selected = rv[k]
Algorithm 2.3 Vector Algorithm for Discrete Selection import random op = [0.15,0.2,0.6,0.05]} bp = [] bp.append(op[0]) for i in range(1,len(op)): bp.append(bp[i-1]+op[i]) N = 10000 u = np.random.rand(N) # N vector of samples from U(0,1) w2 = (u < bp[0])*2 # 2's where true a = np.array(u>=bp[0]) # working arrays needed b = np.array(u< bp[1]) # for the and operation w3 = (a & b)*3 # 3's where true a = np.array(u>=bp[1]) b = np.array(u< bp[2]) w4 = (a & b)*4 # 4's where true w5 = (u>=bp[2])*5 # 5's where true w = w2+w3+w4+w5 # 10000 vector with the right frequencies
Algorithm 2.4 Walker Construction Algorithm import numpy as np import matplotlib.pyplot as plt def firstUnder(arr): #but greater than 0 k=0 while( True ): if( arr[k] == 0 or arr[k] > S ): k += 1 else: break; return k def firstOver(arr): k = 0 while( True ): if( arr[k] < S): k += 1 else: break; return k def reset(idx,ind): Q[idx] = tab[idx] tab[idx] = 0 resid = S - Q[idx] A[idx] = ind tab[ind] -= resid ### mmm ### #rw = [.3,.4,.1,.2] rw = [.02,.04,0.08,.15,.2,.21,.16,.09,.05]; M = len(rw) tab = [0]*M for i in range(M): tab[i] = rw[i] Q = [0]*M A = [0]*M S = 1.0/M for i in range(M-1): t = firstUnder(tab) #take from this sector p = firstOver(tab) #put the residual here reset(t,p) #last t = 0; max = 0; for i in range(M): if( tab[i] > max): max = tab[i]; t = i Q[t] = tab[t] #print("Q-pre",Q) for i in range(len(Q)): Q[i] *= len(Q) print("Q: ",end="") for i in range(len(Q)): print(str(round(Q[i],3))+" ",end="") print("") print("A: ",A)
Algorithm 2.5 Poisson Sampling import numpy as np import random import matplotlib.pyplot as plt def poissonSample(targ): u = 1; x = 0 while( u > targ): last = x u *= random.random() #print("u now "+str(u)+", last now "+str(last)) x += 1 return last lam = 0.1 # event rate per minute, lambda is a reserved word t = 30 # number of minutes targ = np.exp(-lam*t) # get a sample X = poissonSample(targ) print(X)
Algorithm 2.6 Rational Approximation to the Normal CDF import numpy as np import random import matplotlib.pyplot as plt # Abramowitz and Stegun def normalCDF(x): a1 = 0.31938153; a2 = -0.356563782; a3 = 1.781477937; a4 = -1.821255978; a5 = 1.330274429; b=0.2316410; c=1/np.sqrt(2*np.pi) L=abs(x); K=1/(1+b*L); w = 1-c*np.exp(-L*L/2)*K*(a1+K*(a2+K*(a3+K*(a4+a5*K)))); msign = -(x<0); mfact = 2*msign+1; w = mfact*(w+msign) return w x = 1 print(normalCDF(x))
Algorithm 2.7 Gilbrat's Approximation Example import numpy as np import random import matplotlib.pyplot as plt a = 0.2; b=2.0; n=10 c = b-a alfa = (n/c)*(b*(np.log(b)-1)-a*(np.log(a)-1)) beta2 = (n/c)*(b*(np.log(b)*np.log(b)-2*np.log(b)+2)-\ a*(np.log(a)*np.log(a)-2*np.log(a)+2))-alfa**2 beta = np.sqrt(beta2) nReps = 2000000 X = np.zeros(nReps) for i in range(nReps): R = 1; for j in range(n): r = a + c*random.random() R *= r X[i] = R ## generate the normal samples using alfa and beta logXexact = beta*np.random.randn(nReps)+alfa # do the lognormal Xexact = np.exp(logXexact) xmin = 0; xmax = 200 fig = plt.figure() ax = plt.subplot(111) ax.hist(Xexact, bins=200, density=True, log = True, \ range = [0,xmax],label="exact lognormal") plt.hist(X, bins=200, density=True, log = True, \ range = [0,xmax],label="product random variable") ax.legend() x = np.linspace(xmin,xmax) y = (1/(x*beta*np.sqrt(2*np.pi)))*\ np.exp(-(np.log(x)-alfa)**2/(2*beta*beta)) ax.plot(x, y, 'k', linewidth=1) # plot in black plt.xlabel("X") plt.ylabel("probability density") title = "Lognormal Histogram Comparison, alpha= {:.2f}, beta= {:.2f}".\ format(alfa, beta) plt.title(title) plt.show() fig.savefig('lognormal_comparisonDisp.png')
Algorithm 2.8 Joint Sampling Over a Triangle mport numpy as np import matplotlib.pyplot as plt x = [0,0,1,0] y = [0,1,0,0] plt.plot(x,y) for i in range(200): u1 = np.sqrt(np.random.uniform()) u2 = np.random.uniform() x = 1-u1 y = u2*u1 plt.scatter(x,y,color='black',s=8) plt.text(0.40,0.67, "y=1-x", fontsize=12) plt.title("200 points uniformly over a triangle") plt.hlines(0.685,0.322,0.39) #plt.savefig("uniformovertrianglefig.png") plt.show()