Julia中的numpy.einsum?(2)

7

从这个问题中,我想知道是否可能有一个更广义的einsum。假设我有以下问题

using PyCall
@pyimport numpy as np

a = rand(10,10,10)
b = rand(10,10)
c = rand(10,10,10)

Q = np.einsum("imk,ml,lkj->ij", a,b,c)

类似这种问题,如果不通过循环求和怎么解决?

最好的问候


1
也许这个张量操作库可以帮助你。请注意,它看起来已经被放弃了(最新提交于2015年3月,目前构建失败)。 - Felipe Lema
你在方程式中漏掉了 cPython 实现严重依赖于 nditer 迭代器。 - hpaulj
1
只是提醒一下,einsum 可能还没有直接移植到 Julia,因为手动编写循环速度同样很快。如果我要编写它的移植版本,我可能会将其作为一个宏来实现,在解析时解码下标字符串并直接扩展为一堆 for 循环(类似于 @printf 的工作方式)。 - mbauman
1个回答

6

编辑/更新:此代码现已注册为软件包,您可以执行Pkg.add("Einsum")命令,然后按照下面的示例进行操作。

原始答案:我刚刚创建了一些代码来完成这个任务。它完全遵循Matt B.在评论中描述的方法。希望能帮到你,如果有问题请告诉我。

https://github.com/ahwillia/Einsum.jl

以下是如何实现您的示例:

using Einsum

a = rand(10,10,10)
b = rand(10,10)
c = rand(10,10,10)
Q = zeros(10,10)

@einsum Q[i,j] = a[i,m,k]*b[m,l]*c[l,k,j]

在幕后,宏会构建以下嵌套的 for 循环,并在编译时将它们插入到您的代码中。请注意,这不是插入的确切代码;它还使用 macroexpand 来检查输入的维度是否相符。
for j = 1:size(Q,2)
    for i = 1:size(Q,1)
        s = 0
        for l = 1:size(b,2)
            for k = 1:size(a,3)
                for m = 1:size(a,2)
                    s += a[i,m,k] * b[m,l] * c[l,k,j]
                end
            end
        end
        Q[i,j] = s
    end
end

如果这个回答解决了你的问题,请将其标记为已解决。谢谢! - Chris Rackauckas
1
这似乎是将求和实现为宏,而不是函数。我对Julia还很陌生;如何在表达式中使用它来创建一个带有Einstein求和语法的新数组。例如,如何使用它来表示在numpy中可能写成z = exp(einsum("j,ijl->il",x,y))的内容? - MRule

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接