Cómo lambdificar una expresión SymPy que contiene la función erf para usar con NumPy

Me gustaría lambdificar una expresión simbólica que contiene la función erf con SymPy. Esto se puede hacer para los argumentos escalares de la siguiente manera:

log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2)) F = sym.lambdify([x, mu, sigma], log_normal) F(1.0, 0.0, 1.0) 

Me gustaría vectorizar lo anterior. Normalmente haría lo siguiente …

 log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2)) vector_F = sym.lambdify([x, mu, sigma], log_normal, modules='numpy') vector_F(1.0, 0.0, 1.0) 

Sin embargo, lo anterior plantea un NameError

 --------------------------------------------------------------------------- NameError Traceback (most recent call last)  in () ----> 1 vector_F(1.0, 0.0, 1.0) /Users/drpugh/anaconda/lib/python2.7/site-packages/numpy/__init__.pyc in (x, mu, sigma) NameError: global name 'erf' is not defined 

¿Es esto un error, o me falta algo trivial?

Le dijiste a lambdify que solo tenía numpy como un módulo para jugar; Dale una fuente para erf . Iow, tienes

 >>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy']) >>> vector_F(1.0, 0.0, 1.0) Traceback (most recent call last): File "", line 1, in  vector_F(1.0, 0.0, 1.0) File "", line 1, in  NameError: global name 'erf' is not defined 

pero

 >>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', 'sympy']) >>> vector_F(1.0, 0.0, 1.0) 0.500000000000000 

o

 >>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', 'math']) >>> vector_F(1.0, 0.0, 1.0) 0.5 

o el que prefiera, dependiendo de si desea un sympy.core.numbers.Float o un float .

A partir de SymPy 1.3, scipy se admite automáticamente en lambdify. Si omite el argumento de los modules , agrega scipy automáticamente. O puede usar modules=['numpy', 'scipy'] .

 >>> log_normal = 0.5 + 0.5 * sym.erf((sym.log(x) - mu) / sym.sqrt(2 * sigma**2)) >>> vector_F = sym.lambdify([x, mu, sigma], log_normal) >>> vector_F(1.0, 0.0, 1.0) 0.5 

En general, para admitir una función que lambdify no conoce, agréguela como un diccionario al argumento de los modules . El argumento de los modules determina el espacio de nombres con el que se ejecuta la función lambdified. Consulte la documentación de lambdify . Por ejemplo, para soportar erf en SymPy <1.3:

 >>> import scipy.special >>> vector_F = sym.lambdify([x, mu, sigma], log_normal, modules=['numpy', {'erf': scipy.special.erf}]) >>> vector_F(1.0, 0.0, 1.0) 0.5