如何在SymPy中正确实现张量缩并:解决向量维度匹配问题
SymPy Tensor模块中传入(n,1)向量的问题解决
问题场景
我正在学习SymPy的Tensor模块,尝试实现类似矩阵与列向量相乘的缩并操作,但遇到了维度匹配错误。
报错代码
from sympy.tensor.tensor import TensorIndexType, TensorHead, tensor_indices import sympy as smp ExTen = TensorIndexType('ExampleTensor') m, n = tensor_indices('m n', ExTen) T = TensorHead('T', [ExTen, ExTen]) ExVec = TensorIndexType('ExampleVector') V = TensorHead('V', [ExVec]) a, b, c, d = smp.symbols('a b c d') v1, v2 = smp.symbols('v_1, v_2') (T(n, -m) * V(m)).replace_with_arrays({V(m): smp.Array([[v1], [v2]]), T(n, -m): smp.Array([[a, b], [c, d]])})
触发错误
ValueError: shapes for tensor V(m) expected to be [dim_E], replacement array shape is (2, 1)
临时可行方案
将向量改为1维数组(行向量形式)后代码可正常运行,但结果是1维数组,不符合预期的列向量输出:
(T(n, -m) * V(m)).replace_with_arrays({V(m): smp.Array([v1, v2]), T(n, -m): smp.Array([[a, b], [c, d]])})
解决方案
SymPy的replace_with_arrays对张量阶数与数组形状有严格匹配要求:1阶张量必须对应1维数组,2阶张量对应2维数组,以此类推。(2,1)是2阶数组,无法直接替换1阶张量V(m)。要实现传入列向量形式并得到列向量结果,可按以下两种方式处理:
方式1:先计算再reshape
用1维数组传入向量完成缩并,再将结果reshape为列向量:
from sympy.tensor.tensor import TensorIndexType, TensorHead, tensor_indices import sympy as smp ExTen = TensorIndexType('ExampleTensor', dim=2) m, n = tensor_indices('m n', ExTen) T = TensorHead('T', [ExTen, ExTen]) ExVec = TensorIndexType('ExampleVector', dim=2) V = TensorHead('V', [ExVec]) a, b, c, d = smp.symbols('a b c d') v1, v2 = smp.symbols('v_1, v_2') # 用1维数组计算得到1维结果 result_1d = (T(n, -m) * V(m)).replace_with_arrays({V(m): smp.Array([v1, v2]), T(n, -m): smp.Array([[a, b], [c, d]])}) # 转换为列向量 result_col = result_1d.reshape(2, 1) print(result_col)
输出:
[[a*v_1 + b*v_2], [c*v_1 + d*v_2]]
方式2:用协变指标匹配数学意义
将向量定义为协变张量(下标指标),计算后转置为列向量,更符合张量分析的数学逻辑:
from sympy.tensor.tensor import TensorIndexType, TensorHead, tensor_indices import sympy as smp ExTen = TensorIndexType('ExampleTensor', dim=2) m, n = tensor_indices('m n', ExTen) T = TensorHead('T', [ExTen, ExTen]) ExVec = TensorIndexType('ExampleVector', dim=2) V = TensorHead('V', [ExVec]) a, b, c, d = smp.symbols('a b c d') v1, v2 = smp.symbols('v_1, v_2') # 定义协变指标的向量 v_cov = tensor_indices('-v', ExVec)[0] # 缩并计算 result_cov = (T(n, -m) * V(v_cov)).replace_with_arrays({V(v_cov): smp.Array([v1, v2]), T(n, -m): smp.Array([[a, b], [c, d]])}) # 转换为列向量 result_col = result_cov.reshape(2, 1) print(result_col)
原理说明
在SymPy Tensor模块中:
- 1阶逆变张量(上标指标,如
V(m))对应数学中的行向量,用1维数组表示 - 1阶协变张量(下标指标,如
V(-m))对应数学中的列向量,同样用1维数组表示 - 缩并操作的结果默认以1维数组输出,如需二维列向量形式,需手动调用
reshape转换
内容的提问来源于stack exchange,提问作者Daddy Myers
相关产品推荐
相关产品推荐

