1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- import numpy
- import convolveLN
- def generateSample(mu,cv):
- return numpy.array([convolveLN.ln(mu,cv) for i in range(10000)])
- def getEdges(a):
- #convert array of bin centers a to array of bin edges with one more element than a
- a1=numpy.zeros(len(a)+1)
- a2=numpy.zeros(a1.shape)
- a1[1:]=a
- a2[:-1]=a
- e=0.5*(a1+a2)
- e[0]=2*e[1]-e[2]
- e[-1]=2*e[-2]-e[-3]
- return e
- def calculateDistribution(fy,muTarget,mu,cv,dydp):
- #calculate distribution of random variable y with a functional dependence
- #on random parameters p, each with a log-normal
- #distribution with a mean mu(p) and coefficients of variation cv(p)
- #and dydp giving partial derivatives of y on p
- #muTarget is the target mean of y distribution
- #fy is the set of values y where distribution is evaluated at
- #Parameters mu, cv and dydp are given as vectors/lists
-
- qa=mu*dydp
- A=numpy.sum(qa)
- qa*=muTarget/A
- cvPrime=cv*A/muTarget
- sigmaS=numpy.sqrt(numpy.log(1+cvPrime*cvPrime))
- muS=numpy.log(qa/numpy.sqrt(1+cvPrime*cvPrime))
- y=convolveLN.convolveLN(fy,sigmaS,muS)
- return y/numpy.sum(y)
- def generateDistribution(fx,muTarget,mu,cv,dydp, dbg=0):
- #sum randomly generated variables to approximate distribution of
- #variable y with a functional dependence y(p) on random parameters p,
- #each with a log-normal (LN) distribution
- #with a mean mu(p) and coefficient of variation cv(p)
- #target mean of y is muTarget
- #distribution is evaluated at points fy,
- #dydp are derivatives of y with respect to parameters p
-
- qa=mu*dydp
- A=numpy.sum(qa)
- qa*=muTarget/A
- cvPrime=cv*A/muTarget
- samples=[a*generateSample(1,c) for a,c in zip(qa,cvPrime)]
- mean=[numpy.mean(s) for s in samples]
- std=[numpy.std(s) for s in samples]
- convSample=numpy.zeros(len(samples[0]))
- msg='[{}] mean={:.2f} std={:.2f} cv={:.2f}'
- for i in range(len(cv)):
- convSample+=samples[i]
- if dbg:
- print(msg.format(i,mean[i],std[i],std[i]/mean[i]))
-
- convM=numpy.mean(convSample)
- convS=numpy.std(convSample)
- if dbg:
- code=x
- print(msg.format(code,convM,convS,convS/convM))
- h,be=numpy.histogram(convSample,bins=getEdges(fx))
- #h should be len(fx)
- return h/numpy.sum(h)
-
-
|