方法¶
包含对 IndexedBase、Indexed 和 Idx 对象进行操作的函数的模块
检查形状一致性
确定结果表达式中的索引
等等。
此模块中的方法可以通过调用 Expr 对象上的方法来实现。当情况稳定时,这可能是一个有用的重构。
- sympy.tensor.index_methods.get_contraction_structure(expr)[源代码][源代码]¶
确定
expr
的虚拟索引并描述其结构通过 dummy 我们指的是求和指标。
表达式的结构确定并描述如下:
符合条件的索引对象的求和描述为一个字典,其中键是求和索引,对应的值是包含所有适用项的集合。SymPy表达式树中的所有Add对象都以此方式描述。
对于SymPy表达式树中所有*不是*类型为Add的节点,以下规则适用:
如果一个节点在其一个参数中发现缩写,该节点本身将被存储为字典中的一个键。对于该键,相应的值是一个字典列表,每个字典都是对 get_contraction_structure() 进行递归调用的结果。该列表仅包含非平凡更深层次缩写的字典,省略了仅有一个键为 None 的字典。
备注
字典键中表达式的存在表示索引收缩的多个层次。嵌套字典显示嵌套的收缩,并且可能本身包含来自更深层次的字典。在实际计算中,最深嵌套层次的求和必须首先计算,以便外部表达式可以访问结果的索引对象。
示例
>>> from sympy.tensor.index_methods import get_contraction_structure >>> from sympy import default_sort_key >>> from sympy.tensor import IndexedBase, Idx >>> x, y, A = map(IndexedBase, ['x', 'y', 'A']) >>> i, j, k, l = map(Idx, ['i', 'j', 'k', 'l']) >>> get_contraction_structure(x[i]*y[i] + A[j, j]) {(i,): {x[i]*y[i]}, (j,): {A[j, j]}} >>> get_contraction_structure(x[i]*y[j]) {None: {x[i]*y[j]}}
多个缩并因子的乘积会产生嵌套的字典,表示内部缩并。
>>> d = get_contraction_structure(x[i, i]*y[j, j]) >>> sorted(d.keys(), key=default_sort_key) [None, x[i, i]*y[j, j]]
在这种情况下,产品没有缩写:
>>> d[None] {x[i, i]*y[j, j]}
因素被“首先”考虑:
>>> sorted(d[x[i, i]*y[j, j]], key=default_sort_key) [{(i,): {x[i, i]}}, {(j,): {y[j, j]}}]
一个带括号的 Add 对象也会作为嵌套字典返回。包含括号的项是一个 Mul,其参数之间存在收缩,因此它将作为结果中的一个键被找到。它存储了递归调用 Add 表达式所得到的字典。
>>> d = get_contraction_structure(x[i]*(y[i] + A[i, j]*x[j])) >>> sorted(d.keys(), key=default_sort_key) [(A[i, j]*x[j] + y[i])*x[i], (i,)] >>> d[(i,)] {(A[i, j]*x[j] + y[i])*x[i]} >>> d[x[i]*(A[i, j]*x[j] + y[i])] [{None: {y[i]}, (j,): {A[i, j]*x[j]}}]
在字典中,底数或指数中带有缩写的幂也将作为键出现,映射到递归调用的结果列表:
>>> d = get_contraction_structure(A[j, j]**A[i, i]) >>> d[None] {A[j, j]**A[i, i]} >>> nested_contractions = d[A[j, j]**A[i, i]] >>> nested_contractions[0] {(j,): {A[j, j]}} >>> nested_contractions[1] {(i,): {A[i, i]}}
当用字符串表示时,收缩结构的描述在上述例子中可能显得复杂,但迭代起来很容易:
>>> from sympy import Expr >>> for key in d: ... if isinstance(key, Expr): ... continue ... for term in d[key]: ... if term in d: ... # treat deepest contraction first ... pass ... # treat outermost contactions here
- sympy.tensor.index_methods.get_indices(expr)[源代码][源代码]¶
确定表达式
expr
的外部索引通过 outer 我们指的是不是求和索引的索引。返回一个集合和一个字典。集合包含外部索引,字典包含关于索引对称性的信息。
示例
>>> from sympy.tensor.index_methods import get_indices >>> from sympy import symbols >>> from sympy.tensor import IndexedBase >>> x, y, A = map(IndexedBase, ['x', 'y', 'A']) >>> i, j, a, z = symbols('i j a z', integer=True)
总表达式的指标被确定,重复的指标意味着求和,例如矩阵 A 的迹:
>>> get_indices(A[i, i]) (set(), {})
在许多术语的情况下,这些术语需要具有相同的索引。否则会引发 IndexConformanceException。
>>> get_indices(x[i] + A[i, j]*y[j]) ({i}, {})
- 异常:
IndexConformanceException 意味着术语不兼容,例如:
>>> get_indices(x[i] + y[j]) (...) IndexConformanceException: Indices are not consistent: x(i) + y(j)
警告
*外*指标的概念是递归应用的,从最深层次开始。这意味着括号内的哑元首先被假定为求和,因此以下表达式可以被优雅地处理:
>>> get_indices((x[i] + A[i, j]*y[j])*x[j]) ({i, j}, {})
这是正确的,并且可能看起来很方便,但你需要小心这一点,因为如果请求,SymPy 会乐意 .expand() 这个乘积。生成的表达式会将外部的
j
与括号内的哑变量混合,这使得它成为一个不同的表达式。为了安全起见,最好通过为所有应保持独立的收缩使用唯一的指标来避免这种歧义。