矩阵与张量运算
这一教程将对 Wolfram 语言所提供的用于构造和操控矩阵、向量和张量的函数进行评述. 它着重介绍 Wolfram 语言的专用函数,并使用矩阵作为例子. 然而,所有函数都是一般的,同样适用于向量和张量.
构造矩阵
Table[f,{i,m},{j,n}] | 建立一个 m×n 矩阵,其中 f 是 i 和 j 的函数,它给出第 i,j 项的值 |
Array[f,{m,n}] | 建立一个 m×n 矩阵,其中第 i,j 项是 f[i,j] |
DiagonalMatrix[list] | 建立一个对角矩阵,对角线上是 list 的元素 |
IdentityMatrix[n] | 建立一个 n×n 单位阵 |
ConstantArray[val,{m,n}]] | 建立一个 m×n 矩阵,其中每一个元素都是 val |
RandomReal[{0,val},{m,n}]] | 建立一个各项随机产生的 m×n 矩阵 |
Normal[SparseArray[{{i1,j1}->v1,{i2,j2}->v2,…},{m,n}]] | |
建立一个 m×n 矩阵,其中在位置{ik,jk}处的值为非零值 νk |
SparseArray[{},{n,n}] | 一个零矩阵 |
SparseArray[{i_,i_}->1,{n,n}] | 一个 n×n 单位矩阵 |
SparseArray[{i_,j_}/;i>=j->1,{n,n}] | |
一个下三角矩阵 |
通过 SparseArray 构建特殊类型的矩阵.
能够将文件读入矩阵的函数在矩阵的"导入和导出" 一节中介绍.
特殊矩阵
HilbertMatrix[n] | 创建一个 n×n Hilbert 矩阵,其中元素通过 1/(i+j-1) 给出 |
HilbertMatrix[{m,n}] | 创建一个 m×n Hilbert 矩阵 |
HankelMatrix[n] | 创建一个 n×n Hankel 矩阵,其中第一列通过1, 2, …, n 给出,且主反对角线下方的各元素均为零 |
HankelMatrix[list] | 创建一个 Hankel 矩阵,其中第一列通过 list 给出, 且主反对角线下方的各元素均为零 |
HankelMatrix[col,row] | 创建一个 Hankel 矩阵,其中第一列通过列表 col 给出,最后一行通过列表 row 给出 |
结构操作
这些操作全部与矩阵结构有关. 这一节中所介绍的许多技术可以应用于 Wolfram 语言表达式,并非矩阵专用.
获得矩阵的一部分
使用 Wolfram 语言函数 Part 可以直接提取矩阵的元素、行或列. 通常 Part 可以使用[[ ]] 符号进行输入.
m[[i,j]] | 第 i,j 项 |
m[[i]] | 第 i 行 |
m[[i;;i]] | i 至 j 行 |
m[[All,i]] | 第 i 列 |
m[[All,i;;j]] | i 至 j 列 |
m[[{i1,…,ir},{j1,…,js}]] | r×s 子矩阵,其中元素的行标为 ik, 列标为 jk |
Tr[m,List] | m 的对角元素列表 |
应该注意到这些用于矩阵部分提取的命令适用于任何 Wolfram 语言表达式.
获得多个部分
设置矩阵的部分
使用任务左方的 Wolfram 语言函数 Part 可以设置矩阵的元素、行和列从而直接更新矩阵.
m={{a11,a12,…},{a21,a22,…},…} | 指定 m 为一个矩阵 |
m[[i,j]]=v | 重新设置元素{i,j} 为 v |
m[[i]]=v | 重新设置行 i 的全部元素为 v |
m[[i]]={v1,v2,…} | 重新设置行 i 的全部元素为{v1,v2,…} |
m[[All,j]]=v | 重新设置列 j 的全部元素为 v |
m[[All,j]]={v1,v2,…} | 重新设置列 j 的全部元素为{v1,v2,…} |
可以使用任务左方的函数 Part 来更新部分矩阵.
设置多个部分
提取子矩阵
m[[i0;;i1,j0;;j1]] | 提取行 i0 至 i1 及列 j0 至 j1 组成的子矩阵 |
m[[i0;;i1]] | 提取行 i0 至 i1 组成的子矩阵 |
m[[All,j0;;j1]] | 提取列 j0 至 j1 组成的子矩阵 |
删除行与列
可以使用 Drop 进行行或列的删除.
Drop[m,{i0,i1}] | 删除行 i0 至 i1 |
Drop[m,{},{j0,j1}] | 删除列 j0 至 j1 |
Drop[m,{i0,i1},{j0,j1}] | 删除行 i0 至 i1以及列 j0 至 j1 |
插入行与列
可以使用 Insert 进行行或列的插入.
Insert[m,r,i] | 在矩阵 m 的位置 i 处插入行 r |
扩展矩阵
转置
元素的轮换
矩阵的测试
Wolfram 语言提供了一系列用于测试矩阵及提取尺寸信息的函数.
MatrixQ[expr] | 如果 expr 是矩阵的形式,则给出 True,否则给出 False |
Dimensions[expr] | 向量或矩阵的维数列表 |
mi==mj | 比较两个矩阵中元素的等价性 |
应该注意到 Equal 可用于任何 Wolfram 语言表达式. 如果想要使用矩阵的整体属性比较两个矩阵相等与否,比较矩阵范数可能更好. 这将在后面讨论.
进一步的结构操作
Flatten[m] | 展平 m 中的嵌套列表 |
Flatten[m,n] | 将 m 中的嵌套列表展平至层 n |
Partition[m,n] | 将 m 分成长度为 n 的子列表 |
Join[m1,m2] | 将 m1 和 m2 串联 |
Append[m,r] | 在 m 的尾部插入行 r |
Prepend[m,r] | 在 m 的头部插入行 r |
应该注意到这也可以通过 Insert 完成;参见"插入行和列"一节.
元素相关的操作
可列表性
映射
向量和张量
除了支持矩阵外,Wolfram 语言也同样支持向量和张量. 所有这一切都通过列表建立. 正如在 "Wolfram 语言中的线性代数引言"一节所介绍的, Wolfram 语言使用张量一词来指广义化的矩阵. 构建矩阵的所有操作可以被推广到向量和张量. Wolfram 语言向量的列表为1层.
Table[f,{i,n}] | 通过计算 f 在 i=1,2,… ,n 的值,建立一个长度为 n 的向量 |
Array[a,n] | 建立一个长为 n,形如 {a[1],a[2],…} 的向量 |
Range[n] | 创建列表{1,2,3,… ,n} |
Range[n1,n2] | 创建列表 {n1,n1+1…,n2} |
Range[n1,n2,dn] | 创建列表 {n1,n1+dn …,n2} |
应该注意的是,Wolfram 语言中没有行或列向量的概念;向量只有一个指标,用于指定该向量的一个元素.
向量和张量的测试
Wolfram 语言提供了一系列测试向量和张量并提取尺寸信息的函数.
VectorQ[expr] | 如果 expr 具有向量的形式则返回 True,否则返回 False |
MatrixQ[expr] | 如果 expr 具有矩阵的形式则返回 True,否则返回 False |
ArrayQ[t,n] | 测试 t 是否是一个 n 阶张量 |
Dimensions[expr] | 一个向量或矩阵的维数列表 |
ArrayDepth[t] | 找到一个张量的阶 |
ti==tj | 比较两个张量中的元素是否相等 |
矩阵的可视化
MatrixForm[mat] | 显示一个矩阵,其元素以二维数组方式排列 |
MatrixPlot[mat] | 显示 mat 的结构模式 |
矩阵格式化
绘制矩阵
MatrixPlot 有一系列图形选项来控制图形的外观. 其中许多是 Wolfram 语言 DensityGraphics 对象的常规选项. 该函数会有一个特殊选项 MaxPlotPoints 来控制矩阵显示的最大尺寸. 尺寸在此之上的矩阵将被降低采样率. 一些重要的选项归纳如下.
选项名称 | 默认值 | |
MaxPlotPoints | 200 | 矩阵显示的最大尺寸 |
AspectRatio | 1 | 缩放最终图像形状 |
ColorRules | Automatic | 为每个元素着色 |
ColorFunction | Automatic | 为每个元素着色的函数 |
Mesh | False | 是否绘制网格 |
MeshStyle | GrayLevel[1] | 网格样式 |
MatrixPlot 选项.
导入和导出矩阵
Wolfram 语言提供了一系列用于导入和导出的不同工具. 如果想将数据保存在文件中,以便以后您或同事可以继续在 Wolfram 语言中使用,您可能想使用一些适用于文件中 Wolfram 语言表达式的函数. 这些将在"表达式的导入和导出"中讨论.
还存在其它矩阵格式. 例如,Harwell–Boeing 用于稀疏矩阵以及 Matrix Market 用于稀疏和稠密矩阵.这些将在"稀疏矩阵的导入和导出"中讨论. 此外,MAT 矩阵格式以及 FITS 天文数据格式也是有用的导入和导出格式.
矩阵乘法
矩阵乘法的定义按下式给定,其中 是两个矩阵 和 的乘积,即 .
该定义可以进行推广,下式给出的是两个任意阶张量 和 的乘积,乘积用 表示.
因此,将 Dot 作用到一个 阶张量和一个 阶张量的结果是一个 阶张量. 下面是一个例子.
外积
外积的可视化
广义内积
矩阵乘法是线性代数计算的一项基础运算. 因此,Wolfram 语言提供了 Dot 作为一个极度优化的专用函数. 然而,广义的矩阵乘法由 Inner 提供. 这使得形成乘积的两种运算可以被明确指定.
矩阵置换
许多矩阵技术依赖于对矩阵进行特殊方式的排序. 例如,有些技术试图对矩阵排序使得元素被放在对角线上,也有一些技术试图将某些元素组合到密集块上. Wolfram 语言函数 Part 非常适用于将置换作用于矩阵的行和列上.
m[[perm]] | 将置换作用在一个矩阵的行上 |
m[[All,perm]] | 将置换作用在一个矩阵的列上 |
m[[perm,perm]] | 将置换作用在一个矩阵的行与列上 |
m[[perm]]=m | 将逆置换作用在一个矩阵的行上 |
m[[All,perm]]=m | 将逆置换作用在一个矩阵的列上 |
现在矩阵将被重新排列,使得各行按照2范数递增的次序排列.(有关范数的讨论见"矩阵计算:范数".)
置换矩阵
通常,使用 Wolfram 语言函数 Part 来应用一个置换速度较快,但有时采用置换矩阵会比较方便.