加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – Cython中用于循环调用的快速基本线性代数

发布时间:2020-12-20 13:51:27 所属栏目:Python 来源:网络整理
导读:我正在尝试在cython中编写一个函数来进行蒙特卡罗模拟.该函数涉及多个小的线性代数运算,如点积和矩阵求逆.由于该功能被称为成千上万次,所以numpy开销占了很大一部分成本. 三年前有人提出这个问题: calling dot products and linear algebra operations in C
我正在尝试在cython中编写一个函数来进行蒙特卡罗模拟.该函数涉及多个小的线性代数运算,如点积和矩阵求逆.由于该功能被称为成千上万次,所以numpy开销占了很大一部分成本.
三年前有人提出这个问题: calling dot products and linear algebra operations in Cython?
我试图使用两个答案的建议,但第一个scipy.linalg.blas仍然通过一个python包装器,我没有真正得到任何改进.第二种,使用gsl包装器也相当慢,当向量的尺寸非常大时,往往会冻结我的系统.我还发现了Ceygen软件包,看起来非常有前途,但似乎安装文件在最后一次Cython更新中破了.
另一方面,我看到scipy正在使用一个用于lapack的cython包装器,但看起来仍然无法使用( scipy-cython-lapack))
最后,我还可以为这些操作编写自己的C例程,但它似乎有点重新发明轮子.

总结一下:在Cython中有没有新的方法来进行这种操作? (因此我不认为这是重复的)或者您是否找到了更好的方法来处理我尚未见过的这类问题?

强制性代码示例:
(这只是一个例子,当然它仍然可以改进,但只是为了提出这个想法)

cimport numpy as np
 import numpy as np

 cpdef double risk(np.ndarray[double,ndim=2,mode='c'] X,np.ndarray[double,ndim=1,mode='c'] v1,mode='c'] v2):

     cdef np.ndarray[double,mode='c'] tmp,sumX
     cdef double ret

     tmp = np.exp(X)
     sumX = np.tile(np.sum(tmp,1).reshape(-1,1),(1,tmp.shape[0]))
     tmp = tmp / sumX
     ret = np.inner(v1,np.dot(X,v2))
     return ret

谢谢!!

tl; dr:如何在cython中使用线性代数?

解决方法

答案 you link to仍然是从Cython调用BLAS函数的好方法.它实际上不是一个python包装器,仅仅使用Python,因此获取指向该函数的C指针,这可以在初始化时完成.所以你应该得到基本上类似C的速度.我可能是错的,但我认为即将推出的Scipy 0.16版本将提供一个方便的BLAS Cython API,基于这种方法,它不会改变性能方面.

如果你在移植到Cython之后没有经历过反复调用BLAS函数的任何加速,那么在numpy中执行此操作的python开销无关紧要(例如,如果计算本身是最昂贵的部分)或者你做错了什么(不必要的记忆副本等)

我想说这种方法应该比使用GSL更快更容易维护,前提是您使用优化的BLAS(OpenBLAS,ATLAS,MKL等)编译scipy.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读