文章目录
  1. 1. 张量与矩阵
  2. 2. 爱因斯坦求和约定
  3. 3. 张量的乘法计算
  4. 4. 矩阵与向量的乘法运算
  5. 5. 坐标变换
  6. 6. 张量微分
  7. 7. 总结

所谓张量,是坐标变换下不变的量,也就是说,必须有一种坐标变换关系与之对应。

常见的张量:

  • 0阶:常见形式为标量,温度、势等;
  • 1阶:常见形式为矢量,力、速度等;
  • 2阶:常见形式为矩阵,应力、应变等;
  • 3阶:应力梯度等;
  • 4阶:弹性模量等。

张量在力学中十分常用,而 Numpy 对张量运算和矩阵运算都有支持,需要小心使用。

张量与矩阵

  • 矩阵:矩阵就是一种二维的数据结构,长宽任意,与坐标变换没有关系。而三维空间中的二阶张量一定是\(3\times3\)

  • 向量:在讨论矩阵时,常把向量当作矩阵的特例,这是向量可分为行向量、列向量;但是若把向量作为张量,则并不存在“行、列”的概念。这一点在 Matlab 和 Numpy 中差别明显:

1
2
3
4
5
6
7
> % Matlab 基于矩阵,数据默认为矩阵
> A = [1,2,3]
1 2 3
> A'
1
2
3

1
2
3
4
5
6
7
8
9
>>> # Numpy 对矩阵没有偏爱,维度取决于方括号
>>> A = np.array([1,2,3])
>>> A.T
array([1,2,3])
>>> B = np.array([[1,2,3]])
>>> B.T
array([[1],
[2],
[3]])

爱因斯坦求和约定

这是数学史上的一大发现,若不信的话,可以试着返回那不使用这方法的古板日子。

简言之,就是(N项式中的)一项中,如果一个下标出现两次,就把它作为从 1 变化到 3 的求和变量(称为哑标);如果出现一次,就认为它可从 1 到 3 自由取值(称为自由标)。例如矩阵乘法:

\[ \mathbf{C}=\mathbf{AB}\Leftrightarrow c_{ij}=\sum_{k=1}^3a_{ik}b_{kj}\Leftrightarrow c_{ij}=a_{ik}b_{kj} \]

(不过张量计算中不用直接并在一起表示矩阵相乘)

在 Numpy 中,有一个函数einsum()来按照求和约定求和,但是哑标和自由表没有完全遵守规定:

用法 爱因斯坦记法 注解
c = einsum('i,i',a,b) \(c=a_ib_i\)
c = einsum('ii',a) \(c=a_{ii}\) 迹,相当于trace(a)
c = einsum('ii->i',a) \(c_j=a_{ii}\) 缩并,非标准的标记,理论上是ii->j
c = einsum('ij->i',a) \(c_i=\sum_ja_{ij}\) 单向求和,非标准的标记
c = einsum(a,[0,1],b,[1,0]) \(c=a_{ij}b_{ji}\) 相当于用数字代替了脚标

可以用einsum_path查看其求和过程,输出是一个完整的 log (长长的字符串)。

张量的乘法计算

类型众多,而且很容易和矩阵运算混淆,甚至本身就有些定义不明……下面列出主要运算和 Numpy 函数。注意:

  • 整体表示法只是个记号,爱因斯坦表示法则能揭示其具体运算。
  • 因为张量的阶数是不定的,因此大部分用二阶作为例子,也可以推广到更多。
  • 张量积、外积、克罗内克积众说纷纭,我取了互不矛盾且符合 Numpy 函数的版本。
