在Zfit中定义二维高斯PDF遇问题,请求排查代码错误
Zfit自定义二维高斯PDF的错误排查
你的代码存在以下几个关键错误:
- 类方法缩进错误:
@zfit.supports()装饰器和_unnormalized_pdf方法没有缩进,不属于MyG类,导致Zfit无法识别这个PDF的核心计算方法。 - 未归一化PDF逻辑错误:
_unnormalized_pdf方法应返回未归一化的概率密度,你手动除以归一化因子A会导致Zfit后续自动归一化逻辑失效,生成异常分布。 - 变量引用错误:最后调用PDF值时用了
custom_pdf,但实际实例化的对象是pdf,变量名不匹配。 - 张量索引错误:指数计算中使用
x[0]、x[1]直接索引张量,而你已经通过z.unstack_x(x)得到了x1、y1,应使用这两个变量避免索引问题。 - 函数调用错误:
plt.show缺少括号,无法触发绘图显示。
修正后的完整代码
import zfit import numpy as np import matplotlib.pyplot as plt class MyG(zfit.pdf.ZPDF): _N_OBS = 2 # 维度,可省略 _PARAMS = ['mean_x', 'std_x', 'mean_y', 'std_y'] # 参数名称 @zfit.supports() def _unnormalized_pdf(self, x, params): x1, y1 = zfit.unstack_x(x) mean_x = params['mean_x'] std_x = params['std_x'] mean_y = params['mean_y'] std_y = params['std_y'] # 未归一化的二维高斯,不除以归一化因子,Zfit会自动处理归一化 exponent = -((x1 - mean_x) ** 2 / (2 * std_x ** 2) + (y1 - mean_y) ** 2 / (2 * std_y ** 2)) return zfit.exp(exponent) # 创建参数 meanx = zfit.Parameter("meanx", 5) meany = zfit.Parameter("meany", 5) stdx = zfit.Parameter("stdx", 1) stdy = zfit.Parameter("stdy", 1) # 定义观测空间 xobs = zfit.Space('xobs', limits=(1, 10)) yobs = zfit.Space('yobs', limits=(1, 10)) obsxy = yobs * xobs # 实例化PDF pdf = MyG(obs=obsxy, mean_x=meanx, mean_y=meany, std_x=stdx, std_y=stdy) # 生成网格点计算PDF值 x = np.linspace(1, 10, 100) y = np.linspace(1, 10, 100) X, Y = np.meshgrid(x, y) grid_points = np.column_stack([X.ravel(), Y.ravel()]) pdf_values = pdf.pdf(grid_points).numpy() Z = pdf_values.reshape(X.shape) # 绘图 fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') ax.plot_surface(X, Y, Z, cmap="viridis", alpha=0.7) plt.show()
关键修正说明
- 调整装饰器和方法的缩进,确保属于
MyG类的成员方法。 - 删除归一化因子
A的计算与除法操作,让Zfit自动处理归一化流程。 - 替换张量索引为
unstack_x得到的x1、y1,避免直接索引张量的潜在问题。 - 修正变量引用,将
custom_pdf改为实例化的pdf对象。 - 补全
plt.show()的括号,触发绘图显示。
内容的提问来源于stack exchange,提问作者King Meruem
相关产品推荐
相关产品推荐

