求助:参考Monte Carlo卡方实现编写monte_carlo_gaussian函数
monte_carlo_gaussian函数修复方案
核心问题清单
- 高斯分布公式错误:现有
gaussian函数的指数运算作用范围错误,标准正态分布概率密度公式为 $\frac{1}{\sqrt{2\pi}} \cdot e{-\frac{x2}{2}}$,仅自然常数e参与指数运算,原代码将整个前半段表达式做指数处理,输出值完全不符合高斯分布定义。 - y轴采样范围错误:原代码y值采样范围与x轴一致为
[a, b],但高斯函数值域为$(0, \frac{1}{\sqrt{2\pi}}]$(最大值约0.3989),若a为负数会采样到无效负y值,且上限远高于高斯函数最大值,采样效率极低、结果偏差大。 - 积分计算逻辑错误:蒙特卡洛投点法计算定积分的公式为「采样矩形面积 × 曲线下点的占比」,采样矩形面积为x轴区间长度$(b-a)$乘以y轴采样区间高度,原代码直接返回
b * 占比不符合计算逻辑。
修正后完整代码
import math import numpy as np def gaussian(x): # 修正公式,仅e做指数运算 return (1 / math.sqrt(2 * math.pi)) * (math.e ** (-x ** 2 / 2)) def under_curve(x, y): if 0 <= y <= gaussian(x): return True else: return False def greater_than(x, a): return x > a def less_than(x, b): return x < b def monte_carlo_gaussian(a, b, n): # x采样范围保持[a, b] x = np.random.uniform(low=a, high=b, size=n) # y采样范围修正为0到高斯函数最大值 y_max = 1 / math.sqrt(2 * math.pi) y = np.random.uniform(low=0.0, high=y_max, size=n) i = 0 ndartsunder = 0 ndarts = 0 for xi in x: yi = y[i] if less_than(xi, b) and greater_than(xi, a): ndartsunder += 1 * under_curve(xi, yi) ndarts += 1 i += 1 prob_under_curve = ndartsunder / ndarts # 修正面积计算:矩形面积(宽*高) × 占比 return (b - a) * y_max * prob_under_curve # 测试示例:计算[-1,1]区间的积分,结果应接近0.6827 print(monte_carlo_gaussian(-1, 1, 100000))
内容的提问来源于stack exchange,提问作者ashnotallyson
相关产品推荐
相关产品推荐

