SymPy,如何强制浮点以防止Cython nogil上下文中的错误

时间:2015-11-28 12:58:04

标签: python integer expression cython sympy

我在编译包含SymPy编写的整数的Cython代码时遇到了麻烦。一个例子是:

3.814697265625e-7*x1t*(-300540195*xi1**20 + 2294446650*xi1**18 - 707153400*xi1**17 - 6644311875*xi1**16 + 3102350400*xi1**15 + 9947431000*xi1**14 - 5616324000*xi1**13 - 8551893350*xi1**12 + 5408312000*xi1**11 + 4341581244*xi1**10 - 2974571600*xi1**9 - 1270659390*xi1**8 + 931170240*xi1**7 + 196911000*xi1**6 - 155195040*xi1**5 - 13159575*xi1**4 + 11668800*xi1**3 + 193050*xi1**2 - 257400*xi1 + xi2*(300540195*xi2**19 - 2294446650*xi2**17 + 707153400*xi2**16 + 6644311875*xi2**15 - 3102350400*xi2**14 - 9947431000*xi2**13 + 5616324000*xi2**12 + 8551893350*xi2**11 - 5408312000*xi2**10 - 4341581244*xi2**9 + 2974571600*xi2**8 + 1270659390*xi2**7 - 931170240*xi2**6 - 196911000*xi2**5 + 155195040*xi2**4 + 13159575*xi2**3 - 11668800*xi2**2 - 193050*xi2 + 257400))

给出相同错误的最小化示例是:

cdef double ctest(double x) nogil:
    return 2294446650*x # <-- here is the problem

def test():
    return ctest(x=3.)

错误信息是:

cdef double ctest(double x) nogil:
    return 2294446650*x
                    ^
_stack.pyx:2:21: Coercion from Python not allowed without the GIL

...
cdef double ctest(double x) nogil:
    return 2294446650*x
                    ^
_stack.pyx:2:21: Operation not allowed without gil

...
cdef double ctest(double x) nogil:
    return 2294446650*x
                      ^
_stack.pyx:2:23: Converting to Python object not allowed without gil

如果函数写为:

,则会消除此错误
cdef double ctest(double x) nogil:
    return 2294446650.*x # <-- note the added floating point

问题:

1)有没有人知道如何强制SymPy用浮点写表达式?

2)如果#1不可能,是否可以在Cython中做一些事情以防止出现此错误?

1 个答案:

答案 0 :(得分:1)

evalf()方法会将表达式中的所有数字系数转换为浮点数:

>>> a = (3.814697265625e-7*x1t*(-300540195*xi1**20 + 2294446650*xi1**18 - 707153400*xi1**17 - 6644311875*xi1**16 + 3102350400*xi1**15 + 9947431000*xi1**14 - 5616324000*xi1**13 - 8551893350*xi1**12 + 5408312000*xi1**11 + 4341581244*xi1**10 - 2974571600*xi1**9 - 1270659390*xi1**8 + 931170240*xi1**7 + 196911000*xi1**6 - 155195040*xi1**5 - 13159575*xi1**4 + 11668800*xi1**3 + 193050*xi1**2 - 257400*xi1 + xi2*(300540195*xi2**19 - 2294446650*xi2**17 + 707153400*xi2**16 + 6644311875*xi2**15 - 3102350400*xi2**14 - 9947431000*xi2**13 + 5616324000*xi2**12 + 8551893350*xi2**11 - 5408312000*xi2**10 - 4341581244*xi2**9 + 2974571600*xi2**8 + 1270659390*xi2**7 - 931170240*xi2**6 - 196911000*xi2**5 + 155195040*xi2**4 + 13159575*xi2**3 - 11668800*xi2**2 - 193050*xi2 + 257400)))
>>> a.evalf()
3.814697265625e-7*x1t*(-300540195.0*xi1**20 + 2294446650.0*xi1**18 - 707153400.0*xi1**17 - 6644311875.0*xi1**16 + 3102350400.0*xi1**15 + 9947431000.0*xi1**14 - 5616324000.0*xi1**13 - 8551893350.0*xi1**12 + 5408312000.0*xi1**11 + 4341581244.0*xi1**10 - 2974571600.0*xi1**9 - 1270659390.0*xi1**8 + 931170240.0*xi1**7 + 196911000.0*xi1**6 - 155195040.0*xi1**5 - 13159575.0*xi1**4 + 11668800.0*xi1**3 + 193050.0*xi1**2 - 257400.0*xi1 + xi2*(300540195.0*xi2**19 - 2294446650.0*xi2**17 + 707153400.0*xi2**16 + 6644311875.0*xi2**15 - 3102350400.0*xi2**14 - 9947431000.0*xi2**13 + 5616324000.0*xi2**12 + 8551893350.0*xi2**11 - 5408312000.0*xi2**10 - 4341581244.0*xi2**9 + 2974571600.0*xi2**8 + 1270659390.0*xi2**7 - 931170240.0*xi2**6 - 196911000.0*xi2**5 + 155195040.0*xi2**4 + 13159575.0*xi2**3 - 11668800.0*xi2**2 - 193050.0*xi2 + 257400.0))