首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个巨大的稠密矩阵的乘法Hadamard--乘以一个稀疏矩阵

两个巨大的稠密矩阵的乘法Hadamard--乘以一个稀疏矩阵
EN

Stack Overflow用户
提问于 2021-01-20 11:36:06
回答 1查看 96关注 0票数 4

我有两个密集矩阵AB,每个矩阵的大小都是3e5x100。另一个大小为3e5x3e5的稀疏二进制矩阵C。我想要找到以下数量:C ∘ (AB'),其中是Hadamard乘积(即元素智慧),B'B的转置。显式计算AB'会占用大量内存(~500 of )。由于最终结果不需要整个AB',因此只计算乘法A_iB_j'就足够了,其中C_ij != 0,其中A_i是矩阵A的列iC_ij是矩阵C的位置(i,j)处的元素。建议的方法类似于下面的算法:

代码语言:javascript
复制
result = numpy.initalize_sparse_matrix(shape = C.shape)
while True:
 (i,j) = C_ij.pop_nonzero_index() #prototype function returns the nonzero index and then points to the next nonzero index
 if (i,j) is empty:
   break
 result(i,j) = A_iB_j'

然而,这个算法需要花费太多的时间。有没有什么办法可以使用LAPACK/BLAS算法来改进它?我用Python语言编写代码,所以我认为对于LAPACK/BLAS来说,numpy可以成为更人性化的包装器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-20 14:16:23

假设C存储为scipy.sparse矩阵,则可以使用以下公式执行此计算:

代码语言:javascript
复制
C = C.tocoo()
result_data = C.data * (A[C.row] * B[C.col]).sum(1)
result = sparse.coo_matrix((result_data, (row, col)), shape=C.shape)

在这里,我们展示了对于一些较小的输入,结果与朴素算法相匹配:

代码语言:javascript
复制
import numpy as np
from scipy import sparse

N = 300
M = 10

def make_C(N, nnz=1000):
  data = np.random.rand(nnz)
  row = np.random.randint(0, N, nnz)
  col = np.random.randint(0, N, nnz)
  return sparse.coo_matrix((data, (row, col)), shape=(N, N))


A = np.random.rand(N, M)
B = np.random.rand(N, M)
C = make_C(N)

def f_naive(C, A, B):
  return C.multiply(np.dot(A, B.T))

def f_efficient(C, A, B):
  C = C.tocoo()
  result_data = C.data * (A[C.row] * B[C.col]).sum(1)
  return sparse.coo_matrix((result_data, (C.row, C.col)), shape=C.shape)

np.allclose(
    f_naive(C, A, B).toarray(),
    f_efficient(C, A, B).toarray()
)
# True

在这里,我们看到它适用于完整的输入大小:

代码语言:javascript
复制
N = 300000
M = 100

A = np.random.rand(N, M)
B = np.random.rand(N, M)
C = make_C(N)

out = f_efficient(C, A, B)

print(out.shape)
# (300000, 300000)

print(out.nnz)
# 1000
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65802720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档