【问题标题】:Diagonal Block Multiplication via Tensor Multiplication in Numpy在 Numpy 中通过张量乘法进行对角块乘法
【发布时间】:2017-01-14 01:37:57
【问题描述】:

是否有一个表达式(可能使用np.tensordot)最能表达地捕获对角块的块矩阵和相应大小的向量之间的稀疏矩阵向量乘法?

我有一个工作实现,可以执行我想要的确切操作,但我使用了两个 python 循环(见下文)而不是一个合适的 numpy 命令,它可能存在。

例如:

import numpy as np

outer_size = 2
inner_size = 5
shape = (outer_size, outer_size, inner_size)
diag_block = np.arange(np.prod(shape)).reshape(shape)
true_diag = np.bmat([[np.diag(diag_block[i,j]) for j in range(shape[1])] for i in range(shape[0])]).A
x = np.arange(shape[1] * shape[2])

def sparse_prod(diags, x):
    outer_size = diags.shape[0]
    return np.hstack(sum(diags[i] * x.reshape(outer_size, -1)) for i in range(outer_size))

print(true_diag.dot(x))
print(sparse_prod(diag_block, x))

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    方法#1:你可以使用np.einsum -

    np.einsum('ijk,jk->ik', diag_block, x.reshape(outer_size, -1)).ravel()
    

    基本上,我们保持最后一个轴在两个输入之间对齐,并分别对第二个和第一个轴进行求和。


    方法#2:根据输入数组的形状,您可能希望在循环中使用np.dot/np.tensordot,如this post 中详细讨论的那样。

    这是一种带有循环的方法 -

    m,_,n = diag_block.shape
    x2D = x.reshape(outer_size, -1)
    out = np.empty((m,n))
    for i in range(n):
        out[:,i] = np.dot(diag_block[...,i], x2D[:,i])
    out.shape = out.size  # Flatten
    

    【讨论】:

    • 对,我同意 einsum 会起作用,但是,正如您的链接所指出的那样,它比替代方案慢得多。 Tensordot 是等价的,但不需要爱因斯坦求和下标语法知识,也不需要下标编译。您是否介意添加等效的张量点以确保完整性(我无法弄清楚)。
    • 如果你写了你想dot一个(n,m,k)数组和一个(m,k)一个,einsum符号是微不足道的。您的block_diagonal 框架在某种程度上掩盖了这一点。你为什么关心subscript compilation?这是在 C 代码中完成的。
    • 即使我将大小增加到 20 和 50,einsum 也会获胜。即使不包括 bmat 构造步骤,true_diag.dot(x) 也很慢。这一步要慢得多。 dot 在 1000x1000 空间上运行,einsum 在 20x20x50 上运行。
    • @hpaulj 你在跟我说话吗?还是给答案的作者?我不太喜欢 einsum,因为它并不广为人知,它的文档基本上说“从示例中概括该函数的行为”。另一方面,tensordot 在文档中有一个正式的、精确的定义,即沿选定轴的张量扩展/收缩。此外,您混淆了我正在用一个我在现实生活中从未做过的巨大操作来检查答案的事实,只是为了验证我的sparse_prod 是否有效。
    • @Divakar 对,很抱歉让您再次遇到麻烦 - 我可以看到如何使用 dot 进行操作,我特别想知道 tensordot,没有外部循环。
    猜你喜欢
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 2019-01-07
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    相关资源
    最近更新 更多