爱因斯坦 - 公约就像隐含总结与同情

时间:2017-03-20 15:03:59

标签: sympy

给出一些简单的张量

A = sympy.tensor.array.Array( <3rd-rank data consisting of sympy expressions> )

以及表示基础变换的矩阵TT1=T.inv(),是否有可能使用像

这样的表示法
B[i,j,k] = T[i,a] * A[a,b,c] * T1[b,j] * T1[c,k]

计算变换张量?

原则上,似乎可以同意使用爱因斯坦求和惯例,但我遇到了多个问题:

  • 代码段

    from sympy import symbols, IndexedBase, EinsteinSum 
    TX, A, x = symbols('TX A x', cls=IndexedBase)
    i, j = symbols('i j')
    ein_sum = EinsteinSum(A[i, j] * x[j])
    

    我发现不起作用,因为EinsteinSum似乎不再存在。

  • 尝试使用

    等表达式时
    var("i")
    Sum(A[i,i,i],(i,1,3))
    

    我会引发一个TypeError(显然Array不允许使用符号索引)。

1 个答案:

答案 0 :(得分:1)

最近在SymPy的development version添加了一些功能。它们将在下一版本中提供。

注意: EinsteinSum从未存在过。只有一个建议添加它,IIRC。

假设您有

给出的3级数组A
In [13]: A
Out[13]: 
⎡⎡1  0  0   0 ⎤  ⎡0   0   0  1⎤  ⎡0   0  0  -ⅈ⎤  ⎡0   0  1  0 ⎤⎤
⎢⎢            ⎥  ⎢            ⎥  ⎢            ⎥  ⎢            ⎥⎥
⎢⎢0  1  0   0 ⎥  ⎢0   0   1  0⎥  ⎢0   0  ⅈ  0 ⎥  ⎢0   0  0  -1⎥⎥
⎢⎢            ⎥  ⎢            ⎥  ⎢            ⎥  ⎢            ⎥⎥
⎢⎢0  0  -1  0 ⎥  ⎢0   -1  0  0⎥  ⎢0   ⅈ  0  0 ⎥  ⎢-1  0  0  0 ⎥⎥
⎢⎢            ⎥  ⎢            ⎥  ⎢            ⎥  ⎢            ⎥⎥
⎣⎣0  0  0   -1⎦  ⎣-1  0   0  0⎦  ⎣-ⅈ  0  0  0 ⎦  ⎣0   1  0  0 ⎦⎦

和一个简单的矩阵T由:

给出
In [15]: T
Out[15]: 
⎡2  0  0  0⎤
⎢          ⎥
⎢0  2  0  0⎥
⎢          ⎥
⎢0  0  2  0⎥
⎢          ⎥
⎣0  0  0  2⎦

那样:

In [17]: T.inv()
Out[17]: 
⎡1/2   0    0    0 ⎤
⎢                  ⎥
⎢ 0   1/2   0    0 ⎥
⎢                  ⎥
⎢ 0    0   1/2   0 ⎥
⎢                  ⎥
⎣ 0    0    0   1/2⎦

我建议将所有内容转换为Array,因为我担心Matrix和Array对象无法很好地互操作。

现在支持符号索引:

In [28]: T[i, j]
Out[28]: 
⎡2  0  0  0⎤      
⎢          ⎥      
⎢0  2  0  0⎥      
⎢          ⎥[i, j]
⎢0  0  2  0⎥      
⎢          ⎥      
⎣0  0  0  2⎦ 

只要将值 i j 替换为数字,就会评估张量表达式。

如果要对阵列的张量积进行操作,请使用tensorproducttensorcontraction函数。要模拟Array对象上的矩阵乘法:

In [29]: tensorcontraction(tensorproduct(T, T1), (1, 2))
Out[29]: 
⎡1  0  0  0⎤
⎢          ⎥
⎢0  1  0  0⎥
⎢          ⎥
⎢0  0  1  0⎥
⎢          ⎥
⎣0  0  0  1⎦

注意:如果同时在多个轴上签约,最新的SymPy版本会出现tensorcontraction的错误。发展部门应该解决。

