Sympy lambdify报错:ufunc循环不支持无log方法的Float类型
牛顿法方程组求解中lambdify生成函数的log未定义错误
问题背景
我在用SymPy配合牛顿法编写方程组求解程序,流程是先求解两个方程的所有偏导数,再通过lambdify将导数转换为可调用的数值函数,核心代码如下:
x = sp.Symbol('x') y = sp.Symbol('y') temp1 = sp.diff(eq_1(x,y,T),x) eq_1_d1 = sp.lambdify([x,y,sp.Symbol('T')],temp1)
问题现象
首次计算某点的导数完全正常,但循环运行一轮后,第二次执行会触发NameError: name 'log' is not defined错误。循环部分代码如下:
solution_list = [] solution_list.append([np.array([x_0]),np.array([y_0])]) x = solution_list[-1][0][0] y = solution_list[-1][1][0] eq_arr = np.array([[eq_1(x,y,T)],[eq_2(x,y,T)]]) while (eq_arr[0] > k and eq_arr[1] > k) or (eq_arr[0] < -k and eq_arr[1] < -k): x = solution_list[-1][0][0] y = solution_list[-1][1][0] temp_vec = np.array([[x],[y]]) J = np.array([[eq_1_d1(x,y,T),eq_1_d2(x,y,T)],[eq_2_d1(x,y,T),eq_2_d2(x,y,T)]]) J_inverse = np.linalg.inv(J) temp_vec2 = temp_vec - J_inverse @ eq_arr solution_list.append(temp_vec2)
排查细节
- 已通过打印确认,x、y能从
solution_list中获取正确数值 - 将报错行中的
log替换为sp.log可得到正确浮点数,但无法理解lambdify生成的函数为何会出现该问题 - 报错的导数生成函数代码如下:
def _lambdifygenerated(x, y, T): return -1662.8*log(-0.03049 + (x - 0.03049)/y)/(x - y)**2 + 1662.8/(x - 0.03049)**2 + 1662.8/(y*(-0.03049 + (x - 0.03049)/y)*(x - y)) + 5.537*y/x**2 + 11.074/x**3
原因及解决办法
问题根源
lambdify默认会将SymPy的log直接转换为裸的log符号,但当前运行环境中未导入math.log或numpy.log,导致第二次运行时找不到该名称(首次运行正常可能是环境中存在临时的log定义,比如之前使用SymPy时残留的)。
修复方案
- 指定lambdify的modules参数(推荐):
生成函数时明确指定使用NumPy或math库,生成的代码会自动替换为np.log或math.log:
# 适合数组运算的NumPy版本 eq_1_d1 = sp.lambdify([x,y,sp.Symbol('T')], temp1, modules=['numpy']) # 适合单个数值计算的math版本 eq_1_d1 = sp.lambdify([x,y,sp.Symbol('T')], temp1, modules=['math'])
- 手动导入log:
在代码开头添加from math import log或import numpy as np; log = np.log,但这种方式易引发命名冲突,不如第一种严谨。
内容的提问来源于stack exchange,提问作者jaceks123
相关产品推荐
相关产品推荐

