矩阵是一种非常好用的数学工具, 刚开始是为了求解线性方程组而被发明出来. 随着线性代数在各个领域的广泛应用而得到巨大的发展.
因为矩阵是一种非常抽象的概念和工具, 矩阵乘法更是让不少人摸不着头脑, 作者在多年的学习和实践中有了一些自己的理解, 在此分享出来, 希望能够对大家有所帮助.
矩阵一开始是为了求解线性方程组而发明出来的工具.
方程组: { x + 2 y + z = 7 2 x − y + 3 z = 7 3 x + y + 2 z = 18 \begin{cases} x+2y+z=7\\ 2x-y+3z=7 \\3x+y+2z=18\end{cases} ⎩⎪⎨⎪⎧x+2y+z=72x−y+3z=73x+y+2z=18
以方程的个数m为行, 未知数的个数n为列, 将未知数的系数按照m行n列排列起来就形成系数矩阵: [ 1 2 1 2 − 1 3 3 1 2 ] \begin{bmatrix}1 & 2 & 1 \\2 & -1 & 3 \\3 & 1 & 2 \\\end{bmatrix} ⎣⎡1232−11132⎦⎤, 将未知数按照m行1列排列起来形成未知数矩阵: [ x y z ] \begin{bmatrix}x\\y\\z\end{bmatrix} ⎣⎡xyz⎦⎤, 也可以叫列向量 x ⃗ \vec{x} x, 将方程等号右边的常数按照m行1列排列起来形成常数矩阵: [ 7 7 8 ] \begin{bmatrix}7\\7\\8\end{bmatrix} ⎣⎡778⎦⎤, 原方程组可以写成: [ 1 2 1 2 − 1 3 3 1 2 ] [ x y z ] = x ⃗ [ 1 2 3 ] + y ⃗ [ 2 − 1 1 ] + z ⃗ [ 1 3 2 ] = [ 1 x 2 y 1 z 2 x − 1 y 3 z 3 x 1 y 2 z ] = [ 7 7 8 ] \begin{bmatrix}1 & 2 & 1 \\2 & -1 & 3 \\3 & 1 & 2 \\\end{bmatrix} \begin{bmatrix}x\\y\\z\end{bmatrix} = \vec{x}\begin{bmatrix}1 \\ 2 \\ 3\end{bmatrix} + \vec{y}\begin{bmatrix}2 \\ -1 \\ 1\end{bmatrix} + \vec{z}\begin{bmatrix}1 \\ 3 \\ 2\end{bmatrix} = \begin{bmatrix}1x & 2y & 1z \\2x & -1y & 3z \\3x & 1y & 2z \\\end{bmatrix}=\begin{bmatrix}7\\7\\8\end{bmatrix} ⎣⎡1232−11132⎦⎤⎣⎡xyz⎦⎤=x⎣⎡123⎦⎤+y⎣⎡2−11⎦⎤+z⎣⎡132⎦⎤=⎣⎡1x2x3x2y−1y1y1z3z2z⎦⎤=⎣⎡778⎦⎤.
我们也可以用 A x ⃗ = b ⃗ A\vec{x}=\vec{b} Ax=b的形式来降低理解难度, 此时可以将 A A A看作是某个函数, x ⃗ \vec{x} x看作是某个变量, b ⃗ \vec{b} b看作是某个常数. 利用比较熟悉的函数概念来理解矩阵, 可能会有比较好的收获.
我们只需要通过求出 A A A的逆矩阵就可以求出 x ⃗ \vec{x} x的值, 即方程组的解. 也可以通过矩阵的性质(线性相关性)来快速判断方程组是否有解, 有多少个解.
而求逆矩阵有很多方法, 比如常见的高斯消元法, 伴随矩阵法, 矩阵性质法(如正交矩阵的转置矩阵等于其逆矩阵), 也可以通过计算机来求解.
我们使用矩阵来研究线性方程组解的性质, 用矩阵来求解线性方程组, 相当于从某个更易于理解(虽然也不太容易理解)的角度来认识抽象的方程组, 从而更容易解决和描述某些问题.
矩阵本身只是将一堆数按照行和列排列起来, 没有具体的含义, 只是我们在具体使用时给它赋予实际的意义, 比如可以用矩阵来求解线性方程组, 可以用来表示变换, 可以用来表示空间, 等等.
我们定义行数或者列数为1的矩阵为一种特殊的矩阵: 向量. 向量其实就是一个矩阵. 只是我们将其定义为向量后可以更直观的表示一些特定的概念.
因为我们可以定义矩阵的形式和矩阵的基本运算, 只要某类问题能够满足这些条件, 我们不需要对问题有太多的理解, 就可以用矩阵来解决问题.
矩阵本身与变换, 空间, 线性等相关概念其实并没有什么必然的关系, 只是我们可以用矩阵来表示它们, 是人为赋予的意义. 没有了矩阵, 空间还是空间, 变换还是变换, 线性相关还是线性相关, 矩阵只是一种可以用来描述它们的工具而已. 就像同样是一个意思, 我们可以用不同的语言来表达, 可以用中文, 也可以用英文, 甚至于用手语. 理解这个关系是很重要的, 它会伴随我们学习和使用矩阵始终, 也有助于我们对矩阵本质的理解.
总之一句话: 矩阵没有什么实际的含义, 矩阵就是一堆按照行和列排列起来的数的集合, 是一个用来解决某些数学问题和表达某些数学概念的工具.
我们通过一个没有什么具体含义的矩阵, 居然能够解决各种具体的问题, 是不是感觉很神奇?
其实这和我们以前学过的算术(研究数和数的运算)和代数(研究带变量的数和数的运算)是一个道理. 下面举两个例子大家感受一下:
想象一下, 我可以用5+3来代表"加"这个性质, 至于说5是指代一个苹果还是一辆车, 我在求解的时候根本不关心, 只需要在得出结果后, 给结果赋予对应的意义就行了.
比如我们要计算袋子里的所有水果数量, 5+3中5代表苹果, 3代表梨子, 在计算的时候, 我们根本不用关心5和3代表什么, 只需要按照"加"的性质来得出一个数, 再给这个数赋予"袋子里的所有水果数量", 即可解决我们的问题. 是不是很方便?
向量(本文中的向量指行或者列为1的矩阵)的点乘, 代数上我们规定为:两个向量对应维度上的值相乘后的结果相加得到的一个数. 如 [ 1 2 3 ] [ 1 2 3 ] = 1 × 1 + 2 × 2 + 3 × 3 = 14 \begin{bmatrix}1&2&3\end{bmatrix}\begin{bmatrix}1\\2\\3\end{bmatrix}=1\times1+2\times2+3\times3=14 [123]⎣⎡123⎦⎤=1×1+2×2+3×3=14.
在我们给相乘的两个矩阵赋予特定含义之前, 我们居然就可以计算出一个结果14了, 只不过这个时候因为向量没有指定含义, 这个结果也是没有含义的.
比如我们要计算袋子里的水果总价, 那第一个向量代表水果的数量, 且每一个维度代表一种水果, 第二个向量代表水果的单价, 也是每个维度代表一种水果的单价. 在计算的时候我们根本不关心它们到底指代什么, 只需要最后给结果14赋予"袋子里的水果总价"即可.
比如我们要计算一个人的综合素质, 那第一个向量代表素质, 每个维度代表某种素质, 比如学习能力, 理解能力, 记忆力, 然后第二个向量代表每种能力在综合能力中所占比重. 在计算的时候我们根本不关心它们到底指代什么, 只需要最后给结果14赋予"一个人的综合素质"即可.
怎么样? 看完上面的例子, 是不是感觉和前面所说的: 向量(矩阵)本质没什么具体的含义, 当我们要解决的问题符合其性质时, 不需要关心其具体指代, 就能计算出结果. 是不是感觉很厉害?
很多教材使用几何相关的问题来帮助我们学习矩阵, 是因为矩阵可以解决很多几何相关的问题, 而几何是我们日常中再熟悉不过的概念.
矩阵本身只是一个代数工具, 本身是一种很抽象的概念, 通过熟悉的概念, 比如几何, 比如函数来学习和研究矩阵, 有助于将抽象的概念具象化, 更容易理解.
但是也给很多同学留下了一个根深蒂固的观念: 矩阵就是研究几何用的. 总是将矩阵和几何联系起来, 一旦问题脱离熟悉的几何概念, 比如很多不是那么直观的几何概念(如超过三维的几何, 线性相关, 空间的变换等), 比如大数据相关的问题等, 比如日常生活中的许多问题, 感觉就不会使用矩阵了. 这是不应该的, 使用几何来学习和理解矩阵后, 需要将它们分离开, 从更抽象的角度去理解矩阵, 才能在更多的领域或者日常生活和工作中灵活使用.
我们先从代数的角度来理解矩阵乘法, 这个角度抛开了矩阵所代表的具体意义, 只关注"乘"这个性质, 后面我们再通过使用矩阵乘法解决具体问题来进一步理解矩阵乘法.
矩阵乘法在代数上的定义很简单, 其实就是两个向量点乘的扩展, 只不过有更多维度参与计算, 其结果也不再是单独的数, 而是另一个矩阵. 两个向量点乘, 代数上其结果其实依然是一个向量, 只不过这个向量只有一个维度而已.
其直观化的定义为: 矩阵乘法就是两个满足特定条件的矩阵的进行点乘后获得一个新的矩阵, 第一个矩阵的列数需要与第二个矩阵的行数相同, 新矩阵的行数来自于第一个矩阵, 列数来自于第二个矩阵, 新矩阵的每个元素的值由元素所在位置(第几行第几列), 从第一个矩阵中取对应的行, 从第二个矩阵中取对应的列进行点乘得到.
如:
[ 1 0 0 0 1 0 0 0 1 ] [ 1 1 1 2 2 2 3 3 3 ] = [ 1 1 1 2 2 2 3 3 3 ] \begin{bmatrix}1 & 0 & 0 \\0 & 1 & 0 \\0 & 0 & 1 \\\end{bmatrix}\begin{bmatrix}1 & 1 & 1 \\2 & 2 & 2 \\3 & 3 & 3 \\\end{bmatrix}=\begin{bmatrix}1 & 1 & 1 \\2 & 2 & 2 \\3 & 3 & 3 \\\end{bmatrix} ⎣⎡100010001⎦⎤⎣⎡123123123⎦⎤=⎣⎡123123123⎦⎤
不知道上面的定义会不会让大家觉得一头雾水, 下面作者将尝试给出一些解释, 希望能解释清楚.
我们先从简单的来, 当第二个矩阵是向量时:
[ 1 0 0 0 1 0 0 0 1 ] [ 1 2 3 ] = [ 1 2 3 ] \begin{bmatrix}1 & 0 & 0 \\0 & 1 & 0 \\0 & 0 & 1 \\\end{bmatrix}\begin{bmatrix}1\\2\\3\\\end{bmatrix}=\begin{bmatrix}1\\2\\3 \\\end{bmatrix} ⎣⎡100010001⎦⎤⎣⎡123⎦⎤=⎣⎡123⎦⎤
其结果是一个3行(来自于第一个矩阵)1列(来自于第二个矩阵)的向量, 结果矩阵的每个元素, 如第二个元素的位置为(2, 1), 取第一个矩阵的第2行, 取第二个矩阵的第1列进行点乘, 得到结果2, 即: [ 0 1 0 ] [ 1 2 3 ] = 0 × 1 + 1 × 2 + 0 × 3 = 2 \begin{bmatrix}0&1&0\end{bmatrix}\begin{bmatrix}1\\2\\3\end{bmatrix}=0\times1+1\times2+0\times3=2 [010]⎣⎡123⎦⎤=0×1+1×2+0×3=2.
其实就是将第二个向量与第一个矩阵的每一个行向量分别点乘获得一个新的向量而已.
直观上感觉是: 将第二个向量, 在每个维度上, 分别被第一个矩阵对应维度上的行向量"处理"过后获得的一个新的维度值组成的向量.
这个"处理"也就是所谓的向量点乘的代数定义: 对应维度分别相乘后将各个维度的结果值相加.
如果这样理解, 我们将这种情况扩展到第二个矩阵是一个有两列的矩阵时就比较好理解了:
[ 1 0 0 0 1 0 0 0 1 ] [ 1 2 2 3 3 4 ] = [ 1 2 2 3 3 4 ] \begin{bmatrix}1 & 0 & 0 \\0 & 1 & 0 \\0 & 0 & 1 \\\end{bmatrix}\begin{bmatrix}1&2\\2&3\\3&4\end{bmatrix}=\begin{bmatrix}1&2\\2&3\\3&4\end{bmatrix} ⎣⎡100010001⎦⎤⎣⎡123234⎦⎤=⎣⎡123234⎦⎤
我们把第二个矩阵的每一个列向量的各个维度, 分别被第一个矩阵的行向量来"处理", 获得新的向量, 将这些被"处理"过后的向量排列起来就是那个新的矩阵.
因为我们需要"处理"第二个矩阵中列向量的每个维度, 所以需要保证第一个矩阵中的行向量能够"处理"每个维度, 那两个向量的维度肯定需要保持一致, 而第一个矩阵中的行向量的维度就是第一个矩阵的列数, 第二个矩阵中列向量的维度就是第二个矩阵的行数.
然后我们将情况扩展到第一个矩阵的行数比第二个矩阵的行数要少的情况, 就是所谓的对第二个矩阵降维:
[ 1 0 0 0 1 0 ] [ 1 2 2 3 3 4 ] = [ 1 2 2 3 ] \begin{bmatrix}1 & 0 & 0 \\0 & 1 & 0 \end{bmatrix}\begin{bmatrix}1&2\\2&3\\3&4\end{bmatrix}=\begin{bmatrix}1&2\\2&3\end{bmatrix} [100100]⎣⎡123234⎦⎤=[1223]
因为第一个矩阵只"处理"了第二个矩阵列向量的前面两个维度, 列向量的第三个维度信息丢失了, 由三维向量降维成了2维向量.
最后我们将情况扩展到第一个矩阵的行数比第二个矩阵的行数要多的情况, 就是所谓的对第二个矩阵升维:
[ 1 0 0 1 1 1 ] [ 1 2 2 3 ] = [ 1 2 2 3 3 5 ] \begin{bmatrix}1 & 0 \\0 & 1 \\1 & 1 \\\end{bmatrix}\begin{bmatrix}1&2\\2&3\end{bmatrix}=\begin{bmatrix}1&2\\2&3\\3&5\end{bmatrix} ⎣⎡101011⎦⎤[1223]=⎣⎡123235⎦⎤
可以理解为第一个矩阵对第二个矩阵处理过后, 附加了额外的维度信息, 使得第二个矩阵"升维"了.
综合上面的情况, 我们可以得出一个可能更直观的定义:矩阵乘法就是两个矩阵进行乘法, 第二个矩阵中每个列向量的每个维度分别由第一个矩阵的行向量"处理", 处理结果是新的列向量组成的矩阵. 获得的新的列向量可能被升维或者降维.
不知道上面的解释够不够清晰, 大家能不能理解?
矩阵乘法可以用来描述某种映射关系.
上面我们讲求解线性方程组时提到可以用 A x ⃗ = b ⃗ A\vec{x}=\vec{b} Ax=b的形式来描述方程组, 这就是使用函数的概念来理解, 大家都学过, 函数就是某种映射关系的描述. 此时, 我们可以说矩阵乘法就是一个函数, 给与一个输入值, 得到与之映射的输出值. 函数描述的是这个输入值和输出值的对应关系. 它们的关系可以是一对一, 也可以是一对多, 也可以多对多, 我们当矩阵拥有逆矩阵时, 我们可以知道他们的关系肯定是一对一的, 为什么? 因为矩阵描述的是一个输入值对应一个输出值, 这只是正向, 同一个输出值可能对应多个输入值, 而逆矩阵就是一个相反的映射, 原函数的输出值变成了反函数的输入, 原函数的输入变成了反函数的输出, 此时, 反函数的一个输入对应一个输出, 两者是一对一的, 这是反向. 正反两个方向都是一对一, 我们就说整个函数描述的关系的一对一的关系. 怎么样, 这些概念是不是很熟悉?
在 A x ⃗ = b ⃗ A\vec{x}=\vec{b} Ax=b的表示下, y ⃗ = f ( x ⃗ ) = A x ⃗ \vec{y} = f(\vec{x})=A\vec{x} y=f(x)=Ax, 输入一个已知的向量, 获得一个对应的输出向量. 如果存在反函数, 那么 x ⃗ = f ( y ⃗ ) − 1 = A − 1 y ⃗ \vec{x} = f(\vec{y})^{-1}=A^{-1}\vec{y} x=f(y)−1=A−1y, 同样也是, 输入一个已知的向量, 获得一个对应的输出向量. 在这种情况下, 我们得到的输出向量就是线性方程组的解.
所以我们可以得出, 如果矩阵存在逆矩阵, 那么线性方程组一定有唯一解, 反过来说也是一样的.
至于方程组没有解, 或者解不唯一的情况, 我们这里不做探究, 唯一需要的记住的就是: 矩阵乘法可以用来描述映射关系.
矩阵可以描述空间, 描述位置(坐标, 位置向量), 矩阵乘法可以描述空间的变换.
首先我们需要对几何的一些基本概念做简单的回顾.
"空间"一词其实是更抽象的概念, 泛指拥有一些性质的集合, 这些性质有:
而几何空间其实是抽象空间的一个具象化的理解, 其中的元素是一个个"点", “点"之间的映射关系被称之为"运动”. 而矩阵乘法就可以来描述这种"运动".
这就是为什么作者要先介绍从函数(映射)的角度来理解矩阵乘法的原因.
不管是几何空间, 点, 还是运动, 其实都只是抽象概念的具象化, 几何空间就是空间, 点就是空间中的元素, 运动就是空间中元素的映射关系. 抽象概念具象化的好处是理解起来更加直观, 降低了学习难度. 但是本质上其实都是一样的东西. 我们可以通过研究几何空间来研究空间的性质, 反过来也是一样的.
上面的线性方程组的未知数向量其实就是线性空间中元素, 也就是未知数向量可能会取的值, 我们可以通过研究矩阵乘法来将这些问题统一处理, 我们可以通过解线性方程组来获得几何空间中的一个点(二元一次方程组的解就是两个方程构建两条直线的交点), 也可以反过来通过几何空间中的一些性质来求解线性方程组(比如两条线段之间的交点就是二元一次方程组的解), 当然也可以通过矩阵和矩阵乘法来达到相同的目的, 因为他们都有一样的性质. 怎么样, 是不是很神奇, 它们居然在某种程度上保持了统一.
了解了以上的概念后, 对于以前学习的线性方程组还有空间几何相关的知识是不是有更新的理解?
既然我们需要研究的是空间中的元素和它们的对应关系, 那么肯定需要知道怎么去描述空间中的元素吧.
想想平时我们一般怎么去描述一个物件, 为了描述的更精确, 大概率会从不同的角度去描述. 这里的不同角度就是所谓的维度.
描述元素使用的维度越多, 那么描述就越准确, 如一顶帽子:
从各个维度的信息中, 我们对这顶帽子有了比较准确的认识.
空间是有维度的, 空间中的元素可以使用空间定义的维度来描述. 空间定义的维度够多, 我们就能更精确的描述元素.
那我们怎么描述元素之间的对应关系呢?
其实是先定义好元素的关系, 然后我们才能研究这种关系. 根据对关系的不同定义方法, 我们就能得到不同的空间.
比如线性代数研究的就是线性空间, 而解析几何要研究的就是欧几里得几何空间.
线性空间(其中的元素是向量), 也叫向量空间, 其的定义就是: 空间中的元素要满足两个运算, 这两个运算都是线性的, 假设线性空间为 V V V
加法: p 1 ⃗ + p 2 ⃗ = q ⃗ \vec{p_1}+\vec{p_2}=\vec{q} p1+p2=q, 其中 p 1 ⃗ , p 2 ⃗ , q ⃗ ∈ V \vec{p_1}, \vec{p_2}, \vec{q} \in V p1,p2,q∈V, 即空间中的两个向量相加一定能得到空间中的另一个向量.
数乘: k p ⃗ = q ⃗ k\vec{p}=\vec{q} kp=q, 其中, p ⃗ , q ⃗ ∈ V , k ∈ R \vec{p}, \vec{q} \in V, k \in \Reals p,q∈V,k∈R, 即空间中的向量乘以一个实数一定能得到空间中的另一个向量.
欧几里得几何空间的定义就是在线性空间的定义上加上: 空间中的元素要支持内积(点乘实现).
所以我们可以理解平时熟悉的几何空间是一个支持点积的线性空间, 而线性空间就是线性代数研究的主题.
而几何空间的基就是选择一组与空间维度数相同数量的向量来表示空间中的所有向量, 就是说只要有这组基, 我们就可以使用它们来描述空间所有的向量. 当然一般情况下我们会选择相互垂直且长度为1的向量作为空间的基, 这样的基被称为标准正交基(标准就是长度为1, 正交就是相互垂直, 点乘为0).
选择好几何空间的基之后, 我们再指定一个向量作为原点(一般选择零向量), 就构成了一个坐标系如: ( O , x ⃗ , y ⃗ , z ⃗ ) (O, \vec{x}, \vec{y}, \vec{z}) (O,x,y,z). 我们从小大学习的坐标系全名笛卡尔坐标系(Cartesian Frame or Cartesian Coordinates), 就是选择了一组基为: x ⃗ = [ 1 0 0 ] , y ⃗ = [ 0 1 0 ] , z ⃗ = [ 0 0 1 ] \vec{x}=\begin{bmatrix}1\\0\\0\end{bmatrix}, \vec{y}=\begin{bmatrix}0\\1\\0\end{bmatrix}, \vec{z}=\begin{bmatrix}0\\0\\1\end{bmatrix} x=⎣⎡100⎦⎤,y=⎣⎡010⎦⎤,z=⎣⎡001⎦⎤的坐标系. 通过坐标系我们可以描述空间中的所有向量(点). 所以空间的基实质上是描述了空间本身. 而基可以用矩阵形式来表示: [ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤, 这里的列向量对应空间的基.
这篇文章的目的在于直观化的理解矩阵和矩阵乘法, 所以更抽象的概念不打算再介绍, 有机会的话会在另外的文章中介绍.
我们目前只需要了解到这些就行了.
好了, 了解了上面两节的各种抽象概念后, 我们终于迎来了本文的重点.
显然我们选择不同的原点和不同的基后可以形成不同的坐标系, 虽然实质是形成了不同的仿射空间后决定了不同坐标系, 但是本文不想讨论仿射空间这种太抽象的概念. 所以我们就略过空间, 直接关注坐标系吧.
变换就是空间的映射, 也就是坐标系的映射. 一个坐标系中的对象(可以是点, 向量, 线, 面等)经过某种映射, 可以与另一个坐标系中的对象重合, 这就是所谓变换.
我们在这里区分开点和向量的概念, 点就是一个位置向量, 是一个束缚向量, 即初始点固定的向量, 而单独说明的向量是一个自由向量, 即初始点不固定的向量. 只要长度和方向相同, 我们就说两个向量相同, 但是还需要满足初始点相同, 我们才能说两个点是同一个点.
变换可以理解为在不同的坐标系下描述同一个几何空间下的点, 会得出不同的向量, 也可以在不同的坐标系下描述同一个向量, 会得出不同的点.
还有一个理解是:变换就是使用各自坐标系的坐标来描述对方, 这个有点不好理解, 我们下面详细说明.
通过研究我们发现, 对坐标系的变换和对基的变换等价, 也就是说我们研究变换只需要研究基的变换就可以推广到整个坐标系中所有的对象.
而基可以使用矩阵来描述, 当然也可以使用矩阵来描述变换, 这里再给大家理一下:
下面通过Unity中的一些概念来举几个例子.
我们使用矩阵 [ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤来表示世界坐标系 W W W, 通过对 W W W各种变换来映射各种不同的模型坐标系.
我们现在有一个模型坐标系 M M M: [ 2 0 0 0 2 0 0 0 2 ] \begin{bmatrix}2 & 0 & 0\\0 & 2 & 0 \\0 & 0 & 2\end{bmatrix} ⎣⎡200020002⎦⎤, 它表示的是将 W W W的三个基都在各自的轴上缩放2倍. 它可以将模型坐标系下的一个坐标映射为世界坐标下的另一个坐标.
比如现在有 M M M下的坐标 [ 1 1 1 ] \begin{bmatrix}1\\1\\1\end{bmatrix} ⎣⎡111⎦⎤, 应用变换后: [ 2 0 0 0 2 0 0 0 2 ] [ 1 1 1 ] = [ 2 2 2 ] \begin{bmatrix}2 & 0 & 0\\0 & 2 & 0 \\0 & 0 & 2\end{bmatrix} \begin{bmatrix}1\\1\\1\end{bmatrix}=\begin{bmatrix}2\\2\\2\end{bmatrix} ⎣⎡200020002⎦⎤⎣⎡111⎦⎤=⎣⎡222⎦⎤. 也就是说描述模型空间的矩阵 M M M右乘一个模型空间中下的点后可以得到一个世界空间下的点.
这是怎么做到的呢? 下面我们一起来剖析这个过程.
首先我们的目标是将模型坐标系的一个点变换到世界坐标系下, 那我们肯定需要知道模型坐标系和需要变换的点. 但是单纯的知道模型坐标系是没有什么用的, 因为就模型坐标系自身来看, 它基本上都是 [ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤, 我们其实更关注的是模型坐标系和世界坐标系的联系, 而它们的联系其实就是: 如何使用世界坐标来描述模型坐标系. 而我们可以使用一个矩阵来描述这个关系. 而需要变换的点肯定是模型坐标系下的某个坐标.
通过对世界坐标系的基向量作各种变换, 可以得到一个新的坐标系, 这个坐标系与目标模型坐标系重合. 而对世界坐标系的基向量作各种变换可以通过矩阵来描述.
[ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤代表世界坐标系, : x ⃗ = [ 1 0 0 ] , y ⃗ = [ 0 1 0 ] , z ⃗ = [ 0 0 1 ] \vec{x}=\begin{bmatrix}1\\0\\0\end{bmatrix}, \vec{y}=\begin{bmatrix}0\\1\\0\end{bmatrix}, \vec{z}=\begin{bmatrix}0\\0\\1\end{bmatrix} x=⎣⎡100⎦⎤,y=⎣⎡010⎦⎤,z=⎣⎡001⎦⎤分别是基向量, 我们分别对三个向量作缩放值为2的变换(其实就是数乘2)则基向量变成了: x ⃗ ′ = [ 2 0 0 ] , y ⃗ ′ = [ 0 2 0 ] , z ⃗ ′ = [ 0 0 2 ] \vec{x}'=\begin{bmatrix}2\\0\\0\end{bmatrix}, \vec{y}'=\begin{bmatrix}0\\2\\0\end{bmatrix}, \vec{z}'=\begin{bmatrix}0\\0\\2\end{bmatrix} x′=⎣⎡200⎦⎤,y′=⎣⎡020⎦⎤,z′=⎣⎡002⎦⎤, 用矩阵来描述这个过程就是 M : [ 2 0 0 0 2 0 0 0 2 ] M:\begin{bmatrix}2 & 0 & 0\\0 & 2 & 0 \\0 & 0 & 2\end{bmatrix} M:⎣⎡200020002⎦⎤, 所以 M M M既可以用来描述模型坐标系本身(描述一个空间), 又可以描述将世界坐标系变换到模型坐标系的过程(描述一个运动过程). 矩阵既可以描述一个静态的概念, 也可以描述一个动态的过程, 是不是很神奇?
假设我们需要变换的模型坐标系下的点为 [ 1 1 1 ] \begin{bmatrix}1\\1\\1\end{bmatrix} ⎣⎡111⎦⎤, 则这个点对应世界坐标系下的点为: [ 2 0 0 0 2 0 0 0 2 ] [ 1 1 1 ] = [ 2 2 2 ] \begin{bmatrix}2 & 0 & 0\\0 & 2 & 0 \\0 & 0 & 2\end{bmatrix} \begin{bmatrix}1\\1\\1\end{bmatrix}=\begin{bmatrix}2\\2\\2\end{bmatrix} ⎣⎡200020002⎦⎤⎣⎡111⎦⎤=⎣⎡222⎦⎤, 就是说几何空间下的同一个点, 在不同的坐标系下的向量是不同的. 反过来说就是, 同一个向量在不同的坐标系下对应不同的点.
想象一下, 我么是不是可以站在一个上帝视角看待两个坐标系: 世界坐标膨胀2倍就是模型坐标系. 而矩阵就是用来描述膨胀2倍这个过程, 也是描述膨胀2倍后得到的模型坐标系本身.
下面我们来分析逆过程.
同理, 首先我们的目标是将世界坐标系的一个点变换到模型坐标系下, 那我们肯定需要知道世界坐标系和需要变换的点. 但是单纯的知道世界坐标系是没有什么用的, 因为就世界坐标系自身来看, 它基本上都是 [ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤, 我们其实更关注的是世界坐标系和模型坐标系的联系, 而它们的联系其实就是: 如何使用模型坐标来描述世界坐标系. 而我们可以使用一个矩阵来描述这个关系. 而需要变换的点肯定是世界坐标系下的某个坐标.
通过对模型坐标系的基向量作各种变换, 可以得到一个新的坐标系, 这个坐标系与目标世界坐标系重合. 而对模型坐标系的基向量作各种变换可以通过矩阵来描述.
[ 1 0 0 0 1 0 0 0 1 ] \begin{bmatrix}1 & 0 & 0\\0 & 1 & 0 \\0 & 0 & 1\end{bmatrix} ⎣⎡100010001⎦⎤代表模型坐标系, : x ⃗ = [ 1 0 0 ] , y ⃗ = [ 0 1 0 ] , z ⃗ = [ 0 0 1 ] \vec{x}=\begin{bmatrix}1\\0\\0\end{bmatrix}, \vec{y}=\begin{bmatrix}0\\1\\0\end{bmatrix}, \vec{z}=\begin{bmatrix}0\\0\\1\end{bmatrix} x=⎣⎡100⎦⎤,y=⎣⎡010⎦⎤,z=⎣⎡001⎦⎤分别是基向量, 我们分别对三个向量作缩放值为0.5的变换(其实就是数乘0.5)则基向量变成了: x ⃗ ′ = [ 0.5 0 0 ] , y ⃗ ′ = [ 0 0.5 0 ] , z ⃗ ′ = [ 0 0 0.5 ] \vec{x}'=\begin{bmatrix}0.5\\0\\0\end{bmatrix}, \vec{y}'=\begin{bmatrix}0\\0.5\\0\end{bmatrix}, \vec{z}'=\begin{bmatrix}0\\0\\0.5\end{bmatrix} x′=⎣⎡0.500⎦⎤,y′=⎣⎡00.50⎦⎤,z′=⎣⎡000.5⎦⎤, 用矩阵来描述这个过程就是 M − 1 : [ 0.5 0 0 0 0.5 0 0 0 0.5 ] M^{-1}:\begin{bmatrix}0.5 & 0 & 0\\0 & 0.5 & 0 \\0 & 0 & 0.5\end{bmatrix} M−1:⎣⎡0.50000.50000.5⎦⎤. 而 M − 1 M^{-1} M−1是 M M M的逆矩阵.
假设我们需要变换的世界坐标系下的点为 [ 2 2 2 ] \begin{bmatrix}2\\2\\2\end{bmatrix} ⎣⎡222⎦⎤, 则这个点对应模型坐标系下的点为: [ 0.5 0 0 0 0.5 0 0 0 0.5 ] [ 2 2 2 ] = [ 1 1 1 ] \begin{bmatrix}0.5 & 0 & 0\\0 & 0.5 & 0 \\0 & 0 & 0.5\end{bmatrix} \begin{bmatrix}2\\2\\2\end{bmatrix}=\begin{bmatrix}1\\1\\1\end{bmatrix} ⎣⎡0.50000.50000.5⎦⎤⎣⎡222⎦⎤=⎣⎡111⎦⎤.
这里作者故意按照非常类似的表达来描述, 就是想表明两个坐标系变换的实质其实很简单: 坐标系变换就是使用对方的坐标系来描述自身的坐标系, 可以使用矩阵来描述这个变换. 也可以假设有一个小人站在第一个坐标系下, 用这个坐标系的语言来描述第二个坐标系, 我们可以用**相同的方式(矩阵)**来描述另一个第二个坐标系的任意对象(矩阵乘法).
看了上面的介绍, 大家可能会有疑问, 就是说一个矩阵为什么能够描述动态的变换, 同时还能描述静态的空间本身呢? 其实它们之间存在内在的联系.
它们内在的联系其实就是空间的本质: 空间是运动的, 运动性决定空间的性质. 而矩阵是一个代数工具, 可以描述空间元素的关系.
这个话有点抽象, 我们回想下上面对空间的介绍: 空间=要研究的元素集合+元素之间的关系(运动, 也被称为空间的结构). 而元素之间的关系决定空间的性质, 即这个关系可以代表空间本身, 我们说关系确定了, 空间就确定了.
元素之间的关系可以称为结构, 映射, 函数, 也可以称为运动, 它们在高度抽象下是统一的, 都是代表空间元素之间的关系, 代表空间的结构, 也就是代表空间本身.
当然这里的运动是瞬时运动, 更多的被称为跃迁运动, 是立即完成的.
所以在矩阵右乘一个向量的下面的说法都是等价的:
那么矩阵右乘另一个矩阵代表什么呢?
在代数上, 矩阵右乘另一个矩阵, 我们可以看做是第二个矩阵的每个列分别被第一个矩阵右乘后形成的新的矩阵.
在几何上, 矩阵右乘另一个矩阵, 比如我们有一个世界坐标系 W W W, 而有两个模型坐标系 M 1 , M 2 M_1, M_2 M1,M2, 有一个 M 2 M_2 M2下的点 p ⃗ \vec{p} p, 将 p ⃗ \vec{p} p变换到 W W W中可以表示成: M 1 M 2 p ⃗ = [ 3 0 0 0 3 0 0 0 3 ] [ 2 0 0 0 2 0 0 0 2 ] [ 1 1 1 ] M_1 M_2 \vec{p}=\begin{bmatrix}3 & 0 & 0\\0 & 3 & 0 \\0 & 0 & 3\end{bmatrix}\begin{bmatrix}2 & 0 & 0\\0 & 2 & 0 \\0 & 0 & 2\end{bmatrix}\begin{bmatrix}1\\1\\1\end{bmatrix} M1M2p=⎣⎡300030003⎦⎤⎣⎡200020002⎦⎤⎣⎡111⎦⎤, 我们可以看做
其它几种情况应该都比较好理解, 两个变换结合后形成的新的变换是什么鬼? 产生了新的坐标系? 可是原来的向量不是第二个坐标系的向量么? 为什么可以这么理解?
我们的目标是将 M 2 M_2 M2 下的点 p ⃗ \vec{p} p 变换到 W W W, 但是 M 2 M_2 M2是用 M 1 M_1 M1的坐标来描述的, 我们缺乏 W W W和 M 2 M_2 M2的关系描述, 而 M 1 M_1 M1是将 M 1 M_1 M1下的点变换到 W W W的描述, M 2 M_2 M2是将 M 2 M_2 M2下的点变换到 M 1 M_1 M1的描述, M 1 M 2 = M 3 M_1 M_2=M_3 M1M2=M3是将使用 M 1 M_1 M1坐标表示的 M 2 M_2 M2变换到 W W W的描述. 即 M 3 M_3 M3就是使用 W W W坐标描述 M 2 M_2 M2的矩阵. 由此可见变换具有传递性. 而 p ⃗ \vec{p} p依然是 M 2 M_2 M2坐标系下的点.
可能有些绕, 这里再给大家梳理一下: 由于我们缺乏 W W W和 M 2 M_2 M2的关系描述, 而 M 2 M_2 M2是用 M 1 M_1 M1的坐标来描述的, 所以我们需要借助 M 1 M_1 M1转换其中的关系, 将 M 2 M_2 M2代表的坐标系使用 W W W来描述.
从矩阵的由来到矩阵的本质到空间的概念最后到坐标的变换, 我们尝试从直观的角度来认识矩阵和矩阵乘法.
在作者看来, 矩阵本质上就是一个代数工具, 并没有具体的意义, 我们发明这种工具是为了在研究具体领域问题时更方便, 在研究不同领域的问题矩阵有不同的意义. 只是我们将它们在代数层次上统一了.
比如计算机根本就不理解, 也不关心什么是空间, 什么是变换, 它只关心实际的代数运算.
我们将具体的问题抽象为代数运算, 最后给代数运算的结果赋予我们想要的实际意义.
本文尝试对矩阵和矩阵乘法进行直观化的解释, 不追求严谨的数学证明和概念, 旨在从相对比较容易理解的角度来阐释矩阵和矩阵乘法, 但是有些抽象概念还是不够直观.
作者也在不断学习, 不断理解并在这个过程中充分领略数学的美.
由于作者不是专业的数学研究者, 所以理解和解释不一定正确, 只是希望将自己的理解分享出来供大家参考和理解, 希望能对大家学习矩阵和矩阵乘法的过程中提供一点帮助.