2015-04-22 25 views
2

Я выполняю символическую математику с sympy, а затем генерирую функцию лямбда-функции Python с помощью eval и утилиты symfix's lambdastr. Вот упрощенный пример того, что я имею в виду:Создание вызываемого с numexpr

import sympy 
import numpy as np 
from sympy.utilities.lambdify import lambdastr 

# simple example expression (my use-case is more complex) 
expr = sympy.S('b*sqrt(a) - a**2') 
a, b = sorted(expr.free_symbols, key=lambda s: s.name) 

func = eval(lambdastr((a,b), expr), dict(sqrt=np.sqrt)) 

# call func on some numpy arrays 
foo, bar = np.random.random((2, 4)) 
print func(foo, bar) 

Это работает, но мне не нравится использование eval и SymPy не обязательно генерировать вычислительно эффективный код. Вместо этого, я хотел бы использовать numexpr, который, кажется, идеально подходит для этого сценария использования:

import numexpr 
print numexpr.evaluate(str(expr), local_dict=dict(a=foo, b=bar)) 

Единственная проблема заключается в том, что я хотел бы, чтобы сгенерировать вызываемым (как func лямбда), вместо вызова numexpr.evaluate каждый раз. Это возможно?

+0

я не уверен, я следую с аском здесь ... Но вы не можете просто обернуть 'numexpr.evaluate' позвонить в функцию лямбда? – mgilson

+0

Я полагаю, что мог бы, но это повлияет на стоимость повторного анализа строки выражения при каждой оценке? – perimosocordiae

+0

Можете ли вы ['lambdify'] (http://docs.sympy.org/latest/modules/utilities/lambdify.html)? – miradulo

ответ

1

Вы можете использовать модуль lambdify, который позволяет преобразовывать выражения SymPy в лямбда-функции для эффективного расчета. Это хорошо в его способности вернуть функцию с присоединенной реализацией.

Lambdify ИНГИ своей собственной функции может выглядеть следующим образом:

func = lambdify((a,b),expr, dict(sqrt=np.sqrt)) 
+0

Отлично работает, хотя вам не нужны парсеры вокруг 'expr'. Благодаря! – perimosocordiae