Python使用scipy.integrate高斯求积时触发不可调用类型报错
报错核心原因
scipy.integrate.quadrature 高斯求积接口的第一个入参要求是可调用的函数对象:即能接收积分节点值作为输入、返回对应位置函数计算结果的函数。你当前传入的solD[i:,1]是numpy数组切片得到的数值序列,不是可调用函数,因此触发'numpy.ndarray' object is not callable报错;更换测试时如果在该参数位传入浮点数,就会对应触发'float is not callable'报错,两类报错的诱因完全一致。
代码逻辑问题说明
- 你用
odeint求解常微分方程得到的solD是二维numpy数组,形状为(时间点数量, 状态变量维度),solD[i:,1]只是截取了第二列状态变量从第i个时间点开始的所有存储值,本质是存数值的数组,积分器无法像调用函数一样给它传参、获取任意积分点的计算结果。 - 高斯求积是面向连续解析函数的数值积分方法,不支持直接传入离散数值序列计算积分。
修复方法
根据你的实际需求二选一即可:
- 如果你要积分的是ODE求解得到的离散状态序列,不要使用高斯求积,换成适配离散数据的积分接口:
solD = odeint(SolveMe, ic, t) solT = np.zeros(partition) for i in range(partition): # 先筛选积分区间[0,6]对应的时间点索引 valid_idx = (t >= 0) & (t <= 6) # 用梯形法/辛普森法计算离散序列积分,直接传入数值和对应自变量即可 solT[i] = integrate.trapz(solD[valid_idx, 1], t[valid_idx])
- 如果你确实需要用高斯求积计算连续函数的积分,请把待积分的函数逻辑封装为可调用对象传入,不要传提前计算好的数值/数组:
# 定义待积分的连续函数 def target_func(x): # 替换为你实际的积分函数逻辑 return x ** 2 + 2*x # 正确调用:第一个参数传入函数本身,不要加括号、不要传计算后的数值 solT[i] = integrate.quadrature(target_func, 0, 6)
通用排查规则:所有
X is not callable类报错,都代表你在需要传入函数/可调用对象的位置,传入了普通数值、数组这类不可调用的对象,Python尝试将其作为函数执行传参操作时就会抛出该错误。
内容的提问来源于stack exchange,提问作者Taylor Larrechea
相关产品推荐
相关产品推荐

