首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义Python蒙特卡罗积分函数低估了多维积分

自定义Python蒙特卡罗积分函数低估了多维积分
EN

Stack Overflow用户
提问于 2021-02-28 09:00:39
回答 1查看 219关注 0票数 0

我需要创建一个自定义的蒙特卡罗集成函数,以适应使用NumPy的自定义多维分布对象。我需要它在每个维度中集成相同的值。它在单个维度上工作正常,但在多个维度上低估了,随着维度的增加,情况会变得更糟。我正在使用这个paper (方程式5)作为指导。我的体积*平均密度公式是错误的吗?我的抽样方法有误吗?我真的不知道错误是什么。

代码语言:javascript
复制
import numpy as np
from scipy.stats import multivariate_normal

# Set up distribution parameters.
dim = 3
loc = np.repeat(0., repeats=dim)
scale = np.repeat(1., repeats=dim)

# Initialize a multivariate normal distribution.
mvn = multivariate_normal(mean=loc, cov=scale)

def mc_integrator(distribution, dim, support, size=1000, seed=0):
    """
    Parameters
    ----------
    distribution : function
        A probability density function.
    dim : int
        The number of dimensions of the distribution.
    support : list
        List of the low and high values of the hypercube to integrate over.
    size : int, optional
        Number of samples used for estimation. The default is 1000.
    seed : int, optional
        A random seed for reproducibility. The default is 0.

    Returns
    -------
    float
        The estimate of the integral over the hypercube.
    """
    # Set the random seed.
    np.random.seed(seed)
    # Separate the elements of the support.
    a, b = support[0], support[1]
    # Calculate the volume of the hypercube.
    volume = (b-a)**dim
    # Generate random samples of the appropriate shape.
    samples = np.random.uniform(low=a, high=b, size=(size,dim))
    # Return the estimate of the integral.
    return volume*np.mean(distribution(samples))

# Set the number of samples to use for estimation.
size = 10000
# Set the low and high value over each dimension of the hypercube.
support = [-2, 2]
# Print the estimate of the integral.
print(mc_integrator(mvn.pdf, dim, support, size=size))
# Print the exact value of the integral.
print(mvn.cdf(np.repeat(support[1], dim))-mvn.cdf(np.repeat(support[0], dim)))

Output: 0.8523870204938726
        0.9332787601629401
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-02 00:44:53

约翰,总体上看起来不错,但在我看来,你没有正确计算出预期的结果。我认为预期的结果应该是(F(2) - F(-2)^3,其中F是均值为0和方差为1的高斯cdf。对于F(2) - F(-2),我得到的erf(sqrt(2))约为0.9545,然后(F(2) - F(-2))^3为0.8696,这与您的结果非常吻合。

我不知道mvn.cdf应该返回什么,但"cdf“的概念在多个维度上都有点可疑,所以也许你可以避开它。

关于多维积分,你通常会提到使用Halton序列。我认为这也是一个有趣的想法。我计算积分的经验是使用一维或二维的求积规则,使用3到几个(5? 7?)的低偏差序列。我不知道),和MC在更多。哦,还有,我的建议是,在求助于数值近似之前,要努力获得准确的结果。

我很有兴趣听听你在做什么。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66404952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档