You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:27:45