I am just learning how to use sympy for symbolic variable manipulations. I now have an expression that I'd like to evaluate many times in an optimization scheme, so I'd like for it to run very quickly. The sympy documentation on Numeric Computation describes a few methods for doing this: subs/evalf; lambdify; lambdify-numpy; ufuncify; Theano.
So far, I've gotten lambdify to work, but it still doesn't seem fast enough for me. Reading up on this further, it looks like lambdify operates at python speed, whereas ufuncify could be recompiling the code into C code under the hood, so I am now looking into this option.
So far, I have been able to ufuncify my expression, but it throws an error whenever I pass a complex input as an argument.
I modified the ufuncify example from this link to create my MWE. When I run this:
import sympy as sp
from sympy.utilities.autowrap import ufuncify
import numpy as np
# Create an example expression
a, b, c = sp.symbols('a, b, c')
expr = a + b*c
# Create a binary (compiled) function that broadcasts it's arguments
func = ufuncify((a, b, c), expr)
b = func(np.arange(5), 2.0+1j, 3.0)
print(b)
I get this error: TypeError: ufunc 'wrapper_module_0' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
If I change the code to just remove the imaginary part of the second argument, it runs fine:
import sympy as sp
from sympy.utilities.autowrap import ufuncify
import numpy as np
# Create an example expression
a, b, c = sp.symbols('a, b, c')
expr = a + b*c
# Create a binary (compiled) function that broadcasts it's arguments
func = ufuncify((a, b, c), expr)
b = func(np.arange(5), 2.0, 3.0)
print(b)
returns: [ 6. 7. 8. 9. 10.]
Ideally I would like to use cython or f2py as the backend, since I expect them to be the fastest... but I get similar errors:
func = ufuncify((a, b, c), expr, backend='cython')
returns TypeError: Argument 'b_5226316' has incorrect type (expected numpy.ndarray, got complex)