当前位置: 首页 > 面试题库 >

在Cython中调用点积和线性代数运算?

东门文斌
2023-03-14
问题内容

我正在尝试使用Cython的numpy中提供的点积,矩阵求逆和其他基本线性代数运算。诸如numpy.linalg.inv(求反),numpy.dot(点积),X.t(矩阵/数组的转置)之类的函数。numpy.*从Cython函数进行调用会产生很大的开销,而该函数的其余部分是用Cython编写的,因此我想避免这种情况。

如果我假设用户已numpy安装,是否可以执行以下操作:

#include "numpy/npy_math.h"

作为extern,并调用这些函数?或者直接调用BLAS(或者这些核心操作的numpy调用是什么)?

举个例子,假设您在Cython中有一个函数可以完成很多事情,最后需要进行涉及点积和矩阵逆的计算:

cdef myfunc(...):
  # ... do many things faster than Python could
  # ...
  # compute one value using dot products and inv
  # without using 
  #   import numpy as np 
  #   np.*
  val = gammaln(sum(v)) - sum(gammaln(v)) + dot((v - 1).T, log(x).T)

如何才能做到这一点?如果已经有一个库可以在Cython中实现这些功能,我也可以使用它,但是什么也没找到。即使这些过程没有直接比BLAS进行优化,但没有numpy从Cython调用Python模块的开销仍然可以使整个过程更快。

我想调用的示例函数:

  • 点积(np.dot
  • 矩阵求逆(np.linalg.inv
  • 矩阵乘法
  • 进行转置(相当于x.Tnumpy)
  • γ函数(与scipy.gammaln等效函数一样,应在C语言中可用)

我意识到,正如在numpy邮件列表(https://groups.google.com/forum/?fromgroups=#!topic/cython-
users/XZjMVSIQnTE
)上所说的那样,如果您在大型矩阵上调用这些函数,则毫无意义从Cython执行此操作,因为从numpy调用它只会导致大部分时间花费在numpy调用的优化C代码中。但是,就我而言,我
在小型矩阵上多次调用这些线性代数运算
-在这种情况下,反复从Cython返回numpy再回到Cython所带来的开销将远远超过实际计算BLAS。因此,对于这些简单的操作,我想将所有内容都保持在C
/ Cython级别,而不要使用python。

我不希望通过GSL,因为这会增加另一个依赖关系,并且目前尚不清楚GSL是否得到积极维护。因为我假设代码的用户已经安装了scipy /
numpy,所以我可以放心地假设他们具有所有与这些库一起的关联C代码,因此我只想能够使用该代码并对其进行调用来自Cython。

编辑
:我发现一个库,将BLAS包装在Cython(https://github.com/tokyo/tokyo)中,这很接近,但不是我要找的东西。我想直接调用numpy
/ scipy C函数(我假设用户已经安装了这些函数。)


问题答案:
调用与Scipy捆绑在一起的BLAS是“相当”简单的,这是调用DGEMM计算矩阵乘法的一个示例: https
//gist.github.com/pv/5437087
注意BLAS和LAPACK期望所有数组都是Fortran连续的(模将LDA / b /
C参数),因此, order="F"double[::1,:]其中所需要的正确功能。

通过将LAPACK函数dgesv应用于单位矩阵,可以类似地计算逆。有关签名,请参见此处。所有这些都需要下拉到相当底层的编码,您需要自己分配临时工作数组等。—但是,这些可以封装到您自己的便捷函数中,或者只是tokyo通过用lib_*函数指针替换函数来重用代码通过上述方式从Scipy获得。

如果使用Cython的memoryview语法(double[::1,:]),则转置与x.T通常相同。或者,您可以通过编写自己的函数来计算转置,该函数跨对角线交换数组的元素。Numpy实际上不包含此操作,x.T仅更改数组的步幅并且不移动数据。

可能可以重写该tokyo模块以使用Scipy导出的BLAS / LAPACK并将其捆绑在其中scipy.linalg,以便您可以这样做from scipy.linalg.blas cimport dgemm。如果有人愿意接受拉取请求,则接受该请求。

如您所见,所有这些都归结为传递函数指针。如上所述,Cython实际上确实提供了自己的协议来交换功能指针。例如,考虑from scipy.spatial import qhull; print(qhull.__pyx_capi__)-–这些功能可以通过from scipy.spatial.qhull cimport XXXXCython访问(尽管它们是私有的,所以不要这样做)。

但是,目前scipy.special不提供此C-API。但是,鉴于scipy.special中的接口模块是用Cython编写的,实际上提供它非常简单。

我认为目前尚无任何明智且可移植的方式来访问功能,以进行繁重的工作gamln(尽管您可以窥探UFunc对象,但这不是理智的解决方案:),所以目前可能最好只是从scipy.special中获取源代码的相关部分,并将其与您的项目捆绑在一起,或者使用例如GSL。



 类似资料:
  • 是否可以强制Hazelcast在调用线程的TransactionalMap上运行put()、replace()和delete()方法?我希望XA事务从写到Hazelcast转移到写到MapStore中的数据库,但是Hazelcast正在排队等待在其他线程上运行的更改,因此它们不在相同的事务上下文中。 我已经将它设置为一个直写持久性,但我看到它将TxnSetOperation排队,并在单独的线程上运

  • 问题 你需要执行矩阵和线性代数运算,比如矩阵乘法、寻找行列式、求解线性方程组等等。 解决方案 NumPy 库有一个矩阵对象可以用来解决这个问题。 矩阵类似于3.9小节中数组对象,但是遵循线性代数的计算规则。下面的一个例子展示了矩阵的一些基本特性: >>> import numpy as np >>> m = np.matrix([[1,-2,3],[0,4,5],[7,8,-9]]) >>> m

  • 简单的说,矩阵和数列这两个术语是经常可以替换使用的。更准确地说,矩阵是一个表示线性变换的二维数字数组。矩阵定义下的数学运算是线性代数的主题。 杜勒的魔方 A = 16 3 2 13 5 10 11 8 9 6 7 12 4 15 14 1 提供了几个例子,给出了MATLAB矩

  • 此函数返回两个数组的点积。 对于二维向量,其等效于矩阵乘法。 对于一维数组,它是向量的内积。 对于 N 维数组,它是a的最后一个轴上的和与b的倒数第二个轴的乘积。 输出如下: [[37 40] [85 92]] 要注意点积计算为: [[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]] numpy.vdot() 此函数返回两个向量的点积。 如果第一个参

  • 问题内容: 所以我想通过cython从c调用一些python代码。我设法从c调用cython代码。而且我还可以从cython调用python代码。但是,当我将它们全部加在一起时,会丢失一些东西。 这是我的python代码(): 这是我的cython“ bridge”(): 这是c代码(): 运行此命令时,出现以下异常: 我怀疑缺少的部分: 我还没打电话 我还没有 Cython没有产生任何东西- 不

  • 主要内容:numpy.dot(),numpy.vdot(),numpy.inner(),numpy.matmul(),numpy.linalg.det(),numpy.linalg.solve(),numpy.linalg.inv()NumPy 提供了 numpy.linalg 模块,该模块中包含了一些常用的线性代数计算方法,下面对常用函数做简单介绍: NumPy线性代数函数 函数名称 描述说明 dot 两个数组的点积。 vdot 两个向量的点积。 inner 两个数组的内积。 matmul 两