Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython中平方范数的快速计算_Python_Python 3.x_Performance_Numpy_Cython - Fatal编程技术网

Python Cython中平方范数的快速计算

Python Cython中平方范数的快速计算,python,python-3.x,performance,numpy,cython,Python,Python 3.x,Performance,Numpy,Cython,我想计算平方范数,它可以写成 W是一个矩阵,有V行。u是一个向量。我有两个numpy对象W和u import numpy as np import numpy.random as npr V = 10 W = npr.normal(size=(V, 3)) u = npr.normal(size=(1,3)) 如果我逐行计算,我可以这样做: res = np.zeros(V) for v in range(V): res[v] = (W[v] - u).dot((W[v] - u).

我想计算平方范数,它可以写成

W是一个矩阵,有V行。u是一个向量。我有两个numpy对象W和u

import numpy as np
import numpy.random as npr
V = 10
W = npr.normal(size=(V, 3))
u = npr.normal(size=(1,3))
如果我逐行计算,我可以这样做:

res = np.zeros(V)
for v in range(V):
    res[v] = (W[v] - u).dot((W[v] - u).transpose())
但一旦V变大(比如5000),它可能会变慢,我需要一次又一次地重新计算它。 所以我尝试了矩阵乘法,但没有成功,因为它不是逐行乘法

((W - u).transpose()).dot(W - u)
如何快速计算Numpy中的平方范数

我计划使用Cython,所以循环中的逐行乘法能比Numpy快吗?我了解到Cython有,但如果我在内部使用Numpy对象,Cython似乎无法并行化
for loop
(11月20日添加:可能我无法在
prange
中使用Python对象,但我可以使用Numpy对象)。

方法#1 你可以在NumPy中使用快速BLAS,而不需要任何循环,就像这样-

res = (W**2).sum(1) + (u**2).sum(1) -2*W.dot(u.ravel())
d = W -u
res = np.einsum('ij,ij->i',d,d)
对于
u
-

res = np.einsum('ij,ij->i',W,W) + np.inner(u,u).ravel() -2*W.dot(u.ravel())
方法说明

使用
(W[v]-u).dot((W[v]-u)
在每次迭代中,我们都在做内部点积。因为,我们对
W
的所有行都这样做,这在利用广播时转换为
((W-u)**2).sum(1)

现在,

因此,

sum_k((Xik-Yjk)**2) = sum_k(Xik**2) + sum_k(Yjk**2) - 2*sum_k(Xik*Yjk)
RHS上的最后一个术语基本上是矩阵乘法,我们正在利用
np.dot

进近#2 或者,使用更多的
np.einsum
,情况会是这样-

res = (W**2).sum(1) + (u**2).sum(1) -2*W.dot(u.ravel())
d = W -u
res = np.einsum('ij,ij->i',d,d)

如果我在Cython中使用np.dot(),它会比在纯Python中使用它慢吗?@user2978524如果你能在NumPy这里使用
np.dot
,我想你不会看到它对Cython有任何好处。我明白了,你是对的。你能告诉我你是如何得出第一个答案的(带np.dot的那个)?我对numpy总是很难理解,我不知道为什么你的答案会给出我想要的,这让我在将来也会陷入同样的问题。你知道有用的参考资料吗?@user2978524补充道。你也可以使用
np.linalg.norm(W-u)
您是否在循环变量中添加了
cdef int v
类型?如果没有,可能会导致速度减慢。但您在cython中的并行化是正确的;如果您在循环中接触任何python对象,则无法使用像
prange
这样的OpenMP函数。无论如何,看起来您已经获得了一个更智能的python解决方案!@CodeSur在上面的geon中,我只展示了Python版本以便于复制,但我将在Cython中适当地定义变量!