用于循环调用的快速基本线性代数



我正试图在cython中为蒙特卡罗模拟编程一个函数。该函数涉及多个小的线性代数运算,如点积和矩阵逆。当函数被调用数十万次时,numpy开销占成本的很大一部分。三年前有人问了这个问题:在Cython中调用点积和线性代数运算?我尝试使用了两个答案中的建议,但是第一个scipy. linalg2 .blas仍然要经过一个python包装器,而且我并没有真正得到任何改进。第二,使用gsl包装器也相当慢,并且当向量的维度非常大时,往往会冻结我的系统。我还找到了Ceygen包,看起来非常有前途,但似乎安装文件在上次Cython更新中损坏了。另一方面,我看到scipy正在为lapack开发cython包装器,但它看起来仍然不可用(scipy-cython-lapack)。最后,我还可以为这些操作编写自己的C例程,但这似乎是重新发明轮子。

总结一下:在Cython中是否有new方法来完成这类操作?(所以我不认为这是重复的)或者你有更好的方法来处理这类问题,我还没有看到?

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

 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, 
     np.ndarray[double, ndim=1, mode='c'] v2):
     cdef np.ndarray[double, ndim=2, 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: how-to linear algebra in cython?

您链接到的答案仍然是从Cython调用BLAS函数的好方法。它不是真正的python包装器,python只是用来获取指向函数的C指针,这可以在初始化时完成。所以你应该得到c型的速度。我可能是错的,但我认为即将发布的Scipy 0.16版本将提供一个方便的BLAS cythapi,基于这种方法,它不会改变性能方面的事情。

如果你在移植到Cython后没有体验到重复调用BLAS函数的任何速度提升,要么在numpy中执行此操作的python开销无关紧要(例如,如果计算本身是最昂贵的部分),要么你做错了什么(不必要的内存拷贝等)

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

作为einsum补丁的一部分,我编写了该函数c代码的Python模拟。当我在Python中解析字符串时,我使用cython来编写乘积和计算。

pyx在https://github.com/hpaulj/numpy-einsum/blob/master/sop.pyx

您甚至可以通过Python调用来调用compile einsum模块。比较np.dotnp.einsum有许多SO问题,它们更适合不同的计算。

http://docs.cython.org/src/userguide/memoryviews.html

也看看cython memoryviews -你可能能够使用这些,或cython数组,就像你会numpy数组。例如,本文档提到可以使用[None,:]添加维度。这是否意味着你可以通过广播来做常见的numpy外部产品?

相关内容

  • 没有找到相关文章

最新更新