- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试使用 Cython 的 numpy 中提供的点积、矩阵求逆和其他基本线性代数运算。 numpy.linalg.inv
(反转)、numpy.dot
(点积)、X.t
(矩阵/数组的转置)等函数。从 Cython 函数调用 numpy.*
的开销很大,而函数的其余部分是用 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,没有从 Cython 调用 numpy
Python 模块的开销仍然会使事情总体上更快。
我想调用的示例函数:
np.dot
)np.linalg.inv
)x.T
)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。
编辑:我找到了一个在 Cython ( https://github.com/tokyo/tokyo ) 中包装 BLAS 的库,它很接近但不是我想要的。我想直接调用 numpy/scipy C 函数(我假设用户已经安装了这些函数。)
最佳答案
调用与 Scipy 捆绑的 BLAS “相当”简单,这是调用 DGEMM 计算矩阵乘法的一个示例:https://gist.github.com/pv/5437087请注意,BLAS 和 LAPACK 期望所有数组都是 Fortran 连续的(以 lda/b/c 参数为模),因此 order="F"
和 double[::1,:]
这是正常运行所必需的。
通过应用 LAPACK 函数 dgesv
可以类似地计算逆。在单位矩阵上。签名见here .所有这些都需要降级到相当低级的编码,您需要自己分配临时工作数组等 --- 但是这些可以封装到您自己的便利函数中,或者只是重用 tokyo
中的代码通过替换 lib_*
通过上述方式从 Scipy 获得函数指针的函数。
如果您使用 Cython 的 memoryview 语法 (double[::1,:]
),则转置是相同的 x.T
照常。或者,您可以通过编写自己的函数来计算转置,该函数在对角线上交换数组的元素。 Numpy 实际上不包含此操作,x.T
只会改变数组的步幅,不会移动数据。
可能会重写 tokyo
模块使用 Scipy 导出的 BLAS/LAPACK 并将其捆绑到 scipy.linalg
, 这样你就可以做 from scipy.linalg.blas cimport dgemm
. Pull requests如果有人想深入了解,就会被接受。
如您所见,这一切都归结为传递函数指针。正如上面提到的,Cython 实际上确实提供了自己的协议(protocol)来交换函数指针。例如,考虑 from scipy.spatial import qhull; print(qhull.__pyx_capi__)
--- 这些功能可以通过 from scipy.spatial.qhull cimport XXXX
访问在 Cython 中(虽然它们是私有(private)的,所以不要这样做)。
但是,目前,scipy.special
不提供此 C-API。然而实际上提供它非常简单,因为 scipy.special 中的接口(interface)模块是用 Cython 编写的。
我认为目前没有任何合理且可移植的方式来访问为 gamln
执行繁重工作的功能。 , (尽管您可以窥探 UFunc 对象,但这不是一个理智的解决方案 :),因此目前最好从 scipy.special 中获取源代码的相关部分并将其与您的项目捆绑在一起,或者使用例如GSL。
关于python - 在 Cython 中调用点积和线性代数运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16114100/
我正在尝试构建不同(但每个同质)类型的可遍历项的多个交叉产品。所需的返回类型是元组的可遍历对象,其类型与输入可遍历对象中的类型相匹配。例如: List(1, 2, 3) cross Seq("a",
import java.util.Scanner; public class BooleanProduct { public static void main(String[] args) {
任务 - 数字的最大 K 积 时间限制:1 内存限制:64 M 给定一个整数序列 N(1 ≤ N ≤ 10 月,| A i | ≤ 2.10 9)和数量 K(1 ≤ K ≤ N)。找出乘积最大的 K
考虑一个大小为 48x16 的 float 矩阵 A 和一个大小为 1x48 的 float vector b。 请建议一种在常见桌面处理器 (i5/i7) 上尽可能快地计算 b×A 的方法。 背景。
假设我有一个 class Rectangle(object): def __init__(self, len
设 A 为 3x3 阶矩阵。判断矩阵A的 boolean 积可以组成多少个不同的矩阵。 这是我想出的: #include int main() { int matri
背景 生成随机权重列表后: sizes = [784,30,10] weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1],sizes[
我正在开发一个 python 项目并使用 numpy。我经常需要通过单位矩阵计算矩阵的克罗内克积。这些是我代码中的一个相当大的瓶颈,所以我想优化它们。我必须服用两种产品。第一个是: np.kron(n
有人可以提供一个例子说明如何使用 uBLAS 产品来乘法吗?或者,如果有更好的 C++ 矩阵库,您可以推荐我也欢迎。这正在变成一个令人头疼的问题。 这是我的代码: vector myVec(scala
我正在尝试开发一个Javascript程序,它会提示用户输入两个整数,然后显示这两个整数的和、乘积、差和商。现在它只显示总和。我实际上不知道乘法、减法和除法命令是否正在执行。这是 jsfiddle 的
如何使用 la4j 计算 vector (叉)积? vector 乘积为 接受两个 vector 并返回 vector 。 但是他们有scalar product , product of all e
在 C++ 中使用 Lapack 让我有点头疼。我发现为 fortran 定义的函数有点古怪,所以我尝试在 C++ 上创建一些函数,以便我更容易阅读正在发生的事情。 无论如何,我没有让矩阵 vecto
是否可以使用 Apple 的 Metal Performance Shaders 执行 Hadamard 产品?我看到可以使用 this 执行普通矩阵乘法,但我特别在寻找逐元素乘法,或者一种构造乘法的
我正在尝试使用 open mp 加速稀疏矩阵 vector 乘积,代码如下: void zAx(double * z, double * data, long * colind, long * row
有没有一种方法可以使用 cv::Mat OpenCV 中的数据结构? 我检查过 the documentation并且没有内置功能。但是我在尝试将标准矩阵乘法表达式 (*) 与 cv::Mat 类型的
我是一名优秀的程序员,十分优秀!