实现密度功能

时间:2019-04-27 02:25:19

标签: algorithm function distribution montecarlo

我正在阅读我的书,其中指出:“为此密度函数编写一个采样算法”

y=x^2+(2/3)*x+1/3; 0 <  < 1

或者我可以使用蒙地卡罗(Monte Carlo)? 任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

我假设您有一个函数y(x),该函数的值介于[0,1]之间,并返回y的值。您只需要提供一个随机值x并返回对应的y值即可。

def getSample():
  #get uniform random number
  x = numpy.random.random()

  #sample my custom function
  return y(x)

答案 1 :(得分:0)

我假设您的意思是要生成具有密度x指定的分布的随机y(x)值。

通常希望通过对密度进行积分来得出累积分布函数,并使用inverse transform sampling来生成x值。在您的情况下,CDF是三阶多项式,它不考虑产生简单的立方根解,因此您必须使用数值求解器来找到逆数。是时候考虑替代品了。

另一种选择是使用acceptance/rejection method。在检查了导数之后,很明显您的密度是凸的,因此很容易通过从b(x)f(0)画一条直线来创建边界函数f(1)。这产生b(x) = 1/3 + 5x/3。此边界函数的面积为7/6,而您的f(x)的面积为1,因为它是有效密度。因此,在b(x)下统一生成的点的6/7也将落在f(x)下,并且拒绝尝试中7次尝试中只有1次失败。这是f(x)b(x)的情节:

Plot of f(x) and b(x) showing relatively tight bounding

由于b(x)是线性的,因此在将其缩放6/7以使其成为有效的分布函数后,很容易使用它作为分布来生成x值。用伪代码表示的算法将变为:

function generate():
  while TRUE:
    x <- (sqrt(1 + 35 * U(0,1)) - 1) / 5     # inverse CDF transform of b(x)
    if U(0, b(x)) <= f(x):
      return x
  end while
end function

其中U(a,b)表示生成一个在ab之间均匀分布的值,f(x)是您的密度,b(x)是上述的边界函数。

我实现了上述算法,以生成100,000个候选值,如预期的那样,拒绝了14,199(〜1/7)个候选值。最终结果显示在以下直方图中,您可以将其与上图中的f(x)进行比较。

Histogram of generated data having density f(x)