隐式欧拉法Python实现报错:expected a one-dimensional and numerical function 如何修复?
修复隐式欧拉法实现中的sympy nsolve ValueError错误
错误原因分析
报错expected a one-dimensional and numerical function的核心问题:
- 隐式欧拉法求解二维微分方程组时,必须同时求解由两个迭代方程组成的系统,而非单独求解每个变量。
- 原代码中,每次调用
sp.nsolve时传入单个方程,但指定了两个求解变量(x1,x2),导致nsolve无法处理:多变量求解要求输入的方程组维度与变量数一致(2变量对应2个方程),单方程无法满足这个要求。 - 额外问题:代码中存在命名冲突——定义了
x = sp.Function('x'),但后续fp1的参数名也是x,会覆盖sympy符号,导致逻辑混淆。
修复步骤及完整代码
关键修复点
- 每次迭代构建二维方程组,同时求解下一个时刻的
x1和x2。 - 修正命名冲突,避免sympy符号与函数参数名重复。
- 将nsolve返回的符号结果转换为数值类型,存入结果列表。
修复后的代码
import numpy as np import sympy as sp import matplotlib.pyplot as plt sp.init_printing(use_latex=True) def ImplicitEulerMethod(fp1, fp2, x10, x20, h, t0, tmax): n = int((tmax - t0)/h + 1) x1table = [0.0 for _ in range(n)] x2table = [0.0 for _ in range(n)] x1table[0] = x10 x2table[0] = x20 # 定义求解用的符号变量 x1_sym, x2_sym = sp.symbols('x1_sym x2_sym') for i in range(1, n): t_current = t0 + i * h # 构建隐式欧拉的迭代方程组 eq1 = x1_sym - x1table[i-1] - h * fp1(x1_sym, x2_sym, t_current) eq2 = x2_sym - x2table[i-1] - h * fp2(x1_sym, x2_sym, t_current) # 求解方程组,传入初始猜测值 sol = sp.nsolve((eq1, eq2), (x1_sym, x2_sym), (x1table[i-1], x2table[i-1])) # 将符号结果转为数值,存入列表 x1table[i] = float(sol[0]) x2table[i] = float(sol[1]) Data = [[t0 + i*h, x1table[i], x2table[i]] for i in range(n)] return Data # 修正命名冲突:移除未使用的sp.Function('x'),修改fp参数名避免混淆 def fp1(x1, x2, t): return x1 - x1*x2 def fp2(x1, x2, t): return x1*x2 - x2 # 调用函数并绘图 Data = ImplicitEulerMethod(fp1, fp2, 4, -2, 1, 0, 50) plt.scatter([point[0] for point in Data],[point[1] for point in Data]) plt.xlabel("Time"); plt.ylabel("Love") plt.grid(); plt.show()
代码解释
- 方程组构建:每次迭代生成两个隐式方程,对应
x1和x2的欧拉迭代式,确保变量维度与方程数量匹配。 - nsolve调用:传入方程元组
(eq1, eq2)、变量元组(x1_sym, x2_sym)和初始猜测值,符合多变量求解的要求。 - 结果转换:nsolve返回的是sympy符号对象,通过
float()转换为数值类型,方便后续绘图和计算。 - 命名修正:移除未使用的
sp.Function('x'),将fp函数的参数名改为x1,x2,避免与sympy符号冲突。
内容的提问来源于stack exchange,提问作者daniel12
相关产品推荐
相关产品推荐

