给出一些简单的张量
A = sympy.tensor.array.Array( <3rd-rank data consisting of sympy expressions> )
以及表示基础变换的矩阵T
和T1=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
不允许使用符号索引)。
答案 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 替换为数字,就会评估张量表达式。
如果要对阵列的张量积进行操作,请使用tensorproduct
和tensorcontraction
函数。要模拟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⎦