N 维数组表达式¶
数组表达式是表示 N 维数组的表达式,而不对其进行求值。这些表达式以某种方式表示对 N 维数组操作的抽象语法树。
每个 N 维数组运算符都有一个对应的数组表达式对象。
对应表:
数组运算符 |
数组表达式运算符 |
---|---|
张量积 |
ArrayTensorProduct |
tensorcontraction |
数组收缩 |
tensordiagonal |
ArrayDiagonal |
permutedims |
PermuteDims |
示例
ArraySymbol
对象是矩阵模块中 MatrixSymbol
对象的 N 维等价物:
>>> from sympy.tensor.array.expressions import ArraySymbol
>>> from sympy.abc import i, j, k
>>> A = ArraySymbol("A", (3, 2, 4))
>>> A.shape
(3, 2, 4)
>>> A[i, j, k]
A[i, j, k]
>>> A.as_explicit()
[[[A[0, 0, 0], A[0, 0, 1], A[0, 0, 2], A[0, 0, 3]],
[A[0, 1, 0], A[0, 1, 1], A[0, 1, 2], A[0, 1, 3]]],
[[A[1, 0, 0], A[1, 0, 1], A[1, 0, 2], A[1, 0, 3]],
[A[1, 1, 0], A[1, 1, 1], A[1, 1, 2], A[1, 1, 3]]],
[[A[2, 0, 0], A[2, 0, 1], A[2, 0, 2], A[2, 0, 3]],
[A[2, 1, 0], A[2, 1, 1], A[2, 1, 2], A[2, 1, 3]]]]
组件明确的数组可以在数组表达式内部添加:
>>> from sympy import Array
>>> from sympy import tensorproduct
>>> from sympy.tensor.array.expressions import ArrayTensorProduct
>>> a = Array([1, 2, 3])
>>> b = Array([i, j, k])
>>> expr = ArrayTensorProduct(a, b, b)
>>> expr
ArrayTensorProduct([1, 2, 3], [i, j, k], [i, j, k])
>>> expr.as_explicit() == tensorproduct(a, b, b)
True
从显式索引形式构建数组表达式¶
数组表达式是隐式索引的。这意味着它们不使用任何索引来表示数组操作。函数 convert_indexed_to_array( ... )
可用于将显式索引表达式转换为数组表达式。它接受两个参数作为输入:显式索引表达式和索引的顺序:
>>> from sympy.tensor.array.expressions import convert_indexed_to_array
>>> from sympy import Sum
>>> A = ArraySymbol("A", (3, 3))
>>> B = ArraySymbol("B", (3, 3))
>>> convert_indexed_to_array(A[i, j], [i, j])
A
>>> convert_indexed_to_array(A[i, j], [j, i])
PermuteDims(A, (0 1))
>>> convert_indexed_to_array(A[i, j] + B[j, i], [i, j])
ArrayAdd(A, PermuteDims(B, (0 1)))
>>> convert_indexed_to_array(Sum(A[i, j]*B[j, k], (j, 0, 2)), [i, k])
ArrayContraction(ArrayTensorProduct(A, B), (1, 2))
数组表达式形式中矩阵的对角线:
>>> convert_indexed_to_array(A[i, i], [i])
ArrayDiagonal(A, (0, 1))
数组表达形式中矩阵的迹:
>>> convert_indexed_to_array(Sum(A[i, i], (i, 0, 2)), [i])
ArrayContraction(A, (0, 1))
与矩阵的兼容性¶
数组表达式可以与矩阵模块中的对象混合使用:
>>> from sympy import MatrixSymbol
>>> from sympy.tensor.array.expressions import ArrayContraction
>>> M = MatrixSymbol("M", 3, 3)
>>> N = MatrixSymbol("N", 3, 3)
以数组表达式的形式表示矩阵乘积:
>>> from sympy.tensor.array.expressions import convert_matrix_to_array
>>> expr = convert_matrix_to_array(M*N)
>>> expr
ArrayContraction(ArrayTensorProduct(M, N), (1, 2))
该表达式可以转换回矩阵形式:
>>> from sympy.tensor.array.expressions import convert_array_to_matrix
>>> convert_array_to_matrix(expr)
M*N
在剩余的轴上添加第二个收缩,以得到 \(M \cdot N\) 的迹:
>>> expr_tr = ArrayContraction(expr, (0, 1))
>>> expr_tr
ArrayContraction(ArrayContraction(ArrayTensorProduct(M, N), (1, 2)), (0, 1))
通过调用 .doit()
来简化表达式,并移除嵌套的数组收缩操作:
>>> expr_tr.doit()
ArrayContraction(ArrayTensorProduct(M, N), (0, 3), (1, 2))
获取数组表达式的显式形式:
>>> expr.as_explicit()
[[M[0, 0]*N[0, 0] + M[0, 1]*N[1, 0] + M[0, 2]*N[2, 0], M[0, 0]*N[0, 1] + M[0, 1]*N[1, 1] + M[0, 2]*N[2, 1], M[0, 0]*N[0, 2] + M[0, 1]*N[1, 2] + M[0, 2]*N[2, 2]],
[M[1, 0]*N[0, 0] + M[1, 1]*N[1, 0] + M[1, 2]*N[2, 0], M[1, 0]*N[0, 1] + M[1, 1]*N[1, 1] + M[1, 2]*N[2, 1], M[1, 0]*N[0, 2] + M[1, 1]*N[1, 2] + M[1, 2]*N[2, 2]],
[M[2, 0]*N[0, 0] + M[2, 1]*N[1, 0] + M[2, 2]*N[2, 0], M[2, 0]*N[0, 1] + M[2, 1]*N[1, 1] + M[2, 2]*N[2, 1], M[2, 0]*N[0, 2] + M[2, 1]*N[1, 2] + M[2, 2]*N[2, 2]]]
表达矩阵的迹:
>>> from sympy import Trace
>>> convert_matrix_to_array(Trace(M))
ArrayContraction(M, (0, 1))
>>> convert_matrix_to_array(Trace(M*N))
ArrayContraction(ArrayTensorProduct(M, N), (0, 3), (1, 2))
表达矩阵的转置(将表示为轴的排列:
>>> convert_matrix_to_array(M.T)
PermuteDims(M, (0 1))
计算导数数组表达式:
>>> from sympy.tensor.array.expressions import array_derive
>>> d = array_derive(M, M)
>>> d
PermuteDims(ArrayTensorProduct(I, I), (3)(1 2))
验证导数是否与使用显式矩阵计算的形式一致:
>>> d.as_explicit()
[[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 1, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 1], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 1], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [1, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 1]]]]
>>> Me = M.as_explicit()
>>> Me.diff(Me)
[[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 1, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 1], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [1, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 1, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 1], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [1, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 1]]]]
- class sympy.tensor.array.expressions.ArrayTensorProduct(*args, **kwargs)[源代码][源代码]¶
表示数组类对象的张量积的类。
- 属性:
args
返回 ‘self’ 的参数元组。
assumptions0
返回对象 \(type\) 假设。
canonical_variables
返回一个字典,将
self.bound_symbols
中定义的任何变量映射到与表达式中任何自由符号不冲突的符号。- expr_free_symbols
free_symbols
从自身的原子中返回那些自由符号。
func
表达式中的顶级函数。
- is_algebraic
- is_antihermitian
- is_commutative
is_comparable
如果 self 可以计算为一个具有精度的实数(或已经是一个实数),则返回 True,否则返回 False。
- is_complex
- is_composite
- is_even
- is_extended_negative
- is_extended_nonnegative
- is_extended_nonpositive
- is_extended_nonzero
- is_extended_positive
- is_extended_real
- is_finite
- is_hermitian
- is_imaginary
- is_infinite
- is_integer
- is_irrational
- is_negative
- is_noninteger
- is_nonnegative
- is_nonpositive
- is_nonzero
- is_odd
- is_polar
- is_positive
- is_prime
- is_rational
- is_real
- is_transcendental
- is_zero
- 形状
subranks
返回当前对象中最顶层张量积中对象的秩。
方法
as_content_primitive
([radical, clear])一个存根,允许在计算表达式的内容和基本组件时跳过基本参数(如元组)。
as_dummy
()返回表达式,其中任何具有结构绑定符号的对象都被替换为在其出现的对象中唯一的规范符号,并且仅对交换性具有默认假设为True。
atoms
(*types)返回构成当前对象的原子。
class_key
()类的好顺序。
compare
(other)如果对象在规范意义上小于、等于或大于其他对象,则返回 -1、0、1。
count
(query)计算匹配的子表达式的数量。
count_ops
([visual])用于返回操作计数的 count_ops 的包装器。
doit
(**hints)dummy_eq
(other[, symbol])比较两个表达式并处理哑符号。
find
(query[, group])查找所有匹配查询的子表达式。
fromiter
(args, **assumptions)从可迭代对象创建一个新对象。
has
(*patterns)测试是否有任何子表达式匹配任何模式。
has_free
(*patterns)如果 self 包含对象
x
作为自由表达式,则返回 True,否则返回 False。has_xfree
(s)如果 self 有 s 中的任何一个模式作为自由参数,则返回 True,否则返回 False。
is_same
(b[, approx])如果 a 和 b 结构相同则返回 True,否则返回 False。
match
(pattern[, old])模式匹配。
matches
(expr[, repl_dict, old])用于 match() 的辅助方法,用于在 self 中的通配符符号与 expr 中的表达式之间寻找匹配。
rcall
(*args)通过表达式树递归应用于参数。
refine
([assumption])请参阅 sympy.assumptions 中的 refine 函数。
replace
(query, value[, map, simultaneous, exact])将
self
中匹配的子表达式替换为value
。rewrite
(*args[, deep])使用定义的规则重写 self。
simplify
(**kwargs)请参阅 sympy.simplify 中的 simplify 函数。
sort_key
([order])返回一个排序键。
subrank
()subranks
的总和。subs
(*args, **kwargs)在简化参数后,在表达式中用新内容替换旧内容。
xreplace
(rule)替换表达式中对象的出现。
as_explicit
复制
could_extract_minus_sign
is_hypergeometric
- class sympy.tensor.array.expressions.ArrayContraction(
- expr,
- *contraction_indices,
- **kwargs,
此类旨在表示数组的缩写形式,以便代码打印机易于处理。
- 属性:
args
返回 ‘self’ 的参数元组。
assumptions0
返回对象 \(type\) 假设。
canonical_variables
返回一个字典,将
self.bound_symbols
中定义的任何变量映射到与表达式中任何自由符号不冲突的符号。- contraction_indices
- 表达式
- expr_free_symbols
- 自由指标
- free_indices_to_position
free_symbols
从自身的原子中返回那些自由符号。
func
表达式中的顶级函数。
- is_algebraic
- is_antihermitian
- is_commutative
is_comparable
如果 self 可以计算为一个具有精度的实数(或已经是一个实数),则返回 True,否则返回 False。
- is_complex
- is_composite
- is_even
- is_extended_negative
- is_extended_nonnegative
- is_extended_nonpositive
- is_extended_nonzero
- is_extended_positive
- is_extended_real
- is_finite
- is_hermitian
- is_imaginary
- is_infinite
- is_integer
- is_irrational
- is_negative
- is_noninteger
- is_nonnegative
- is_nonpositive
- is_nonzero
- is_odd
- is_polar
- is_positive
- is_prime
- is_rational
- is_real
- is_transcendental
- is_zero
- 形状
subranks
返回当前对象中最顶层张量积中对象的秩。
方法
as_content_primitive
([radical, clear])一个存根,允许在计算表达式的内容和基本组件时跳过基本参数(如元组)。
as_dummy
()返回表达式,其中任何具有结构绑定符号的对象都被替换为在其出现的对象中唯一的规范符号,并且仅对交换性具有默认假设为True。
atoms
(*types)返回构成当前对象的原子。
class_key
()类的好顺序。
compare
(other)如果对象在规范意义上小于、等于或大于其他对象,则返回 -1、0、1。
count
(query)计算匹配的子表达式的数量。
count_ops
([visual])用于返回操作计数的 count_ops 的包装器。
doit
(**hints)dummy_eq
(other[, symbol])比较两个表达式并处理哑符号。
find
(query[, group])查找所有匹配查询的子表达式。
fromiter
(args, **assumptions)从可迭代对象创建一个新对象。
has
(*patterns)测试是否有任何子表达式匹配任何模式。
has_free
(*patterns)如果 self 包含对象
x
作为自由表达式,则返回 True,否则返回 False。has_xfree
(s)如果 self 有 s 中的任何一个模式作为自由参数,则返回 True,否则返回 False。
is_same
(b[, approx])如果 a 和 b 结构相同则返回 True,否则返回 False。
match
(pattern[, old])模式匹配。
matches
(expr[, repl_dict, old])用于 match() 的辅助方法,用于在 self 中的通配符符号与 expr 中的表达式之间寻找匹配。
rcall
(*args)通过表达式树递归应用于参数。
refine
([assumption])请参阅 sympy.assumptions 中的 refine 函数。
replace
(query, value[, map, simultaneous, exact])将
self
中匹配的子表达式替换为value
。rewrite
(*args[, deep])使用定义的规则重写 self。
simplify
(**kwargs)请参阅 sympy.simplify 中的 simplify 函数。
sort_args_by_name
()在张量积中对参数进行排序,使其顺序为字典序。
sort_key
([order])返回一个排序键。
split_multiple_contractions
()识别多个缩写并尝试将它们重写为成对缩写。
subrank
()subranks
的总和。subs
(*args, **kwargs)在简化参数后,在表达式中用新内容替换旧内容。
xreplace
(rule)替换表达式中对象的出现。
as_explicit
复制
could_extract_minus_sign
flatten_contraction_of_diagonal
is_hypergeometric
- class sympy.tensor.array.expressions.ArrayDiagonal(expr, *diagonal_indices, **kwargs)[源代码][源代码]¶
表示对角运算符的类。
- 属性:
args
返回 ‘self’ 的参数元组。
assumptions0
返回对象 \(type\) 假设。
canonical_variables
返回一个字典,将
self.bound_symbols
中定义的任何变量映射到与表达式中任何自由符号不冲突的符号。- diagonal_indices
- 表达式
- expr_free_symbols
free_symbols
从自身的原子中返回那些自由符号。
func
表达式中的顶级函数。
- is_algebraic
- is_antihermitian
- is_commutative
is_comparable
如果 self 可以计算为一个具有精度的实数(或已经是一个实数),则返回 True,否则返回 False。
- is_complex
- is_composite
- is_even
- is_extended_negative
- is_extended_nonnegative
- is_extended_nonpositive
- is_extended_nonzero
- is_extended_positive
- is_extended_real
- is_finite
- is_hermitian
- is_imaginary
- is_infinite
- is_integer
- is_irrational
- is_negative
- is_noninteger
- is_nonnegative
- is_nonpositive
- is_nonzero
- is_odd
- is_polar
- is_positive
- is_prime
- is_rational
- is_real
- is_transcendental
- is_zero
- 形状
subranks
返回当前对象中最顶层张量积中对象的秩。
方法
as_content_primitive
([radical, clear])一个存根,允许在计算表达式的内容和基本组件时跳过基本参数(如元组)。
as_dummy
()返回表达式,其中任何具有结构绑定符号的对象都被替换为在其出现的对象中唯一的规范符号,并且仅对交换性具有默认假设为True。
atoms
(*types)返回构成当前对象的原子。
class_key
()类的好顺序。
compare
(other)如果对象在规范意义上小于、等于或大于其他对象,则返回 -1、0、1。
count
(query)计算匹配的子表达式的数量。
count_ops
([visual])用于返回操作计数的 count_ops 的包装器。
doit
(**hints)dummy_eq
(other[, symbol])比较两个表达式并处理哑符号。
find
(query[, group])查找所有匹配查询的子表达式。
fromiter
(args, **assumptions)从可迭代对象创建一个新对象。
has
(*patterns)测试是否有任何子表达式匹配任何模式。
has_free
(*patterns)如果 self 包含对象
x
作为自由表达式,则返回 True,否则返回 False。has_xfree
(s)如果 self 有 s 中的任何一个模式作为自由参数,则返回 True,否则返回 False。
is_same
(b[, approx])如果 a 和 b 结构相同则返回 True,否则返回 False。
match
(pattern[, old])模式匹配。
matches
(expr[, repl_dict, old])用于 match() 的辅助方法,用于在 self 中的通配符符号与 expr 中的表达式之间寻找匹配。
rcall
(*args)通过表达式树递归应用于参数。
refine
([assumption])请参阅 sympy.assumptions 中的 refine 函数。
replace
(query, value[, map, simultaneous, exact])将
self
中匹配的子表达式替换为value
。rewrite
(*args[, deep])使用定义的规则重写 self。
simplify
(**kwargs)请参阅 sympy.simplify 中的 simplify 函数。
sort_key
([order])返回一个排序键。
subrank
()subranks
的总和。subs
(*args, **kwargs)在简化参数后,在表达式中用新内容替换旧内容。
xreplace
(rule)替换表达式中对象的出现。
as_explicit
复制
could_extract_minus_sign
is_hypergeometric
- class sympy.tensor.array.expressions.PermuteDims(
- expr,
- permutation=None,
- index_order_old=None,
- index_order_new=None,
- **kwargs,
表示数组轴排列的类。
- 属性:
args
返回 ‘self’ 的参数元组。
assumptions0
返回对象 \(type\) 假设。
canonical_variables
返回一个字典,将
self.bound_symbols
中定义的任何变量映射到与表达式中任何自由符号不冲突的符号。- 表达式
- expr_free_symbols
free_symbols
从自身的原子中返回那些自由符号。
func
表达式中的顶级函数。
- is_algebraic
- is_antihermitian
- is_commutative
is_comparable
如果 self 可以计算为一个具有精度的实数(或已经是一个实数),则返回 True,否则返回 False。
- is_complex
- is_composite
- is_even
- is_extended_negative
- is_extended_nonnegative
- is_extended_nonpositive
- is_extended_nonzero
- is_extended_positive
- is_extended_real
- is_finite
- is_hermitian
- is_imaginary
- is_infinite
- is_integer
- is_irrational
- is_negative
- is_noninteger
- is_nonnegative
- is_nonpositive
- is_nonzero
- is_odd
- is_polar
- is_positive
- is_prime
- is_rational
- is_real
- is_transcendental
- is_zero
- 排列
- 形状
subranks
返回当前对象中最顶层张量积中对象的秩。
方法
as_content_primitive
([radical, clear])一个存根,允许在计算表达式的内容和基本组件时跳过基本参数(如元组)。
as_dummy
()返回表达式,其中任何具有结构绑定符号的对象都被替换为在其出现的对象中唯一的规范符号,并且仅对交换性具有默认假设为True。
atoms
(*types)返回构成当前对象的原子。
class_key
()类的好顺序。
compare
(other)如果对象在规范意义上小于、等于或大于其他对象,则返回 -1、0、1。
count
(query)计算匹配的子表达式的数量。
count_ops
([visual])用于返回操作计数的 count_ops 的包装器。
doit
(**hints)dummy_eq
(other[, symbol])比较两个表达式并处理哑符号。
find
(query[, group])查找所有匹配查询的子表达式。
fromiter
(args, **assumptions)从可迭代对象创建一个新对象。
has
(*patterns)测试是否有任何子表达式匹配任何模式。
has_free
(*patterns)如果 self 包含对象
x
作为自由表达式,则返回 True,否则返回 False。has_xfree
(s)如果 self 有 s 中的任何一个模式作为自由参数,则返回 True,否则返回 False。
is_same
(b[, approx])如果 a 和 b 结构相同则返回 True,否则返回 False。
match
(pattern[, old])模式匹配。
matches
(expr[, repl_dict, old])用于 match() 的辅助方法,用于在 self 中的通配符符号与 expr 中的表达式之间寻找匹配。
nest_permutation
()已弃用。
rcall
(*args)通过表达式树递归应用于参数。
refine
([assumption])请参阅 sympy.assumptions 中的 refine 函数。
replace
(query, value[, map, simultaneous, exact])将
self
中匹配的子表达式替换为value
。rewrite
(*args[, deep])使用定义的规则重写 self。
simplify
(**kwargs)请参阅 sympy.simplify 中的 simplify 函数。
sort_key
([order])返回一个排序键。
subrank
()subranks
的总和。subs
(*args, **kwargs)在简化参数后,在表达式中用新内容替换旧内容。
xreplace
(rule)替换表达式中对象的出现。
as_explicit
复制
could_extract_minus_sign
is_hypergeometric
示例
>>> from sympy.tensor.array import permutedims >>> from sympy import MatrixSymbol >>> M = MatrixSymbol("M", 3, 3) >>> cg = permutedims(M, [1, 0])
对象
cg
表示M
的转置,因为排列[1, 0]
将通过交换其索引来作用于其索引:\(M_{ij} \Rightarrow M_{ji}\)
当转换回矩阵形式时,这一点显而易见:
>>> from sympy.tensor.array.expressions.from_array_to_matrix import convert_array_to_matrix >>> convert_array_to_matrix(cg) M.T
>>> N = MatrixSymbol("N", 3, 2) >>> cg = permutedims(N, [1, 0]) >>> cg.shape (2, 3)
有一些可选参数可以用作排列的替代方案:
>>> from sympy.tensor.array.expressions import ArraySymbol, PermuteDims >>> M = ArraySymbol("M", (1, 2, 3, 4, 5)) >>> expr = PermuteDims(M, index_order_old="ijklm", index_order_new="kijml") >>> expr PermuteDims(M, (0 2 1)(3 4)) >>> expr.shape (3, 1, 2, 5, 4)
为了达到标准形式,张量积的排列被简化:
>>> from sympy.tensor.array import tensorproduct >>> M = MatrixSymbol("M", 4, 5) >>> tp = tensorproduct(M, N) >>> tp.shape (4, 5, 3, 2) >>> perm1 = permutedims(tp, [2, 3, 1, 0])
参数
(M, N)
已被排序,排列已被简化,表达式等价:>>> perm1.expr.args (N, M) >>> perm1.shape (3, 2, 5, 4) >>> perm1.permutation (2 3)
排列在其数组形式中已从
[2, 3, 1, 0]
简化为[0, 1, 3, 2]
,因为张量积 \(M\) 和 \(N\) 的参数已被切换:>>> perm1.permutation.array_form [0, 1, 3, 2]
我们可以嵌套第二个排列:
>>> perm2 = permutedims(perm1, [1, 0, 2, 3]) >>> perm2.shape (2, 3, 5, 4) >>> perm2.permutation.array_form [1, 0, 3, 2]