【问题标题】:Combine Einsum Expressions组合 Einsum 表达式
【发布时间】:2016-04-27 02:40:07
【问题描述】:

我想评价一下

E = np.einsum('ij,jk,kl->ijkl',A,A,A)
F = np.einsum('ijki->ijk',E)

其中 A 是一个矩阵(大小不超过 1000 x 1000)。计算 E 很慢。我想通过只计算我存储在 F 中的“对角线”元素来加快这个速度。是否可以将这两个表达式结合起来?/有没有更好的方法来加快这个计算?

【问题讨论】:

  • 如何在3D 数组中定义“对角线”元素,如F?添加示例案例?
  • 对角线元素是我提取并存储在 F 中的元素。

标签: python numpy linear-algebra


【解决方案1】:

我不确定是否有自动的方法,但您始终可以自己计算并给出最终表达式 einsum:

F = np.einsum('ij,jk,ki->ijk', A, A, A)

【讨论】:

    【解决方案2】:
    In [86]: A=np.random.randint(0,100,(100,100))
    
    In [88]: E1=np.einsum('ijki->ijk',np.einsum('ij,jk,kl->ijkl',A,A,A))
    
    In [89]: E2=np.einsum('ij,jk,ki->ijk',A,A,A)
    
    In [90]: np.allclose(E1,E2)
    Out[90]: True
    

    良好的时间改进 - 100 倍,对应于保存的维度 (l)

    In [91]: timeit np.einsum('ijki->ijk',np.einsum('ij,jk,kl->ijkl',A,A,A))
    1 loops, best of 3: 1.1 s per loop
    
    In [92]: timeit np.einsum('ij,jk,ki->ijk',A,A,A)
    100 loops, best of 3: 10.9 ms per loop
    

    einsum 对所有索引执行组合迭代,尽管是在 Cython 代码中。因此,减少索引的数量可以节省大量时间。看起来i...i 组合在初始计算中有效。

    只有 2g 的内存,(1000,1000) 太大了 E1 情况下的“迭代器太大”,E2 情况下的“内存错误”。

    【讨论】:

    • 谢谢!这真的很有帮助。有没有办法处理“迭代器太大的问题”?我的最终目标是计算 G = np.einsum('ij,jk,kl,lm,mi->ijklm',A,A,A,A,A) ,其中 A 是 1 和 0 的 500 x 500 矩阵。
    • 您的 G 矩阵将包含 500**5 项,大约为 31 万亿。即使每个项目只需要 1 个字节,您也需要 30 TB 的 RAM。所以你可能需要重新考虑你想做什么......
    • 你说得对'好老C'。我一定一直在想我在开发补丁时写的 Cython sum-of-products。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多