numpy:当某些向量元素等于零时,矩阵向量乘法不会跳过计算吗?

伯克大学

我最近一直在从事一个项目,其中大部分时间都花在乘以一个密集矩阵A和一个稀疏向量上v(请参见此处)。在减少计算量的尝试中,我注意到的运行时间A.dot(v)不受的零项数量影响v

为了解释为什么在这种情况下我希望运行时有所改善,让result = A.dot.vso result[j] = sum_i(A[i,j]*v[j]) for j = 1...v.shape[0]如果那样的v[j] = 0话显然result[j] = 0不管价值A[::,j]因此,在这种情况下,我希望仅设置numpy,result[j] = 0但似乎仍然可以继续进行计算sum_i(A[i,j]*v[j])

我继续编写了一个简短的示例脚本,以在下面确认此行为。

import time
import numpy as np

np.__config__.show() #make sure BLAS/LAPACK is being used
np.random.seed(seed = 0)
n_rows, n_cols = 1e5, 1e3

#initialize matrix and vector
A = np.random.rand(n_rows, n_cols)
u = np.random.rand(n_cols)
u = np.require(u, dtype=A.dtype, requirements = ['C'])

#time
start_time = time.time()
A.dot(u)
print "time with %d non-zero entries: %1.5f seconds" % (sum(u==0.0), (time.time() - start_time))

#set all but one entry of u to zero
v = u
set_to_zero = np.random.choice(np.array(range(0, u.shape[0])), size = (u.shape[0]-2), replace=False)
v[set_to_zero] = 0.0

start_time = time.time()
A.dot(v)
print "time with %d non-zero entries: %1.5f seconds" % (sum(v==0.0), (time.time() - start_time))


#what I would really expect it to take
non_zero_index = np.squeeze(v != 0.0)
A_effective = A[::,non_zero_index]
v_effective = v[non_zero_index]


start_time = time.time()
A_effective.dot(v_effective)
print "expected time with %d non-zero entries: %1.5f seconds" % (sum(v==0.0), (time.time() - start_time))

运行此命令,无论使用密集矩阵u还是稀疏矩阵,矩阵向量乘法的运行时间都相同v

time with 0 non-zero entries: 0.04279 seconds
time with 999 non-zero entries: 0.04050 seconds
expected time with 999 non-zero entries: 0.00466 seconds

我想知道这是否是设计使然?还是我在运行矩阵向量乘法的过程中缺少某些东西。就像进行健全性检查一样:我确保已将numpy其链接到本机上的BLAS库,并且两个阵列均已链接C_CONTIGUOUS(因为numpy调用BLAS显然需要这样做)。

hpaulj

尝试一个简单的函数怎么样?

def dot2(A,v):
    ind = np.where(v)[0]
    return np.dot(A[:,ind],v[ind])

In [352]: A=np.ones((100,100))

In [360]: timeit v=np.zeros((100,));v[::60]=1;dot2(A,v)
10000 loops, best of 3: 35.4 us per loop

In [362]: timeit v=np.zeros((100,));v[::40]=1;dot2(A,v)
10000 loops, best of 3: 40.1 us per loop

In [364]: timeit v=np.zeros((100,));v[::20]=1;dot2(A,v)
10000 loops, best of 3: 46.5 us per loop

In [365]: timeit v=np.zeros((100,));v[::60]=1;np.dot(A,v)
10000 loops, best of 3: 29.2 us per loop

In [366]: timeit v=np.zeros((100,));v[::20]=1;np.dot(A,v)
10000 loops, best of 3: 28.7 us per loop

完全迭代的Python实现将是:

def dotit(A,v, test=False):
    n,m = A.shape  
    res = np.zeros(n)
    if test:
        for i in range(n):
            for j in range(m):
                if v[j]:
                    res[i] += A[i,j]*v[j]
    else:
        for i in range(n):
            for j in range(m):
                res[i] += A[i,j]*v[j]
    return res

显然,这不会像编译的那样快dot,但是我希望测试的相对优势仍然适用。为了进一步测试,您可以在中实现它cython

注意,v[j]测试在迭代的深处进行。

对于稀疏v(100个元素中的3个),测试可以节省时间:

In [374]: timeit dotit(A,v,True)
100 loops, best of 3: 3.81 ms per loop

In [375]: timeit dotit(A,v,False)
10 loops, best of 3: 21.1 ms per loop

但是如果v密集的话会花费时间

In [376]: timeit dotit(A,np.arange(100),False)
10 loops, best of 3: 22.7 ms per loop

In [377]: timeit dotit(A,np.arange(100),True)
10 loops, best of 3: 25.6 ms per loop

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当nextInt等于零时,如何终止程序?

来自分类Dev

numpy:向量x矩阵x向量乘法

来自分类Dev

DBA_HIST_SQLSTAT:执行次数等于零时所经过的时间不为零

来自分类Dev

矩阵和向量的Fortran元素明智乘法

来自分类Dev

当option.amount等于零时,获取数组中对象的名称

来自分类Dev

对于Android系统,当uid等于零时是什么意思

来自分类Dev

向量-向量乘法以创建矩阵

来自分类Dev

“向量化”矩阵乘法

来自分类Dev

矩阵向量乘法

来自分类Dev

使用向量的矩阵乘法

来自分类Dev

矩阵乘法的向量化

来自分类Dev

向量矩阵乘法的标量向量乘法

来自分类Dev

数组和向量的numpy逐元素乘法

来自分类Dev

Matlab读取向量的最后一项不等于零

来自分类Dev

SQL CASE,当值等于零时,从具有相同值的另一行返回值

来自分类Dev

当文件中的所有列不等于零时,将其与参考文件中的参考列进行比较

来自分类Dev

PHP登录仅在mysqli_num_rows等于零时起作用,否则不起作用。

来自分类Dev

core.matrix中矩阵和向量的元素明智乘法

来自分类Dev

TensorFlow中矩阵和向量的高效逐元素乘法

来自分类Dev

core.matrix中矩阵和向量的元素明智乘法

来自分类Dev

如何快速地将大矩阵与向量进行元素乘法?

来自分类Dev

向量在计算时改变为矩阵

来自分类Dev

Python平行矩阵向量乘法

来自分类Dev

Java 8矩阵*向量乘法

来自分类Dev

矩阵向量乘法CCS c ++

来自分类Dev

向量乘法矩阵-R与Matlab

来自分类Dev

错误:使用矩阵乘以向量乘法时需要数字/复矩阵/向量参数

来自分类Dev

在等于零的矩阵中设置一些值

来自分类Dev

向量之一为全零时的余弦相似度

Related 相关文章

热门标签

归档