Оценить выражение sympy из массива значений
Я экспериментирую с sympy, и я попал в проблему, которую я не могу решить.
Используя scipy, я могу написать выражение и оценить его для массива значений x следующим образом:
import scipy
xvals = scipy.arange(-100,100,0.1)
f = lambda x: x**2
f(xvals)
Используя sympy, я могу написать одно и то же выражение следующим образом:
import sympy
x = sympy.symbols('x')
g = x**2
Я могу оценить это выражение для одного значения, выполнив следующее:
g.evalf(subs={x:10})
Однако я не могу понять, как оценить его для массива значений x, как, например, с scipy. Как мне это сделать?
Ответы
Ответ 1
Прежде всего, на данный момент SymPy не гарантирует поддержку массивов numpy, которые вы хотите в этом случае. Проверьте этот отчет об ошибке http://code.google.com/p/sympy/issues/detail?id=537
Во-вторых, если вы хотите оценить что-то численное для многих значений, то SymPy - не лучший выбор (в конце концов, это символическая библиотека). Используйте numpy и scipy.
Однако, действительная причина для оценки чего-то численно будет заключаться в том, что получение выражения, которое должно быть оценено, было трудным, поэтому вы выводили его в SymPy, а затем оценивали его в NumPy/SciPy/C/Fortran. Чтобы преобразовать выражение в numpy, просто используйте
from sympy.utilities.lambdify import lambdify
func = lambdify(x, big_expression_containing_x,'numpy') # returns a numpy-ready function
numpy_array_of_results = func(numpy_array_of_arguments)
Для получения дополнительной информации проверьте docstring lambdify. Имейте в виду, что lambdify все еще имеет некоторые проблемы и может потребоваться переписать.
И как побочная заметка, если вы хотите много раз оценивать выражения действительно, вы можете использовать модуль codegen/autowrap от sympy, чтобы создать fortran или C-код, который завернут и вызываемый из python.
EDIT: список обновлений способов делать численные значения в SymPy можно найти на wiki https://github.com/sympy/sympy/wiki/Philosophy-of-Numerics-and-Code-Generation-in-SymPy
Ответ 2
В то время как принятый ответ дает понять, что ОП ищет числовую оценку, я все же укажу, что можно также иметь символическую оценку, используя symarray
:
import sympy
xs = sympy.symarray('x', 10)
f = lambda x: x**2
f(xs)
дает
array([x_0**2, x_1**2, x_2**2, x_3**2, x_4**2, x_5**2, x_6**2, x_7**2,
x_8**2, x_9**2], dtype=object)
Обратите внимание, что это также использует массив numpy
внутри, но заполняется с помощью sympy.Expr
essions.
Ответ 3
Или вы можете сделать это через numpy.vectorize.
Я использую x
, g
и xvals
из тела вопроса.
scalar_func = lambda xx: float(g.evalf(subs={x: xx}))
vector_func = numpy.vectorize(scalar_func)
vector_func(xvals) # returns a numpy array [10000.0, 9980.01, 9960.04, ...]
Ответ 4
попробуйте
import sympy
x = sympy.symbols('x')
f = lambda x: x**2
print [f(k) for k in range(4)]
или вы также можете попробовать
g = x**2
print [g.subs(x,k) for k in range(4)]