pythonsympylambdify

SymPy lambdify throws NameError due to Subs in derivative expression


I want to use sympy.lambdify to compute the derivative of various formulas and evaluate them numerically. Here’s a minimal example:

import sympy as sp
from sympy.utilities.lambdify import lambdify

formula = "arcsin(a**x)"
formula = sp.sympify(formula.strip(), evaluate=False)
d_formula = sp.diff(formula, "x", simplify=False)
grad_func = lambdify(["a","x"], d_formula, modules='numpy')
res = grad_func(0.5,2)

However, when I run this, I get the following error:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[72], line 5
      3 d_formula = sp.diff(formula, "x", simplify=False)
      4 grad_func = lambdify(["a","x"], d_formula, modules='numpy')
----> 5 grad_func(0.5,2)

File <lambdifygenerated-938>:4, in _lambdifygenerated(a, x)
      1 def _lambdifygenerated(a, x):
      2     return (  # Not supported in Python with numpy:
      3   # Derivative
----> 4 a**x*log(a)*Subs(Derivative(arcsin(_xi_1), _xi_1), xi_1_7206919208181693502, a**x))

NameError: name 'Subs' is not defined

I use .doit() to force evaluation of Subs, but it doesn’t seem to work. I also change the differentiation options like simplify=False, but it has no effect.

Why does sympy.diff() introduce a Subs expression here and how to avoid it? How can I transform this derivative into a form that lambdify can handle without errors?

Any insights or alternative approaches would be greatly appreciated!


Solution

  • Using asin and subs:

    In [82]: a,x = sp.symbols('a x')
    
    In [83]: formula=sp.asin(a**x); formula
    Out[83]: 
    asin(a**x)
    
    In [84]: d_formula=sp.diff(formula,x, simplify=False); d_formula
    Out[84]: 
    a**x*log(a)/sqrt(1 - a**(2*x))
    
    In [85]: d_formula.subs({a:.5, x:2})
    Out[85]: 
    -0.178969832451953
    

    Now we can use lambdify:

    In [86]: foo = sp.lambdify((a,x),d_formula)
    
    In [87]: help(foo)
    Help on function _lambdifygenerated:
    
    _lambdifygenerated(a, x)
        Created with lambdify. Signature:
    
        func(a, x)
    
        Expression:
    
        a**x*log(a)/sqrt(1 - a**(2*x))
    
        Source code:
    
        def _lambdifygenerated(a, x):
            return a**x*log(a)/sqrt(1 - a**(2*x))
    
    In [88]: foo(.5,2)
    Out[88]: np.float64(-0.1789698324519529)