定义SymPy函数导数的数值求值

2 投票
1 回答
1348 浏览
提问于 2025-04-18 13:05

我该如何在sympy中定义一个函数的导数的数值评估呢?

我有一些函数,可以用样条(splines)来描述这些函数及其导数,这个过程是通过scipy.interpolate来实现的。

我想对这些函数进行一些操作,然后用样条来评估这些操作后的表达式。

我可以使用lambdify将一个sympy函数转换为可以数值评估的样条函数。

但是,我该如何定义一个sympy函数的导数,以便也能将其作为样条进行数值评估呢?

例如:

import sympy as sp
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
from sympy.ultilitis.lambdify import implemented_function, lambdify

r = sp.symbols('r')
B = sp.symbols('B', cls=sp.Function)

B_spline = InterpolatedUnivariateSpline([1,2,3,4],[1,4,9,16])
B_der_spline = InterpolatedUnivariateSpline([1,2,3,4],[2,4,6,8])
B = implemented_function(B, lambda r: B_spline(r))

class A(sp.Function):
    nargs = 2

    @classfunction
    def eval(cls, r, B):
        return r**2*B(r)

 A_eval = lambdify(r, A(r,B))
 A_eval(3)
 >>> 81.0
 A_diff_eval = lambdify(r, sp.diff(A(r,B)))
 A_diff_eval(3)
 >>> NameError: global name 'Derivative' is not defined

1 个回答

2

SymPy不知道怎么对样条函数求导,因为它只从scipy得到了这个函数的数值版本。

另外,这里的A其实可以是一个Python函数,因为你从来没有去计算它。这样做更合理,因为把一个函数当作参数传给SymPy的函数有点奇怪。

所有implemented_function做的事情就是symfunc._imp_ = staticmethod(implementation)(这里symfunc = B,而implementation = lambda r: B_spline(r))。你还需要添加fdiff,这样它才能返回一个新的SymPy函数B_der_spline。大概是这样的:

class B_spline_sym(Function):
    _imp_ = staticmethod(B_spline)

    def fdiff(self, argindex=1):
        return B_der_spline_sym(self.args[0])

class B_der_spline_sym(Function):
    _imp_ = staticmethod(B_der_spline)

def A(r, B):
    return r**2*B(r)

这样就可以得到:

In [87]: B = B_spline_sym

In [88]:  A_eval = lambdify(r, A(r,B))

In [89]:  A_eval(3)
Out[89]: 81.0

In [91]:  A_diff_eval = lambdify(r, sp.diff(A(r,B)))

In [92]:  A_diff_eval(3)
Out[92]: 108.0

撰写回答