表达式Sum(A[i,i,i],(i, 0, 3))有效(注意:从0开始索引,而不是Python中的1)。

表达式Sum(T[i, j]*T1[j, k], (j, 0, 3))没有给出好的结果,因为它不明白要简化什么。比较:

In [38]: Sum(T[i, j]*T1[j, k], (j, 0, 3))
Out[38]: 
  3                                                 
______                                              
╲                                                   
 ╲     ⎡1/2   0    0    0 ⎤       ⎡2  0  0  0⎤      
  ╲    ⎢                  ⎥       ⎢          ⎥      
   ╲   ⎢ 0   1/2   0    0 ⎥       ⎢0  2  0  0⎥      
    ╲  ⎢                  ⎥[j, k]⋅⎢          ⎥[i, j]
    ╱  ⎢ 0    0   1/2   0 ⎥       ⎢0  0  2  0⎥      
   ╱   ⎢                  ⎥       ⎢          ⎥      
  ╱    ⎣ 0    0    0   1/2⎦       ⎣0  0  0  2⎦      
 ╱                                                  
╱                                                   
‾‾‾‾‾‾                                              
j = 0   

如果你评价它,你会得到:

In [39]: Sum(T[i, j]*T1[j, k], (j, 0, 3)).doit()
Out[39]: 
⎡1/2   0    0    0 ⎤       ⎡2  0  0  0⎤         ⎡1/2   0    0    0 ⎤       ⎡2  0  0  0⎤         ⎡1/2   0    0    0 ⎤       ⎡2  0  0  0⎤   
⎢                  ⎥       ⎢          ⎥         ⎢                  ⎥       ⎢          ⎥         ⎢                  ⎥       ⎢          ⎥   
⎢ 0   1/2   0    0 ⎥       ⎢0  2  0  0⎥         ⎢ 0   1/2   0    0 ⎥       ⎢0  2  0  0⎥         ⎢ 0   1/2   0    0 ⎥       ⎢0  2  0  0⎥   
⎢                  ⎥[0, k]⋅⎢          ⎥[i, 0] + ⎢                  ⎥[1, k]⋅⎢          ⎥[i, 1] + ⎢                  ⎥[2, k]⋅⎢          ⎥[i,
⎢ 0    0   1/2   0 ⎥       ⎢0  0  2  0⎥         ⎢ 0    0   1/2   0 ⎥       ⎢0  0  2  0⎥         ⎢ 0    0   1/2   0 ⎥       ⎢0  0  2  0⎥   
⎢                  ⎥       ⎢          ⎥         ⎢                  ⎥       ⎢          ⎥         ⎢                  ⎥       ⎢          ⎥   
⎣ 0    0    0   1/2⎦       ⎣0  0  0  2⎦         ⎣ 0    0    0   1/2⎦       ⎣0  0  0  2⎦         ⎣ 0    0    0   1/2⎦       ⎣0  0  0  2⎦   

      ⎡1/2   0    0    0 ⎤       ⎡2  0  0  0⎤      
      ⎢                  ⎥       ⎢          ⎥      
      ⎢ 0   1/2   0    0 ⎥       ⎢0  2  0  0⎥      
 2] + ⎢                  ⎥[3, k]⋅⎢          ⎥[i, 3]
      ⎢ 0    0   1/2   0 ⎥       ⎢0  0  2  0⎥      
      ⎢                  ⎥       ⎢          ⎥      
      ⎣ 0    0    0   1/2⎦       ⎣0  0  0  2⎦ 

这是正确的结果,但表示不好看。 SymPy无法识别可能发生的简化。

要以漂亮的形式取回矩阵,您可以使用:

In [45]: Matrix([[Sum(T[i, j]*T1[j, k], (j, 0, 3)).doit().subs({i: ni, k: nk}) for ni in range(4)] for nk in range(4)])
Out[45]: 
⎡1  0  0  0⎤
⎢          ⎥
⎢0  1  0  0⎥
⎢          ⎥
⎢0  0  1  0⎥
⎢          ⎥
⎣0  0  0  1⎦