2012-05-21 20 views
28

Estoy experimentando con Sympy y me he topado con un problema que no puedo resolver.Evaluar la expresión de Sympy de una matriz de valores

Usando scipy Puedo escribir una expresión y evaluarla para una matriz de valores de x como sigue:

import scipy 
xvals = scipy.arange(-100,100,0.1) 
f = lambda x: x**2 
f(xvals) 

Usando sympy I puede escribir la misma expresión como sigue:

import sympy 
x = sympy.symbols('x') 
g = x**2 

que pueda evalúe esta expresión para un solo valor haciendo lo siguiente:

g.evalf(subs={x:10}) 

Sin embargo, puedo No sé cómo evaluarlo para una matriz de valores x, como hice con scipy. ¿Cómo haría esto?

Respuesta

35

En primer lugar, en el momento sympy no garantiza el apoyo para las matrices numpy que es lo que desea en este caso. Marque este informe de error http://code.google.com/p/sympy/issues/detail?id=537

segundo lugar, si se desea evaluar numéricamente para algo muchos valores sympy no es la mejor opción (que es una biblioteca simbólica después de todo). Use numpy y scipy.

Sin embargo, una razón válida para evaluar algo numéricamente será que la derivación de la expresión que se evaluará fue difícil, por lo que se deriva en SymPy y luego se evalúa en NumPy/SciPy/C/Fortran. Para traducir una expresión a numpy simplemente use

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) 

Consulte la documentación de lambdify para obtener más detalles. Tenga en cuenta que lambdify todavía tiene algunos problemas y puede necesitar una reescritura.

Y así como una nota al margen, si se desea evaluar las expresiones realmente muchas veces, se puede utilizar el módulo de codegen/autowrap de sympy con el fin de crear el código FORTRAN o C que se envuelve y se puede llamar desde Python.

EDIT: Una lista de actualizaciones de maneras de hacer numéricos en sympy se puede encontrar en el wiki https://github.com/sympy/sympy/wiki/Philosophy-of-Numerics-and-Code-Generation-in-SymPy

-3

tratar

import sympy 
x = sympy.symbols('x') 
f = lambda x: x**2 
print [f(k) for k in range(4)] 

o también puede probar

g = x**2 
print [g.subs(x,k) for k in range(4)] 
+3

Su primer ejemplo no usa sympy de ninguna manera. El símbolo que define no se accede en el lambda.Además, la pregunta era sobre arreglos numpy y presumiblemente todas las operaciones especiales por elemento soportadas por numpy. Estas no son características presentes en la lista de Python (lo que realmente está usando). – Krastanov

7

Mientras the accepted answer deja claro que el PO estaba buscando numérica evaluación, todavía a señalar que uno también puede tener simbólico evaluación utilizando symarray:

import sympy 
xs = sympy.symarray('x', 10) 
f = lambda x: x**2 
f(xs) 

produce

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) 

Tenga en cuenta que esto también utiliza una matriz numpy internamente, pero una llena con sympy.Expr essions.

+0

Pero symarray no atribuye un valor numérico a cada x_i, entonces, ¿cómo evaluaría la expresión del arange especificado en la pregunta? – fccoelho

+0

@fccoelho Usaría numpy para empezar, o al menos 'lambdify' de la respuesta aceptada. Pero si por alguna razón usted realmente tiene una variedad de expresiones simbólicas, probablemente tendrá que usar una lista de comprensión (o 'for 'loop). Tal vez hay una manera más fácil, pero nunca me molesté con 'symarray's mucho. Mi respuesta es realmente solo aquí como nota al margen –

Cuestiones relacionadas