如何让numpy.einsum与sympy一起玩?

vls*_*lsd 8 python nested numpy sympy

好的,所以我有几个多维的numpy数组的sympy对象(表达式).例如:

A = array([[1.0*cos(z0)**2 + 1.0, 1.0*cos(z0)],
          [1.0*cos(z0), 1.00000000000000]], dtype=object)
Run Code Online (Sandbox Code Playgroud)

等等.

我想要做的是使用einsum将这些数组中的几个相乘,因为我已经通过我之前做过的数值计算得到了它的语法.问题是,当我尝试做类似的事情时

einsum('ik,jkim,j', A, B, C)
Run Code Online (Sandbox Code Playgroud)

我收到类型错误:

TypeError: invalid data type for einsum
Run Code Online (Sandbox Code Playgroud)

当然,所以在谷歌上快速搜索显示我可能无法做到这一点,但没有理由为什么.特别是,在这些数组上调用numpy.dot()和numpy.tensordot()函数就像一个魅力.我可以使用tensordot来做我需要的事情,但是当我考虑用嵌套的tensordot调用替换上面的那些(如下的顺序非常重要)的50个左右的Einsten总结时,我的大脑会受到伤害.更糟糕的是,虽然必须调试该代码并寻找那个错位的索引交换.

长话短说,有谁知道为什么tensordot与物体一起工作但是einsum不会?有关解决方法的任何建议吗?如果没有,关于我如何编写自己的包装器到嵌套的tensordot调用的任何建议有点类似于einsum符号(数字而不是字母都可以)?

小智 6

有趣的是,添加optimize="optimal"对我有用

einsum('ik,jkim,j', A, B, C)产生错误,但是

einsum('ik,jkim,j', A, B, C, optimize="optimal")与 sympy 配合得很好。


seb*_*erg 4

Einsum 基本上取代了tensordot(不是dot,因为dot通常使用优化的线性代数包),在代码方面它是完全不同的。

这是一个对象 einsum,它未经测试(对于更复杂的事情),但我认为它应该可以工作......在 C 中做同样的事情可能更简单,因为你可以从真正的 einsum 函数中窃取除循环本身之外的所有内容。所以,如果你愿意,就实施它,让更多的人快乐......

https://gist.github.com/seberg/5236560

我不会保证任何事情,尤其是对于更奇怪的极端情况。当然,我确信你也可以将 einsum 表示法转换为张量表示法,这可能会快一点,因为循环最终将主要用 C 语言......

  • @Krastanov,我的就是 einsum 实际上所做的,我认为 nditer 非常优雅。您的代码并未涵盖 einsum 所做的所有事情(重复索引),否则如果您关心这一点,它可能会更快一些。但将其翻译成 C 语言,这是迄今为止最好的解决方案。 (2认同)