在cython中定义和使用数学函数

时间:2012-08-13 22:03:01

标签: python performance numeric cython symbolic-computation

我是python的新手,并努力让cython加速我的一些计算。我已经尝试了所有可能的方式,但我似乎还没有理解,所以我对此失败了。我有这些文件: 第一个叫Myfunc.pyx

import math
from sympy import Symbol
x = Symbol('x')


wi=10

cdef float MyList(float a,float b):
  return [(xa,ya,wi+a.subs(x,xa)*math.sin(xa)*b.subs(x,xa)*math.exp(1/ya**2)) for xa in range(1,5001,10) for ya in range(-2501,2501,10)]

setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules=[
    Extension("Myfunc",
              ["Myfunc.pyx"],
              libraries=["m"]) # Unix-like specific
]

setup(
  name = "Demos",
  cmdclass = {"build_ext": build_ext},
  ext_modules = ext_modules
)

最后我调用了calc.py的python脚本来获取我想要的列表,名为“MyList1”:

import Myfunc
from sympy import Symbol
import math

x = Symbol('x')


a1=(10*x)**(0.5)
b1=(20*x)**(0.5)
wi=10


MyList1=Myfunc.MyList(a1,b1)
print MyList1

现在澄清一下: 1)x,y在以前的脚本中纯粹用作导出公式的符号。我使用a.subs(x,xa)b.subs(x,xa)(请参阅第一个文件Myfunc.pyx)来删除x并将其替换为xa以最终获得数字而非符号解决方案。 2)我认为在第三个文件(calc.py)的顶部我不应该使用import Myfunc,但我不会得到其他东西。 我认为我应该做什么:运行setup.py,然后因为创建了2个新文件Myfunc.c和Myfunc.so我只运行calc.py文件,据说我将拥有我的数字在纯蟒蛇中更快。 必须做什么:我终于不知道...... 我想要的是什么: exp()a.subs(x,xa)以及{{1}我认为正在减慢我的计算速度。我尝试将这段代码从纯python转换为“cython”(我认为转换不是一个好词来形容这个)。官方网站上的教程对我来说有点不可思议,所以我总是无法实现这一目标。请原谅我的英语,因为我的气垫船上装满了鳗鱼

2 个答案:

答案 0 :(得分:4)

不可能将sympy与cython结合起来。 Cython通过将cdef类和声明的变量转换为C并对其进行编译来加速python。 sympy.Symbol或任何其他的sympy函数没有C ++等价物,因此无法编译成C语言,因此没有加速。

更具体地说。当您使用a声明float a时,它是C double而不是sympy类型。因此它没有.subs方法。 (它不能有)

如果我理解你正在努力numpy是一个比cython更好的解决方案。基本上numpy.arrays是C数据类型。当您使用它们执行计算时,它以C ++速度发生。记录了如何使用numpy with sympy。如果由于任何原因你无法实现你想要的numpy(不太可能)numpy仍然适用于cython。

答案 1 :(得分:4)

有许多方法可以从SymPy中的符号表达开始,最后得到快速数字代码。

  • 您可以查看SymPy的代码生成

  • 您可以查看lamdify函数