使用Python(Scipy)求解两个高斯函数区间交点的代码报错排查
代码核心错误点
- 求解目标逻辑偏差
scipy.optimize.root的求解规则是找到输入值,让传入的目标函数的每一个输出分量都等于0。当前代码的目标函数是分别返回G1、G2的独立函数值,首先高斯函数的取值恒为正,本身不存在能让输出等于0的x;其次完全没有构造「两函数值相等(即差值为0)」的求解目标,本质是把找交点的问题错当成了找两个高斯函数自身零点的问题,逻辑上从根上就不成立。 - 输入输出维度不匹配
传入的初始猜测点是长度为1的一维数组[2],但目标函数返回了长度为2的列表,违反了求解器要求的「目标函数输出维度与初始猜测维度一致」的规则,hybr方法会直接触发维度校验报错。
修正实现方法
- 重写目标函数:把原来返回两个独立高斯值的逻辑,替换为返回两个高斯值的差值——当差值为0时,对应的x就是两个函数的交点。
- 合理设置初值:本次联立的两个高斯函数,两边取对数消去指数项后可整理为一元二次方程,区间(-5,5)内一共存在两个实根,分别在两个根的附近设置初值,就能稳定覆盖全部交点,避免漏解。
- 可直接运行的修正代码:
import numpy as np from scipy.optimize import root def gauss_diff(x): # G1(x, 均值0, 标准差1) g1 = (1 / np.sqrt(2 * np.pi * 1**2)) * np.exp(-(x[0])**2 / (2 * 1**2)) # G2(x, 均值1, 标准差2) g2 = (1 / np.sqrt(2 * np.pi * 2**2)) * np.exp(-(x[0] - 1)**2 / (2 * 2**2)) # 返回差值,求解目标为让该差值等于0 return g1 - g2 # 分别在两个解的邻域设置初值,覆盖求解区间内的全部交点 sol1 = root(gauss_diff, x0=-2, method='hybr') sol2 = root(gauss_diff, x0=3, method='hybr') print(f"求解区间内两个交点位置分别为:x1={sol1.x[0]:.4f}, x2={sol2.x[0]:.4f}")
补充说明:之前使用简单公式时代码能正常运行,通常是因为当时正确构造了单分量的差值目标,输入输出维度匹配,不存在逻辑错误。
内容的提问来源于stack exchange,提问作者Howdy
相关产品推荐
相关产品推荐

