Debugging:scipy中solve_ivp搭配toms748调用出现广播错误如何解决
错误原因
scipy.integrate.solve_ivp传入右端函数的状态参数永远是NumPy数组类型,哪怕是单变量问题,你这里初始条件为[1],所以E函数接收的r是shape=(1,)的ndarray,不是Python原生标量。scipy.optimize.toms748对输入要求严格:要求搜索区间上下界a、b是标量,传入的求根函数返回值也必须是标量,不支持长度为1的数组作为输入/输出。- 你当前代码直接把数组类型的
r用来构造求根函数、计算区间上下界,会导致toms748内部收集的函数值都是长度为1的数组,做差分时出现维度不匹配,触发你看到的广播错误。至于去掉负号能运行属于版本相关的巧合,本质上代码的输入类型不符合toms748的要求,随时可能出错。
解决方案
- 最简单的修复方式是在
E函数开头先把单元素数组r转为Python标量,修改后的E函数如下:
def E(t,r): # 把单元素numpy数组转为标量 r_scalar = r.item() return -toms748(f(r_scalar), r_scalar-1, r_scalar+1)
- 如果是多变量问题,可以对每个状态分量单独处理,保证传给
toms748的所有参数都是标量、求根函数返回值也为标量即可。 - 额外注意:如果你的求根区间可能不存在异号的情况,还需要额外加判断避免
toms748报区间无效的错误,你的示例中f(r)(x)=x-r在[r-1, r+1]区间两端的函数值为-1和1,天然异号,不会有这个问题。
内容的提问来源于stack exchange,提问作者user7896
相关产品推荐
相关产品推荐