名称 整体表示法 爱因斯坦表示法 Numpy 函数 注解
张量积 \(\mathbf{C}=\mathbf{AB}\) \(C_{ijkl}=A_{ij}B_{kl}\) tensordot(A,B,0) 阶数为二者之和
内积/点积 \(\mathbf{C}=\mathbf{A}\cdot\mathbf{B}\) \(C_{ij}=A_{ik}B_{kj}\) tensordot(A,B,1)A @ B 二阶相当于矩阵相乘
克罗内克积 \(\mathbf{C}=\mathbf{A}\otimes\mathbf{B}\) \(\mathbf{C}=[A_{ij}\mathbf{B}]\) kron(A,B) 相当于张量积展开
二次点积 \(C=\mathbf{A}:\mathbf{B}\) \(C=A_{ij}B_{ij}\) tensordot(A,B,2) 仅用于二阶;交换律

矩阵与向量的乘法运算

这样就可以看出我们熟知的矩阵、向量的运算与张量运算的关系。其中矢量运算也同样适用于一阶张量。以下大部分运算都可以通过@.T的组合完成,不再列出。

名称 矩阵/向量表示 对应张量运算 Numpy 函数 注解
矩阵乘法 \(\mathbf{AB}\) 内积 matmul(A,B)
矩阵外积 \(\mathbf{A}\circ\mathbf{B}\) 克罗内克积 kron(A,B) 形状与克罗内克不同
矢量内积 \(\vec{a}\cdot\vec{b}\Leftrightarrow\vec{a}^T\vec{b}\) 内积 inner(a,b)
矢量叉积 \(\vec{a}\times\vec{b}\) cross(a,b) 一般用于一阶张量
矢量外积 \(\vec{a}\circ\vec{b}\Leftrightarrow\vec{a}\vec{b}^T\) 张量积 outer(a,b)

坐标变换

坐标变换是张量的根本。设原基为 \(\mathbf{i}\),新基为 \(\bar{\mathbf{i}}\),则变换矩阵 \(\mathbf{\beta}=\bar{\mathbf{i}}\cdot\mathbf{i}\)

对于一阶:

\[ \left\{ \begin{split} \bar{\mathbf{a}}&=\mathbf{\beta}\cdot\mathbf{a}\\ \mathbf{a}&=\mathbf{\beta}^T\cdot\bar{\mathbf{a}} \end{split} \right. \]

对于二阶:

\[ \left\{ \begin{split} \bar{\mathbf{A}}&=\mathbf{\beta}\cdot\mathbf{A}\cdot\mathbf{\beta}^T\\ \mathbf{A}&=\mathbf{\beta}^T\cdot\bar{\mathbf{A}}\cdot\mathbf{\beta} \end{split} \right. \]

张量微分

拉普拉斯算符 \(\vec{\nabla}=(\frac{\partial}{\partial x},\frac{\partial}{\partial y},\frac{\partial}{\partial z})​\) ,以此可表示各种微分运算。设 \(\mathbf{A}(x,y,z)​\) 为一 N 阶张量函数。

函数操作 运算 阶数
梯度 \(\mathrm{grad}\ \mathbf{A}=\mathbf{A}\vec{\nabla}\) N+1
散度 \(\mathrm{div}\ \mathbf{A}=\mathbf{A}\cdot\vec{\nabla}\) N-1
旋度 \(\mathrm{rot}\ \mathbf{A}=\mathbf{A}\times\vec{\nabla}\)(矢量叉积) N

总结

其实很多运算说不清到底适用于谁,例如克罗内克积和矩阵外积,矢量叉积……在 Numpy 中,为了保持语义清晰,可以:

  • 鉴于最常用的运算就是张量内积 / 矩阵乘法,应尽量使用通用的@,这在两种语境下都行得通。
  • 进行物理运算时,采用张量方法;计算线性代数时,采用矩阵方法。
  • 进行矩阵运算:将矢量表示为二维;尽量使用@
  • 进行张量运算:将矢量表示为一维;尽量使用@和;由于无法转置,进行矢量运算时,灵活使用inner(),outer(),cross()
文章目录
  1. 1. 张量与矩阵
  2. 2. 爱因斯坦求和约定
  3. 3. 张量的乘法计算
  4. 4. 矩阵与向量的乘法运算
  5. 5. 坐标变换
  6. 6. 张量微分
  7. 7. 总结