对数正态分布随机数c语言,在python中从对数正态分布生成随机数

你有对数正态分布的模式和标准偏差。要使用scipy的rvs()方法,必须根据形状参数s参数化分布,这是基本正态分布的标准差sigma,而{},即{},其中{}是基础分布的平均值。在

您指出,进行这种重新参数化需要求解四次多项式。为此,我们可以使用numpy.poly1d类。该类的实例有一个roots属性。在

一个小代数表明exp(sigma**2)是多项式唯一的正实根x**4 - x**3 - (stddev/mode)**2 = 0

其中stddev和{}是对数正态分布的给定标准差和模式,对于该解,scale(即exp(mu))是

^{pr2}$

下面是一个将模式和标准偏差转换为形状和比例的函数:def lognorm_params(mode, stddev):

"""

Given the mode and std. dev. of the log-normal distribution, this function

returns the shape and scale parameters for scipy's parameterization of the

distribution.

"""

p = np.poly1d([1, -1, 0, 0, -(stddev/mode)**2])

r = p.roots

sol = r[(r.imag == 0) & (r.real > 0)].real

shape = np.sqrt(np.log(sol))

scale = mode * sol

return shape, scale

例如In [155]: mode = 123

In [156]: stddev = 99

In [157]: sigma, scale = lognorm_params(mode, stddev)

使用计算的参数生成样本:In [158]: from scipy.stats import lognorm

In [159]: sample = lognorm.rvs(sigma, 0, scale, size=1000000)

这是样品的标准偏差:In [160]: np.std(sample)

Out[160]: 99.12048952171304

下面是一些matplotlib代码来绘制样本的柱状图,在绘制样本的分布模式下绘制一条垂直线:In [176]: tmp = plt.hist(sample, normed=True, bins=1000, alpha=0.6, color='c', ec='c')

In [177]: plt.xlim(0, 600)

Out[177]: (0, 600)

In [178]: plt.axvline(mode)

Out[178]:

柱状图:

5ab27f757d1418ab08572fdd4c9a58c0.png

如果要使用numpy.random.lognormal()而不是scipy.stats.lognorm.rvs()生成样本,可以执行以下操作:In [200]: sigma, scale = lognorm_params(mode, stddev)

In [201]: mu = np.log(scale)

In [202]: sample = np.random.lognormal(mu, sigma, size=1000000)

In [203]: np.std(sample)

Out[203]: 99.078297384090902

我还没有研究poly1d的roots算法的健壮性,所以一定要测试各种可能的输入值。或者,您可以使用scipy的解算器来求解x的上述多项式。可以使用以下方法绑定解决方案:max(sqrt(stddev/mode), 1) <= x <= sqrt(stddev/mode) + 1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值