Definir evaluación numérica de una derivada de una función sympy.

¿Cómo puedo definir la evaluación numérica de una derivada de una función en sympy? Tengo algunas funciones que puedo describir con splines para la función y es derivativo usando scipy.interpolate. Quiero manipular algunas expresiones con esta función y luego evaluar las expresiones con las splines.

Puedo usar lambdify para hacer que una función sympy se evalúe numéricamente como una spline. Pero, ¿cómo puedo definir la derivada de una función sympy para evaluar numéricamente como una spline?

P.ej

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 

SymPy no sabe cómo tomar la derivada de la función spline, ya que solo tiene la versión numérica de Scipy.

Además, A aquí podría ser simplemente una función de Python, ya que nunca se evalúa. Eso también tiene más sentido porque pasar una función como argumento a una función SymPy es un poco extraño.

Todo lo que hace la función implemented_function es symfunc._imp_ = staticmethod(implementation) (aquí symfunc = B e implementation = lambda r: B_spline(r) ). También deberá agregar fdiff para que devuelva una nueva función B_der_spline para B_der_spline . Algo como

 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) 

Dando

 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