【问题标题】:Explination of numpy's einsumnumpy einsum 的解释
【发布时间】:2021-03-02 03:29:14
【问题描述】:

我目前正在研究用 einsum 函数计算 numpy 中的四阶张量。

我正在计算的张量是用爱因斯坦符号编写的,函数 einsun 完美地完成了工作!但我想知道在以下情况下它在做什么:

import numpy as np

a=np.array([[2,0,3],[0,1,0],[0, 0, 4]])
b= np.eye(3)

r1=np.einsum("ij,kl->ijkl", a, b)
r2=np.einsum("ik,jl->ijkl", a, b)

在r1我基本上是在做标准张量积(相当于np.tensordot(a,b,axes=0))。

r2 呢?

我知道我可以通过a[:,None,:,None]*b[None,:,None,:] 获得价值,但我不知道索引在做什么。这个操作有名字吗?

对不起,如果这太简单了!

【问题讨论】:

  • 我认为r1 和r2 都是外部产品。第二个只是重新排序 4d 结果的轴。矩阵乘积可以进行相同类型的乘法运算,但它对一个或多个轴求和(共享索引)。在您的情况下,没有产品的总和。 r1 也可以用广播编写 - 只需重新排序 None。
  • np.tensordot 对输入进行整形和转置,直到它可以执行标准的 2d dot 乘积,然后将结果转换回来。我的记忆是单个数字轴参数被转换为扩展的轴元组。我发现einsum 索引更清晰,更强大。
  • 关于索引在做什么的问题,你的意思不是很清楚,但听起来你在问None 在做什么。它正在创建一个大小为 1 的额外维度,以便数组兼容乘法。这叫做广播。
  • r2 只是 r1 的轴置换版本

标签: numpy numpy-ndarray numpy-einsum


【解决方案1】:

我尝试使用转置定义来改变多个轴。

它适用于'ij,kl -> ijkl' , 'ik,jl->ijkl' ,'kl,ij->ijkl' 但 'il,jk->ijkl', 'jl,ik->ijkl'and 'jk,il->ijkl' 失败

import numpy as np

a=np.eye(3)
a[0][0]=2
a[0][-1]=3
a[-1][-1]=4

b=np.eye(3)

def permutation(str_,Arr):
    
    Arr=np.reshape(Arr,[3,3,3,3])
   
    def splitString(str_):
        tmp1=str_.split(',')
        tmp2=tmp1[1].split('->')
        str_idx1=tmp1[0]
        str_idx2=tmp2[0]
        str_idx_out=tmp2[1]
        return str_idx1,str_idx2, str_idx_out
    
    
    idx_a, idx_b, idx_out=splitString(str_)
    
    dict_={'i':0,'j':1,'k':2,'l':3}
    
    def split(word): 
        return [char for char in word]
                
    
    a,b=split(idx_a)
    c,d=split(idx_b)
    
    Arr=np.transpose(Arr,(dict_[a],dict_[b],dict_[c],dict_[d]))

    return Arr


str_='jk,il->ijkl'

d=np.outer(a,b)
f=np.einsum(str_, a,b)

check=permutation(str_,d)

if (np.count_nonzero(f-check)==0):
    print ('Code is working!')

else:
    print("Something is wrong...")

感谢您的建议!

【讨论】:

    【解决方案2】:

    r2 与r1 本质上是相同的张量,但索引被重新排列。特别是,r2[i,j,k,l] 等于 a[i,k]*b[k,l]。

    例如:

    >>> r2[0,1,2,1]
    3.0
    

    这对应于a[0,2]*b[1,1]是3 * 1,确实是3。

    另一种思考方式是观察a[:,j,:,l] 在 j == l 时等于 a,否则为零矩阵。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 2020-09-05
      • 2023-03-21
      • 2019-09-17
      相关资源
      最近更新 更多