函数作为类属性存储与使用问题:无法保存求导生成的函数
解决Rosenbrock类中存储SymPy求导生成的Lambda函数问题
我来帮你搞定这个棘手的问题!你遇到的核心卡点应该是直接用SymPy处理lambda函数时没做好符号转换,导致无法把求导后的函数绑定到类实例上。下面是完整的修正代码+详细解释,一步到位解决问题:
完整可运行代码
import sympy as sp class rosenbrock: def __init__(self, a, b): # 先定义SymPy需要的符号变量,这是求导的基础 self.x0, self.x1 = sp.symbols('x0 x1') # 用SymPy表达式形式定义原函数,同时生成可直接调用的数值计算函数 self.f_ros_expr = (a - self.x0)**2 + b*(self.x1 - self.x0**2)**2 self.f_ros = sp.lambdify((self.x0, self.x1), self.f_ros_expr, 'numpy') # 调用内部方法生成导数函数 self._write_derivatives() def _write_derivatives(self): # 分别对x0和x1求偏导(符号形式) df_dx0 = sp.diff(self.f_ros_expr, self.x0) df_dx1 = sp.diff(self.f_ros_expr, self.x1) # 把符号导数转换成可调用的lambda函数,绑定到实例属性 self.df_ros_x0 = sp.lambdify((self.x0, self.x1), df_dx0, 'numpy') self.df_ros_x1 = sp.lambdify((self.x0, self.x1), df_dx1, 'numpy') # 可选:把两个偏导打包成一个返回元组的函数 self.df_ros = lambda x0, x1: (self.df_ros_x0(x0, x1), self.df_ros_x1(x0, x1))
关键思路解析
你之前的代码大概率是直接尝试对lambda函数求导,但SymPy只能处理符号表达式,没法直接解析lambda。所以我们换了个思路:
- 先定义SymPy的符号变量
x0和x1,作为求导的操作对象 - 用符号变量写出原函数的表达式形式,而不是直接写lambda
- 对符号表达式求导后,用
sympy.lambdify把符号导数转换成可以做数值计算的lambda函数,再赋值给类的实例属性,这样就能正常存储和调用了
使用示例
# 用经典Rosenbrock参数实例化(a=1, b=100) ros = rosenbrock(1, 100) # 调用原函数(最小值点处值为0) print(ros.f_ros(1, 1)) # 输出: 0 # 调用单个偏导函数 print(ros.df_ros_x0(1, 1)) # 输出: 0 print(ros.df_ros_x1(1, 1)) # 输出: 0 # 调用打包后的偏导函数,返回(对x0的偏导, 对x1的偏导) print(ros.df_ros(1, 1)) # 输出: (0, 0)
内容的提问来源于stack exchange,提问作者Greedo
相关产品推荐
相关产品推荐

