在前四节中,我们学习了两种表示线性方程组的方法, 即线性方程组和向量方程,在本节将给出线性方程组的第三种表示方法:矩阵方程,并使用C++实现相应的表示。
线性代数部分
考虑下方的向量方程:
x1232+x2435+x3452+x4512=744x_1\begin{bmatrix} 2 \\ 3 \\ 2\end{bmatrix}+x_2 \begin{bmatrix}4\\ 3 \\ 5 \end{bmatrix} + x_3\begin{bmatrix} 4 \\ 5 \\ 2\end{bmatrix}+x_4\begin{bmatrix} 5 \\ 1 \\ 2\end{bmatrix}= \begin{bmatrix} 7 \\ 4 \\4\end{bmatrix}x1 232 +x2 435 +x3 452 +x4 512 = 744
求解该向量方程可以说就是以系数矩阵中的每一个列向量为基本元素进行线性组合,要求出目标向量,在几何上,如果目标向量位于系数向量线性组合所张成的Span{x1,x2,x3}Span\{{\boldsymbol{x_1}, \boldsymbol{x_2},\boldsymbol{x_3}}\}Span{x1,x2,x3}空间中,那么向量方程有解,我们可以将上方的向量方程化为下方的形式:
244533512522x1x2x3x4=744 \begin{bmatrix} 2 & 4 & 4 & 5\\ 3 & 3 & 5 & 1\\ 2 & 5 & 2 & 2 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4 \end{bmatrix} = \begin{bmatrix} 7\\ 4\\ 4\\ \end{bmatrix} 232435452512 x1x2x3x4 = 744
这就是一个矩阵方程,矩阵方程的标准定义是:若A\boldsymbol{A}A是mmm行nnn列的矩阵,其按列表示为:a1,a2,a3...an\boldsymbol{a_1}, \boldsymbol{a_2},\boldsymbol{a_3}...\boldsymbol{a_n}a1,a2,a3...an,x\boldsymbol{x}x是Rn\mathbb{R}^nRn中的向量,那么A\boldsymbol{A}A与向量x\boldsymbol{x}x的积就是A\boldsymbol{A}A中的列向量以x\boldsymbol{x}x中各个元素为权的线性组合,记为Ax\boldsymbol{A}\boldsymbol{x}Ax ,比如:
A=243325,x=x1x2 \boldsymbol{A}= \begin{bmatrix} 2 & 4 \\ 3 & 3 \\ 2 & 5 \end{bmatrix} , \boldsymbol{x}= \begin{bmatrix} x_1 \\ x_2 \\ \end{bmatrix} A= 232435 ,x=x1x2
那么
Ax=243325x1x2=x1232+x2435 \boldsymbol{A}\boldsymbol{x}= \begin{bmatrix} 2 & 4 \\ 3 & 3 \\ 2 & 5 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ \end{bmatrix} = x_1\begin{bmatrix} 2 \\ 3 \\ 2\end{bmatrix}+x_2 \begin{bmatrix}4\\ 3 \\ 5 \end{bmatrix} Ax= 232435 x1x2=x1 232 +x2 435
要注意的是:x\boldsymbol{x}x的行数必须等于A\boldsymbol{A}A的列数,否则Ax\boldsymbol{A}\boldsymbol{x}Ax无意义 。
显然,矩阵方程就像是把向量方程"压缩"了一样,是一种线性组合的压缩形式,它们两者是完全等价的,又由于向量方程与线性方程组是完全等价的,因此可以得出:线性方程组与向量方程与矩阵方程是完全等价的,是同一事物的不同表示方式 ,在上一小节说明过,线性方程组的形式是更偏向代数的表示方法,而向量方程是更偏向几何的表示方法,那么矩阵方程呢?以笔者目前的level来看,矩阵方程的主要意义就是定义出了向量乘积的含义,其本身并没有明确的偏向几何或代数,但是从编程的视角来看,矩阵方程明显非常适合使用程序来表示。所谓的压缩感在下方的例子中有明显的体现:
5232+3435+6452+5512=2445335125225365=7159475\begin{bmatrix} 2 \\ 3 \\ 2\end{bmatrix}+3 \begin{bmatrix}4\\ 3 \\ 5 \end{bmatrix} + 6\begin{bmatrix} 4 \\ 5 \\ 2\end{bmatrix}+5\begin{bmatrix} 5 \\ 1 \\ 2\end{bmatrix} = \begin{bmatrix} 2 & 4 & 4 & 5\\ 3 & 3 & 5 & 1\\ 2 & 5 & 2 & 2 \end{bmatrix} \begin{bmatrix} 5\\ 3\\ 6\\ 5 \end{bmatrix} = \begin{bmatrix} 71\\ 59\\ 47\\ \end{bmatrix} 5 232 +3 435 +6 452 +5 512 = 232435452512 5365 = 715947
同样的,我们需要判断解的情况,由线性方程组,向量方程与矩阵方程之间的等价性,我们可以得出一条定理:
| 定理 |
|---|
| 若A\boldsymbol{A}A是mmm行nnn列的矩阵,其各列为a1,a2,a3...an\boldsymbol{a_1}, \boldsymbol{a_2},\boldsymbol{a_3}...\boldsymbol{a_n}a1,a2,a3...an,向量x\boldsymbol{x}x是Rn\mathbb{R}^nRn中的向量,向量b\boldsymbol{b}b是Rm\mathbb{R}^mRm中的向量,那么 |
| 矩阵方程:Ax=b\boldsymbol{A}\boldsymbol{x}=\boldsymbol{b}Ax=b |
| 向量方程:x1a1+x2a2+x3a3...+xnan=bx_1\boldsymbol{a_1}+ x_2\boldsymbol{a_2}+x_3\boldsymbol{a_3}...+x_n\boldsymbol{a_n} = \boldsymbol{b}x1a1+x2a2+x3a3...+xnan=b |
| 以a1,a2,a3...an,b\\boldsymbol{a_1}, \\boldsymbol{a_2},\\boldsymbol{a_3}...\\boldsymbol{a_n}, \\boldsymbol{b}a1,a2,a3...an,b为增广矩阵的线性方程组 |
| 这三者有完全相同的解集 |
容易得出:如果如果向量b\boldsymbol{b}b是向量A\boldsymbol{A}A中各列的线性组合,那么线性方程组相容,否则不相容 ,对于矩阵方程,有一类比较特殊的问题,那就是已知矩阵A\boldsymbol{A}A是mmm行nnn列的矩阵,问该矩阵各列的线性组合是否能够组合出Rm\mathbb{R}^mRm中任意向量b\boldsymbol{b}b,换句话说就是Span{a1,a2....an}Span\{{\boldsymbol{a_1}, \boldsymbol{a_2}....\boldsymbol{a_n}}\}Span{a1,a2....an}能否张成完整的mmm维空间,比如下方的例子:
A=116−1121314,b=b1b2b3 \boldsymbol{A}= \begin{bmatrix} 1 & 1 & 6\\ -1 & 1 & 2 \\ 1 & 3 & 14 \end{bmatrix} , \boldsymbol{b}= \begin{bmatrix} b_1 \\ b_2 \\ b_3 \end{bmatrix} A= 1−111136214 ,b= b1b2b3
将其组合成增广矩阵得出:
116b1−112b21314b3 \left \\begin{array}{ccc\|c} 1 \& 1 \& 6 \& b_1\\\\ -1 \& 1 \& 2 \& b_2\\\\ 1 \& 3 \& 14 \& b_3 \\end{array} \\right 1−111136214b1b2b3
如果在b1,b2,b3b_1, b_2, b_3b1,b2,b3能够为任意值,没有任何约束的情况下,向量A\boldsymbol{A}A还是能够表示出所有的b\boldsymbol{b}b,那么就说明矩阵A\boldsymbol{A}A各列的线性组合能够张成整个三维空间,因为b\boldsymbol{b}b在没有约束的情况下表示的就是三维空间中的任意一条向量,如果一组向量的线性组合能够表示出某一个维度中任意一条向量,那么就说该组向量的线性组合能够表示出整个维度,我们将上方的矩阵合为增广矩阵, 然后化为行化简矩阵,得出:
102(b1−b2)/2014(b1+b2)/2000b3−b2−2b1 \left \\begin{array}{ccc\|c} 1 \& 0 \& 2 \& (b_1-b_2)/2\\\\ 0 \& 1 \& 4 \& (b_1 + b_2)/2\\\\ 0 \& 0 \& 0 \& b_3-b_2-2b_1 \\end{array} \\right 100010240(b1−b2)/2(b1+b2)/2b3−b2−2b1
注意到最后一行的最后一个元素:b3−b2−2b1b_3-b_2-2b_1b3−b2−2b1,若其值非零,那么就是增广矩阵的最后一列是主元列,线性方程组无解,若其值为零,那么线性方程组有解,在有解的情况下,注意到存在自由变量,因此若b3−b2−2b1=0b_3-b_2-2b_1=0b3−b2−2b1=0,那么线性方程组存在无数解,此时显然向量b\boldsymbol{b}b是存在约束的(函数关系本身就是一种约束),这意味着矩阵A\boldsymbol{A}A各列的线性组合无法张成整个三维空间,由于在向量方程视角中的解集就是系数向量线性组合能够表示的所有向量,而上方的线性方程组如果要存在解,那么必须满足b3−b2−2b1=0b_3-b_2-2b_1=0b3−b2−2b1=0,因此若上方线性方程组有集,那么系数向量线性组合出来的任意向量必然落入b3−b2−2b1=0b_3-b_2-2b_1=0b3−b2−2b1=0中,显然b3−b2−2b1=0b_3-b_2-2b_1=0b3−b2−2b1=0表示一个平面,因此上方系数向量的线性组合就能够得出一个平面,且该平面是b3−b2−2b1=0b_3-b_2-2b_1=0b3−b2−2b1=0表示出来的平面。从上方的例子中我们发现,若系数矩阵的行阶梯型矩阵存在全零行,那么其列向量的线性组合无法表示出完整的行维度,比如下方系数矩阵的行阶梯型矩阵:
134012002000 \left \\begin{array}{ccc} 1 \& 3 \& 4\\\\ 0 \& 1 \& 2\\\\ 0 \& 0 \& 2\\\\ 0 \& 0 \& 0 \\end{array} \\right 100031004220
此时该行阶梯型矩阵存在四行,完整的行维度就是四维,但是最后一行是零行,因此列向量的线性组合无法表示出完整的四维,只能表示出四维中的一个三维,容易得出,1.对于任意矩阵,如果行数大于列数,那么其化为的行阶梯型矩阵就必然存在零行,因此列向量必然无法表示出完整的行维度,2.如果行数小于列数,那么列向量有可能可以表示出完整的行维度,比如下方行阶梯矩阵:
100000\] \\left\[ \\begin{array}{ccc} 1 \& 0 \& 0\\\\ 0 \& 0 \& 0 \\end{array} \\right\] \[100000
此时显然行数小于列数,但是列向量无法表示出完整的行维度,3.列向量线性组合张成的维度数等于行阶梯型矩阵中非零行的行数。标准的表述如下:
| 定理 |
|---|
| 对于任意mmm行nnn列的矩阵A\boldsymbol{A}A,下列所有命题是等价的,也就是说它们同时成立或不成立 |
| 1.对Rm\mathbb{R}^mRm中的任意向量b\boldsymbol{b}b,方程Ax=b\boldsymbol{A}\boldsymbol{x} = \boldsymbol{b}Ax=b有解 |
| 2.Rm\mathbb{R}^mRm中的任意向量b\boldsymbol{b}b都可以使用矩阵A\boldsymbol{A}A中列向量的线性组合表示 |
| 3.矩阵A\boldsymbol{A}A的各列生成Rm\mathbb{R}^mRm |
| 4.矩阵A\boldsymbol{A}A的行阶梯型表示中不存在零行,即A\boldsymbol{A}A在每一行都存在主元 |
利用矩阵方程中定义的向量乘矩阵的含义,我们能够实现定向的求出矩阵方程中某一个条目的线性方程的表示,比如下方的矩阵方程:
244533512522x1x2x3x4=744 \begin{bmatrix} 2 & 4 & 4 & 5\\ 3 & 3 & 5 & 1\\ 2 & 5 & 2 & 2 \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4 \end{bmatrix} = \begin{bmatrix} 7\\ 4\\ 4\\ \end{bmatrix} 232435452512 x1x2x3x4 = 744
我们希望单独求出第二个线性方程的表示,那么就只需要:
3351x1x2x3x4=3x1+3x2+5x3+x4 \begin{bmatrix} & & & \\ 3 & 3 & 5 & 1\\ & & & \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4 \end{bmatrix} = \begin{bmatrix} \\ 3x_1 + 3x_2 + 5x_3 + x_4\\ \\ \end{bmatrix} 3351 x1x2x3x4 = 3x1+3x2+5x3+x4
由此得出:若乘积Ax\boldsymbol{A}\boldsymbol{x}Ax有定义,那么Ax\boldsymbol{A}\boldsymbol{x}Ax的第iii行元素等于A\boldsymbol{A}A的第iii行与x\boldsymbol{x}x中对应元素的乘积之和 。
最后给出两条重要的矩阵方程运算性质:
| 运算性质 |
|---|
| 若A\boldsymbol{A}A是m∗nm*nm∗n的矩阵,u,v\boldsymbol{u},\boldsymbol{v}u,v是Rn\mathbb{R}^nRn中的任意向量,ccc是任意标量,那么: |
| 1.A(u+v)=Au+Av\boldsymbol{A}(\boldsymbol{u} +\boldsymbol{v}) = \boldsymbol{A}\boldsymbol{u}+\boldsymbol{A}\boldsymbol{v}A(u+v)=Au+Av |
| 2.A(cu)=c(Au)\boldsymbol{A}(c\boldsymbol{u}) = c(\boldsymbol{A}\boldsymbol{u})A(cu)=c(Au) |
笔者的奇思妙想(不保证正确性)
1.向量,线段与有向线段
从笔者学习了向量加法后,就一直对向量加法的几何含义有疑惑,在上一节中说向量加法的平移效果,但是现在看来那个说法是错误的,因为向量的本质是即有大小,又有方向的量,确定向量的要素就是大小与方向 ,没有固定的端点,这意味着向量本身不存在平移这个概念,甚至不能说向量是平移不变的,而是说向量压根就不存在平移,向量加法本质上没有任何几何含义,就是按照平行四边形法则得出了一个新的向量。但是线段和有向线段是存在平移的概念的,它们都属于平面几何图形,从定义上来看,线段是直线上两点间的有限部分,确定线段的要素是端点与长度 ,这意味着端点不同,线段也会不同,就算两条线段是长度相等且平行的,它们也是不同的线段,而有向线段的标准定义是规定了起点和终点的线段,确定有向线段的要素是起点,方向,长度 ,这意味着就算两条有向线段完全平行,长度和方向都相同,但是只要它们的起点不同,就是不同的有向线段,容易发现,向量其实就是更自由的有向线段,失去起点的约束就意味着只要两条向量的方向和长度相同,那么它们就是严格等价的,或者说在空间上,它们就是同一条向量。
2.向量是描述几何变化的一门语言
笔者最终得出的结论是,向量不是几何图形,更不是几何体,向量就是向量,这意味着向量本身不存在任何几何变化,比如旋转,平移,轴对称,伸缩在向量中都是不存在的,在几何直观上,我们似乎可旋转或是伸缩一个向量,但是要知道,那得出来的是一个新的向量,与原向量没有半毛钱关系,那么向量的在维度空间中到底有什么意义?笔者从编程的视角出发,得出的最终结论就是:向量是描述与操作几何变化的一门语言 ,向量所具备的几何性质就是描述与操作 ,最基本的,向量加法就是对点平移的描述,比如考虑点(1, 1),使用向量(3, 0)作用于该点,得出来平移后的点就是(4, 1),如下图:
点是空间的基本单位,这意味着如果向量能够描述出一个点的平移,那么向量就能够描述出线,面,体的平移,如图:
这在几何上是非常直观且合理的,但是我们还得给出相应的代数表示,其实也并不难,根据高中的几何学知识,我们就能够使用函数来表示出大部分规则几何体中的任意一个点了,要表示不规则几何体中是所有点就必须使用到微积分,但是无论如何,我们总有方法表示出一个几何体中任意的一个点,既然如此,那么就只需要让向量作用于该几何体的所有的点,就相当于作用于整个几何体了。以线段为例,对于一条端点为(1,1),(3,2)(1, 1),(3, 2)(1,1),(3,2)的线段,我们可以使用参数方程进行表示:
{x=1+2ty=1+t0<=t<=1 \begin{cases} x = 1 + 2t\\ y = 1 + t\\ 0 <= t <= 1 \end{cases} ⎩ ⎨ ⎧x=1+2ty=1+t0<=t<=1
其几何表示如下:
显然我们可以将参数方程封装成向量的形式:(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t),要注意的是此处仅仅只是使用向量的方式进行表示,并不是真的把线段变成了向量,然后我们希望将该线段向右平移两个单位,利用向量进行描述,显然我们需要使用向量(2,0)(2, 0)(2,0)作用于上方线段的所有点,而所有点的表示就是(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t),因此直接让(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)和(2,0)(2, 0)(2,0)相加,要重点注意的时此处不是向量的相加,因为(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)不是向量,是对线段参数方程的封装,其含义是线段上的所有点,因此(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)和(2,0)(2, 0)(2,0)相加的含义是:将线段上的所有点都使用向量(2,0)(2, 0)(2,0)进行操作 ,得出的结果就是(3+2t,1+t)(3+2t, 1+t)(3+2t,1+t),端点是(3,1)(3, 1)(3,1)和(5,2)(5, 2)(5,2),使用几何进行验证:
又或者我们希望将线段长度翻倍,那么使用向量数乘对(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)进行操作,同样的,我们不应该真的把(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)真当成向量了,这仅仅只是使用向量形式表示出来的伪向量 ,其本质上是一条线段的参数方程表示,翻倍操作为:2(1+2t,1+t)=(2+4t,2+2t)2(1+2t, 1+t) = (2+4t, 2+2t)2(1+2t,1+t)=(2+4t,2+2t),端点为:(2,2),(6,4)(2, 2),(6, 4)(2,2),(6,4),使用几何进行验证:
利用平行四边形的性质,容易证明结果正确(此处是相对于整个坐标轴进行缩放的,因此线段两端端点都等比例变化了),当我们把向量当成描述与操作几何变化的语言时,对于向量的几何意义,代数意义和运算法则都成功的进行了合理且优雅的解释,这里要重点区分的是在某些情况下,向量形式表示出来的不一定就真的是向量了,还可能是点,或是某个几何图形/几何体的参数方程,什么时候表示向量,什么时候不表示向量就是要视情况而定的了。此处也算是解答了笔者高中时的一个疑惑:为什么要使用参数方程表示几何图形与几何体 ,显然参数方程天生就是为向量表示而准备的,利用参数方程,可以无缝的让几何变化衔接上线性代数中的所有知识,放到编程中,这就叫统一了函数接口。
3.矩阵是封装向量语句而得出来的几何变化函数
从编程的视角来理解向量产生了神奇的效果,下面来看看编程视角中的矩阵是什么样子的。首先显而易见的是,矩阵可以视为一组向量的集合,既然向量是描述与操作几何变化的一门语言,那么矩阵就是封装了基本向量语法的一个函数,对于矩阵方程Ax\boldsymbol{A}\boldsymbol{x}Ax,我们不把矩阵视为A\boldsymbol{A}A多个列向量,不把矩阵方程Ax\boldsymbol{A}\boldsymbol{x}Ax视为列向量的线性组合,而是把A\boldsymbol{A}A中的每一个列向量都视为对x\boldsymbol{x}x的一次几何变化操作,把整个矩阵A\boldsymbol{A}A视为一个黑盒函数,该函数的效果就是投入一个使用向量形式表示的几何元素,返回一个新的几何元素,比如对于几何元素(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t),我们希望实现一个函数,让该几何元素先向左平移一个单位,再在保持下侧端点固定的情况下将长度翻倍,要求出变化矩阵,显然我们可以得出最终线段的端点是(0,2),(4,3)(0, 2), (4, 3)(0,2),(4,3),参数方程为:
{x=4ty=2+t0<=t<=1 \begin{cases} x = 4t\\ y = 2 + t\\ 0 <= t <= 1 \end{cases} ⎩ ⎨ ⎧x=4ty=2+t0<=t<=1
向量表示为(4t,2+t)(4t, 2+t)(4t,2+t)
通过已知元素来反向推出未知矩阵,即:
a11a12a21a22\]\[1+2t1+t\]=\[4t2+t\] \\begin{bmatrix} a_{11} \& a_{12}\\\\ a_{21} \& a_{22}\\\\ \\end{bmatrix} \\begin{bmatrix} 1+2t\\\\ 1+t\\\\ \\end{bmatrix} = \\begin{bmatrix} 4t\\\\ 2+t\\\\ \\end{bmatrix} \[a11a21a12a22\]\[1+2t1+t\]=\[4t2+t
化为线性方程组,得出:
{a11+a12+(2a11+a12)t=4ta21+a22+(2a21+a22)t=2+t \begin{cases} a_{11} + a_{12} + (2a_{11}+a_{12})t = 4t\\ a_{21} + a_{22} + (2a_{21}+a_{22})t=2+t\\ \end{cases} {a11+a12+(2a11+a12)t=4ta21+a22+(2a21+a22)t=2+t
从形式上来看,显然需要满足:
{a11+a12+0a21+0a22=02a11+a12+0a21+0a22=40a11+0a12+2a21+a22=10a11+0a12+a21+a22=2 \begin{cases} a_{11} + a_{12} + 0a_{21} + 0a_{22} = 0\\ 2a_{11}+a_{12}+0a_{21}+0a_{22}=4\\ 0a_{11}+0a_{12}+2a_{21}+a_{22}=1\\ 0a_{11}+0a_{12}+a_{21}+a_{22}=2 \end{cases} ⎩ ⎨ ⎧a11+a12+0a21+0a22=02a11+a12+0a21+0a22=40a11+0a12+2a21+a22=10a11+0a12+a21+a22=2
化为增广矩阵,得出:
11000210040021100112 \left \\begin{array}{cccc\|c} 1\&1\&0\&0\&0\\\\ 2\&1\&0\&0\&4\\\\ 0\&0\&2\&1\&1\\\\ 0\&0\&1\&1\&2 \\end{array} \\right 12001100002100110412
化为行化简矩阵,得出:
100040100−40010−100013 \left \\begin{array}{cccc\|c} 1\&0\&0\&0\&4\\\\ 0\&1\&0\&0\&-4\\\\ 0\&0\&1\&0\&-1\\\\ 0\&0\&0\&1\&3 \\end{array} \\right 10000100001000014−4−13
显线性方程组相容,不存在自由变量,因此只有唯一解,回代到线性方程组中,得出:
{a11=4a12=−4a21=−1a22=3 \begin{cases} a_{11}=4\\ a_{12}=-4\\ a_{21}=-1\\ a_{22}=3 \end{cases} ⎩ ⎨ ⎧a11=4a12=−4a21=−1a22=3
经笔者验算,结果正确,由此得出变化矩阵A\boldsymbol{A}A为:
4−4−13\] \\left\[ \\begin{array}{c} 4\&-4\&\\\\ -1\&3\&\\\\ \\end{array} \\right\] \[4−1−43
经笔者验算,该矩阵能够将伪向量(1+2t,1+t)(1+2t, 1+t)(1+2t,1+t)变化为伪向量(4t,2+t)(4t, 2+t)(4t,2+t)。
在将向量理解为描述和处理几何变化的语言 ,将矩阵理解为封装向量语句形成的几何变化函数 后,身为程序员,我们就可以使用我们最擅长的角度来理解线性代数了,因为线性代数的核心就是向量与矩阵,我们可以将线性代数的数学性质理解成向量语言的基本语法,将复杂的矩阵变化理解成函数的编写,链式调用,递归,模板...一下子就变的亲切了。
3.全零行与全零列在矩阵中的含义
在矩阵中,最特殊的行与列就是全零行和全零列了,身为程序员,我们应该对这些"边界情况"有敏锐的直觉,因此下面就来详细的分析一下全零行与全零列在矩阵中的代数意义与几何变化意义,先来分析全零行,考虑下方矩阵:
134412000 \left \\begin{array}{ccc} 1 \& 3 \& 4\\\\ 4 \& 1 \& 2\\\\ 0 \& 0 \& 0\\\\ \\end{array} \\right 140310420
我们将该矩阵视为一个几何变化函数,容易发现,投入到该矩阵中的任何几何元素在被矩阵处理后都会丢失一个维度,比如对于三维空间中的一条线段,我们假设该线段参数方程的伪向量表示是(x,y,z)(x, y, z)(x,y,z),将该伪向量投入上方的矩阵中进行变化后,得出:(x+3y+4z,4x+y+2z,0)(x+3y+4z, 4x+y+2z, 0)(x+3y+4z,4x+y+2z,0),zzz消失了,在几何上的直观表示如下:
矩阵存在全零行,在几何直观上就意味着会让被矩阵处理后的几何元素失去一个维度的信息,从这个角度看,全零矩阵显然就是让几何元素失去所有维度的信息,最终塌缩成一个点。下面来看看矩阵中全零列的含义,考虑下方矩阵:
104402903 \left \\begin{array}{ccc} 1 \& 0 \& 4\\\\ 4 \& 0 \& 2\\\\ 9 \& 0 \& 3\\\\ \\end{array} \\right 149000423
同样的将三维中的一个几何元素(x,y,z)(x, y, z)(x,y,z)投入矩阵,处理后得出新的几何元素(x+4z,4x+2z,9x+3z)(x+4z, 4x+2z, 9x + 3z)(x+4z,4x+2z,9x+3z),显然yyy消失了,原本yyy维度的信息变成了由x,zx, zx,z表示的新信息,显然我们只需要调控矩阵中第二行两侧的数字,就可以使用x,zx, zx,z组成不同的yyy,也就是说全零列在几何维度信息上就意味着让几何元素某一维度的信息变为其它维度信息的组合表示。
4.单位矩阵
考虑下方特殊矩阵:
100010001 \left \\begin{array}{ccc} 1 \& 0 \& 0\\\\ 0 \& 1 \& 0\\\\ 0 \& 0 \& 1\\\\ \\end{array} \\right 100010001
显然该矩阵是方阵,并且主对角线上的元素全部都是1,同样的我们将任意三维几何元素(x,y,z)(x, y, z)(x,y,z)投入该矩阵,容易发现在处理后得出的新几何元素是(x,y,z)(x, y, z)(x,y,z),没有发生任何变化,就像是乘了1一样,因此我们称在主对角线上的所有元素都为1的矩阵为单位矩阵 ,符号表示是III,部分国内的教材也使用E 来表示,在本系列文章中,笔者将采用与《线性代数及其应用》相同的III来表示单位矩阵。
5.单位矩阵与全零行,全零列的结合(降维打击)
结合单位矩阵与全零行,全零列的特性,就能够得出非常神奇的几何变化效果,以三维中的一个正方体为例,假设该正方体的边长为2,如下图:
很不幸的是,笔者已经忘记了正方体参数方程的表示,不过没关系,我们可以推导出来,首先要表示出三维空间中的一个正方体,就意味着要表示出正方体中所有点的集合,目前笔者会的只有线的参数方程,直接跳到体难度有点大了,因此先考虑表示出一个二维平面,平面如下:
问题就是:已知该平面正方形的四个端点坐标和边长,求该平面的参数方程,等价的,我们得表示出平面上所有点的集合,直观的,我们发现该正方形中任意点的xxx坐标范围是1,31, 31,3,任意点的yyy坐标范围是1,31,31,3,但是如果使用参数方程:
{x=1+2ty=1+2t0<=t<=1 \begin{cases} x = 1+2t\\ y=1+2t\\ 0<=t<=1 \end{cases} ⎩ ⎨ ⎧x=1+2ty=1+2t0<=t<=1
表示出来的是一条线段,准确的来说是两端点为(1,1),(3,3)(1, 1),(3, 3)(1,1),(3,3)的线段,由于面是由线组成的,我们得到启发,可以先表示出其中一条线,笔者选择表示出最下方的边,其参数方程为:
{x=1+2ty=10<=t<=1 \begin{cases} x=1+2t\\ y=1\\ 0<=t<=1 \end{cases} ⎩ ⎨ ⎧x=1+2ty=10<=t<=1
由于可以使用向量语言来对线段进行偏移,偏移后得出新的线段,因此我们只需要表示出从下方边长到上方边长中的每一条线段就可以了,由此该平面可以表示为:{c02+1+2t1}\{c\bigl\\begin{smallmatrix} 0 \\\\ 2 \\end{smallmatrix}\\bigr+\bigl\\begin{smallmatrix} 1+2t \\\\ 1 \\end{smallmatrix}\\bigr\}{c02+1+2t1},其中0<=c<=1,0<=t<=10<=c<=1,0<=t<=10<=c<=1,0<=t<=1,得出的结果为:{1+2t2c+1}\{\bigl\\begin{smallmatrix} 1+2t \\\\ 2c+1 \\end{smallmatrix}\\bigr\}{1+2t2c+1},我们发现,利用向量语言能够非常便利的进行从点到线,从线到面的扩充。
下面回到正方体中,类似的,我们先表示出一个面,笔者选择表示正方体的下表面,该面投影到xyxyxy平面上是:
类似的,我们先表示出该平面的下边长,得出:
{x=1+2c1y=00<=c1<=1 \begin{cases} x = 1+2c_1\\ y = 0\\ 0<=c_1<=1 \end{cases} ⎩ ⎨ ⎧x=1+2c1y=00<=c1<=1
利用向量语言进行线到面的扩充,得出该面的表示为:{c202+1+2c10}={1+2c12c2}\{c_2\bigl\\begin{smallmatrix} 0 \\\\ 2 \\end{smallmatrix}\\bigr+\bigl\\begin{smallmatrix} 1+2c_1 \\\\ 0 \\end{smallmatrix}\\bigr\} = \{\bigl\\begin{smallmatrix} 1+2c_1 \\\\ 2c_2 \\end{smallmatrix}\\bigr\}{c202+1+2c10}={1+2c12c2},其中0<=c1<=1,0<=c2<=10<=c_1<=1,0<=c_2<=10<=c1<=1,0<=c2<=1,回到正方体中,为该平面加上三维信息,得出正方体下表面参数方程:
{x=1+2c1y=2c2z=10<=c1<=10<=c2<=1 \begin{cases} x = 1+2c_1\\ y = 2c_2\\ z = 1\\ 0<=c_1<=1\\ 0<=c_2<=1 \end{cases} ⎩ ⎨ ⎧x=1+2c1y=2c2z=10<=c1<=10<=c2<=1
同样的,我们使用向量语言对三维平面进行扩充,得出正方体的伪向量表示为:
c3002+1+2c12c21=1+2c12c21+2c3 c_3 \begin{bmatrix} 0\\ 0\\ 2 \end{bmatrix}+ \begin{bmatrix} 1+2c_1\\ 2c_2\\ 1\\ \end{bmatrix} = \begin{bmatrix} 1+2c_1\\ 2c_2\\ 1+2c_3\\ \end{bmatrix} c3 002 + 1+2c12c21 = 1+2c12c21+2c3
其中0<=c1,c2,c3<=10<=c_1, c_2, c_3<=10<=c1,c2,c3<=1,
容易发现,配合向量加法偏移几何元素的效果与向量数乘伸缩几何元素的效果,我们可以利用向量语言表示出一维,二维和三维中的任意一个几何元素,配合上微积分,就能够实现非常精确的表示,当然那是后话了。现在让我们回到主题,笔者并不知道大学中表示几何体的参数方程是什么样子的,但是遵循编程中统一接口的原则,在推导的过程中笔者有意识的将三维几何体的伪向量表示保持在三个元素,幸运的是笔者成功了,那么后续的步骤就非常简单了,考虑让正方体的伪向量表示乘以下方的矩阵:
100010000 \left \\begin{array}{ccc} 1 \& 0 \& 0\\\\ 0 \& 1 \& 0\\\\ 0 \& 0 \& 0\\\\ \\end{array} \\right 100010000
得出的结果显然是:
1+2c12c20 \begin{bmatrix} 1+2c_1\\ 2c_2\\ 0 \end{bmatrix} 1+2c12c20
发现了吗,正方体被压缩到xyxyxy平面上了,用更牛逼的话来说就是正方体被降维打击了,标准术语就是正方体被投影到了xyxyxy平面,使用单位矩阵配合全零行进行投影能够保证原x,yx,yx,y信息不变,属于标准投影,如果不使用单位矩阵的话,那么原几何体被投影后的x,yx,yx,y信息就会发生变化,属于非标准投影。并且容易发现,单位矩阵中的哪一行为零行,几何元素对应行在被处理后就也会变为零行,那么如果单位矩阵中有两行零行呢?情况如下:
100000000 \left \\begin{array}{ccc} 1 \& 0 \& 0\\\\ 0 \& 0 \& 0\\\\ 0 \& 0 \& 0\\\\ \\end{array} \\right 100000000
显然得出的结果是:
1+2c100 \begin{bmatrix} 1+2c_1\\ 0\\ 0 \end{bmatrix} 1+2c100
几何意义就是该正方体被投影到了xxx坐标轴上,并且是标准投影,没有改变原xxx的信息,利用单位矩阵配合全零行,我们就可以实现任意的标准投影,下面来看看单位矩阵配合全零列的情况,考虑下方矩阵:
100000001 \left \\begin{array}{ccc} 1 \& 0 \& 0\\\\ 0 \& 0 \& 0\\\\ 0 \& 0 \& 1\\\\ \\end{array} \\right 100000001
显然这与全零行配合单位矩阵起到的效果是一样的,我们发现在单位矩阵中变为全零行的行对应的也会变为全零列的列。
6.降维逆变化的存在性探讨1
自然而然的,我们会思考:既然能够使用矩阵变化函数让高维几何元素降维,那么能不能反过来让低维几何元素通过矩阵变化函数升维呢?此时分为两种情况,情况1是纯粹的让低维几何元素升维,情况2是在高维几何元素降维后,使用逆变化把低维几何元素变回去。我们先来讨论情况1,来个比较困难的例子,假设我们希望对平面上的一个等边三角形进行升维,让其变为一个正三棱柱,如图:
首先得求出等边三角形的参数方程,然后让一个矩阵作用于该参数方程,得出目标正三棱柱,第一个难题就是要如何使用参数方程表示出等边三角形,我们同样可以将等边三角形视为无数条线的集合,但是恶心的地方就在于每条线的长度是不同的,这意味着我们的使用向量的数乘变化对线段进行缩放变化了,先表示出等边三角形底边的线段:
{x=1+2c1y=10<=c1<=1 \begin{cases} x = 1+2c_1\\ y=1\\ 0<=c_1<=1 \end{cases} ⎩ ⎨ ⎧x=1+2c1y=10<=c1<=1
之后得对该线段进行平移和缩放,平移非常简单,使用向量加法就可以完成,关键是缩放,当底边被平移到不同的位置时,要数乘不同的缩放值,换句话说就是缩放值与平移量存在函数关系,我们得找到这个关系,假设平移量为c2c_2c2,缩放值为uuu,显然在等边三角形中对于任意的平移量,都对应着唯一的缩放值,这里要重点注意的是:线段必须相对于其中点进行缩放,那么最大的问题就是要如何让一条线段相对于自身中点进行缩放?我们考虑下方的线段:
显然该线段的参数方程是:
{x=1+2ty=1+t0<=t<=1 \begin{cases} x = 1+2t\\ y=1+t\\ 0<=t<=1 \end{cases} ⎩ ⎨ ⎧x=1+2ty=1+t0<=t<=1
使用伪向量表示该线段,得出:1+2t1+t\bigl\\begin{smallmatrix} 1+2t \\\\ 1+t \\end{smallmatrix}\\bigr1+2t1+t,如果我们直接让该伪向量乘以2的话,那么得出的新伪向量就是2+4t2+2t\bigl\\begin{smallmatrix} 2+4t \\\\ 2+2t \\end{smallmatrix}\\bigr2+4t2+2t,端点变为了(2,2),(6,4)(2, 2),(6, 4)(2,2),(6,4),如下图:
这显然不是我们所希望的相对于线段中点进行的变化,向量数乘是水似乎同样也不浅,因此在讨论升高维度前,我们得先来好好的研究一下向量数乘变化的缩放效果了。
7.缩放参考点与缩放因子
向量加法与向量数乘,这两条看似简单的变化是整个线性代数的基石,水深的很,从向量加法中,我们推出了:
结论 1.向量是描述和操作几何变化的一门语言 2.矩阵是封装向量语句后形成的几何变化函数 3.向量本身不存在严格意义上的几何变化,向量的几何含义就是描述几何元素的几何变化 4.我们可以使用参数方程表示任意几何元素,并且可以将参数方程转换为伪向量的形式,从而使用向量语言来描述和操作该几何元素的几何变化 5.将向量封装成矩阵函数后就可以对几何元素进行复杂的几何变化 要注意的是,在标准的教材中没有这些定义,这些定义是笔者结合自身编程经验与线性代数知识得出的,不保证正确性,不过这个角度是非常利于程序员理解线性代数的,下面来看看向量数乘变化中又藏着什么东西。
首先数乘变化作用于向量,就是缩放一个向量,得出新向量,作用于伪向量,就是缩放一条线段,得出新线段。对于缩放操作本身,最重要的两个因素就是缩放参考点与缩放比例因子 (这两个名词同样是笔者取的)。 我们先来看向量数乘作用于实际向量的结果,考虑任意二维向量(x,y)(x, y)(x,y),将其数乘任意标量ccc,得出(cx,cy)(cx, cy)(cx,cy),显而易见的是,该向量会被伸缩,还可能会被平移,但是平移对向量是没有意义的,因此数乘作用于实际向量的唯一结果就是伸缩,也就是说缩放参考点对于实际向量是没有意义的,有意义的就只是缩放比例因子,比如对于一个起点为(1,1)(1, 1)(1,1),终点为(2,3)(2, 3)(2,3)的向量,将其模翻倍,得出新向量的起点为(2,2)(2, 2)(2,2),终点为(4,6)(4, 6)(4,6),但是向量不存在平行或平移的概念,原向量和新向量在保持长度与方向不变的情况下可以任意移动,这也是向量本身不存在严谨几何变化的体现之一,可以认为向量就是纯粹的操作描述语言,不存在几何实体,在生活中的体现就是你不会在移动东西的时候看到有一条"带箭头的线"冒出来,你只会看到物品被移动了,而向量更像是你在移动东西的时候在脑子里面想象的移动方法。
下面来看看数乘变化作用于伪向量的情况,对于笔者定义的伪向量,其本质上是几何元素参数方程表示的向量形式,对于几何元素,其与向量最大的不同就是几何元素是存在几何实体的,也就是说其存在平移概念,因为所有几何元素都存在固定的端点,端点本身属于几何元素的一个重要属性,
比如生活中的一个杯子被放在桌子上,那么其所处的位置也是这个杯子性质的一部分,在数学与物理的角度,放在地上的杯子和放在桌子上的杯子是完全不同的两个概念,又比如在上方使用数乘变化表示等边三角形时,我们必须让缩放参考点是线段中点,否则就无法表示出线段平移过程中的每一条长度不同的线段,又又比如对于端点为(1,1),(2,3)(1, 1),(2, 3)(1,1),(2,3)的线段,将其按照端点进行缩放和按照中点进行缩放得出的是完全不同的两条线段,如下图:
显而易见的,上方三条线段的参数方程是不同的,因为参数方程中会体现出线段的端点性质,所以对于几何元素伪向量的数乘变化,是同时存在缩放参考点与缩放因子 两个影响因素的,因此我们重点讨论对于伪向量的数乘变化。在实际需求中,我们往往希望固定下来一个几何体的缩放参考点与缩放因子,比如之前在求等边三角形的参数方程的时候,我们就希望将缩放参考点确定为线段自身的中点,并且在线段移动的过程中,缩放参考点也得跟着线段的中点进行移动,显然确定缩放参考点是非常复杂的,规则的等边三角形尚且如此,对于不规则的图形就更难了,不过在数学与物理中,一个基本的思想就是:复杂的操作都是简单的叠加 ,比如说微积分往简单的说,其实就是一堆1+1的叠加,因此我们先从最简单的线段缩放开始进行推理,先构造出一个具体的实例,考虑端点为(x1,y1),(x2,y2)(x_1, y_1),(x_2, y_2)(x1,y1),(x2,y2)的任意线段,如下图:
容易得知该线段的参数方程为:
{x=x1+t(x2−x1)y=y1+t(y2−y1)0<=t<=1 \begin{cases} x = x_1+t(x_2-x_1)\\ y = y_1 + t(y_2-y_1)\\ 0 <= t <=1 \end{cases} ⎩ ⎨ ⎧x=x1+t(x2−x1)y=y1+t(y2−y1)0<=t<=1
伪向量表示为:x1+t(x2−x1)y1+t(y2−y1)\bigl\\begin{smallmatrix} x_1+t(x_2-x_1) \\\\ y_1 + t(y_2-y_1) \\end{smallmatrix}\\bigrx1+t(x2−x1)y1+t(y2−y1),最终的目的就是使用向量数乘和向量加法的配合,让该线段能够在我们所希望的任意一个缩放参考点中进行任意缩放比例因子是缩放。首先容易发现,直接的向量数乘是以坐标原点为缩放参考点进行缩放的,比如让上方线段的伪向量数乘uuu,得出新线段的伪向量为:ux1+tu(x2−x1)uy1+tu(y2−y1)\bigl\\begin{smallmatrix} ux_1+tu(x_2-x_1) \\\\ uy_1 + tu(y_2-y_1) \\end{smallmatrix}\\bigrux1+tu(x2−x1)uy1+tu(y2−y1),可以发现新线段的端点变为了(ux1,uy1),(ux2,uy2)(ux_1, uy_1),(ux_2, uy_2)(ux1,uy1),(ux2,uy2),就是将原端点的xxx坐标与yyy坐标乘了uuu,即以原点为缩放参考点,如下图:
那么如果缩放参考点不是原点呢?并且我们发现在以原点为缩放参考点时,线段除了被缩放外,还会被平移,某些情况下我们并不希望出现平移效果,比如在求等边三角形的参数方程时,就希望让线段从自身中点开始缩放,不产生平移效果,显然存在两种思路,第一种就是不改变原点位置,将缩放后的线段使用向量加法平移到目标位置,第二种就是改变原点位置(改变缩放参考点位置),以此来控制向量数乘的平移效果,比如当我们希望让缩放后的新线段与原线段有相同的中点时,如果采用思路1的话,那么就是这样的:
如果是采用思路2的话,那么就是这样的:
本质上是一样的操作,只不过视角不同,一个是平移线段,一个是平移坐标轴,以程序员的经验来看,如果我们平移了坐标轴,那么在坐标轴下所有点的坐标都要发生变化,计算量就会比较大,会降低程序的效率,但是如果是平移缩放后的线段的话,就只有线段本身点的坐标会发生变化,计算量比较小,程序的效率比较高,并且从直观上来看,固定的坐标轴也更加利于我们进行理解,因此我们先来讨论思路1的可行性:
首先必须要搞明白需求,也就是要将缩放后的新线段平移到哪个位置,在不同的情况下,我们可能会希望让新线段的中点与原线段重合,或是让新线段的左端点与原线段左端点重合,甚至是让新线段左端点与原线段右端点重合...情况多种多样,我们得总结出通用的数学性质,先来伪造出一个具备通性的实例,假设一条线段的端点为(x1,y1),(x2,y2)(x_1, y_1),(x_2, y_2)(x1,y1),(x2,y2),缩放比例因子为uuu,缩放参考点为原点,缩放后得出的新线段的端点为(ux1,uy1),(ux2,uy2)(ux_1, uy_1),(ux_2, uy_2)(ux1,uy1),(ux2,uy2),我们就以新线段的中点为参考点进行平移,希望将新线段的中点平移到平面上任意一点(x,y)(x, y)(x,y)处,求平移要使用到的向量。也就是这样子的:
图中的都是已知量,我们的目标就是使用已知量表示出平移向量,显然这非常简单,起点与目标点都已知,那么使用目标点坐标减去起点坐标就可以得出平移向量的,即:xy−u∗(x1+x2)/2u∗(y1+y2)/2=x−u∗(x1+x2)/2y−(y1+y2)/2\bigl\\begin{smallmatrix} x \\\\ y\\end{smallmatrix}\\bigr - \bigl\\begin{smallmatrix} u\*(x_1+x_2)/2 \\\\ u\*(y_1+y_2)/2 \\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} x - u\*(x_1+x_2)/2 \\\\ y -(y_1+y_2)/2 \\end{smallmatrix}\\bigrxy−u∗(x1+x2)/2u∗(y1+y2)/2=x−u∗(x1+x2)/2y−(y1+y2)/2,比如当我们希望让新线段中点与原线段是重点重合时,起点就是新线段中点,目标点就是原线段中点,即:
得出的平移向量为(1−u)∗(x1+x2)/2(1−u)∗(y1+y2)/2\bigl\\begin{smallmatrix} (1-u)\*(x_1+x_2)/2 \\\\ (1-u)\*(y_1+y_2)/2 \\end{smallmatrix}\\bigr(1−u)∗(x1+x2)/2(1−u)∗(y1+y2)/2,也就是说只需要让缩放变化后形成的新伪向量加上该平移向量,就可以达到让原线段和新线段的中点重合的需求,利用这种思路,可以让缩放后的新线段通过向量加法移动到任何位置,只需要知道起始重合点与目标重合点就可以了,至于移动坐标轴的方法,暂且先不考虑,现在让我们回到对降维逆变化的探讨中。
8.降维逆变化的存在性探讨2
在降维逆变化的存在性探讨1中,我们讨论的两种情况其实可以总结成一种,那就是:已知低维几何元素的表示,要将其逆向成高维几何元素,也就是知高求低,首先高维几何元素投影到低维必然会丧失一部分的信息,但是我们从不同的角度进行投影,得出的信息是不同的,那么是否能够根据一部分的低维信息,利用向量语言来逆向出高维几何元素呢?也就是说我们希望将一个高维的几何元素使用低维信息表示,在需要时再通过逆向矩阵逆向出高维几何元素。在严格的数学中,降维逆变化是不存在的,主要原因就是数学中的线段是由无数个点组成的,但是在降维后,无数就变为了有限,而有限是无论如何都不可能变为无数的,但是在程序中可不一定,让我们使用编程的视角来进行讨论,考虑下方二维几何图形:
在计算机中,一条线段的点是有限的,是以像素点为单位的,这就在计算机中为降维逆变化提供了可能性,对于上方的二维图形,我们实现一个程序,该程序的效果是:图形上方开始衍生一条线段,并且该线段自带一个计数器和一份距离哈希表,在线段向下生长的过程中,每碰撞到一个有效像素点就让计数器加1,除了第一个点外,碰撞到之后的所有点都往距离哈希表中填入两点间的距离,知道碰撞到x轴,线段生长结束,具体来说就是这样子的:
每当有一条线段"生长下来"我们就记录这一批信息,显然此时我们可以逆向出该线段碰撞到的所有几何元素点,并且我们还可以进一步的进行压缩,把投影到x轴上的信息向坐标原点投影,得出一个投影点,具体操作是从x轴的反向再次生长一条线段,每碰撞到一个投影点就记录该投影点中的所有信息,最终记录最左侧投影点到坐标原点的距离,压缩后得出就是一个记录所有投影点信息的数组,对这个数组进行逆向,就可以还原出原本的高维几何元素了,并且不只二维,该操作对于任意维度的几何元素都适用,可以在逻辑上把复杂的三维模型压缩成一个"点",笔者将在后续章节中尝试实现该算法。
基于该思路,如果我们的世界也是间断的,由一个个点组成的,那么就可以使用该方法在计算机中记录下来整个宇宙中的所有几何信息,当然在物理学界还在争论世界是连续的还是间断的,等笔者写到《用C++实现量子力学》系列时再深入讨论吧。
下面来讨论另一种情况,就是高维几何元素未知,已知的只有低维投影,我们希望使用低维投影信息反推出高维几何元素的表示,也就是知低求高,先来看看在二维中的情况:
在上图中,红色线段表示未知二维几何元素在坐标轴上的投影,显然易见的,如果只看坐标轴上的投影的话,那么存在无数种可能,具体来说这两个投影信息提供了一个约束,就是几何元素必须位于灰色的框框中,满足这个约束条件的二维几何元素存在无数种,比如:
这意味着仅仅只有坐标轴上的两个投影信息是不可能得出固定的二维几何元素的,我们需要更多的投影信息来进行约束,比如:
我们发现了一个事实:新的投影似乎无法再增加有效约束了,也就是说投影这个操作能够产生的约束就只有上方那一个,这就像是你拿手电筒照一个球,得出的所有投影都是圆,但是你无法从投影信息中确定出这个球是不是空心的,显然我们得想办法得出高维几何元素的内部信息,由此得到启发,我们在其中一条对角线上构造出无数个坐标轴,从图形内部进行投影,每个坐标轴都只记录自身原点上方的投影信息,如图:
范围确实缩小了,从直觉上来看似乎可行,但是非常复杂,如果想要毫无缺漏的表示出高维几何元素的话,那么需要无数个投影信息,但是在程序中我们可以在对角线的每一个像素点上做一个坐标轴,然后再进行投影,具体的步骤就是先根据基本坐标轴上的投影确定出范围,该范围必定是矩形,然后在得出的矩形范围中做对角线并在对角线的每一个像素点上做坐标轴,不断的进行投影,得出了所有投影信息后似乎就可以逆向出完整的高维几何元素了。
9.移动线段缩放后的平移起始点
在上文我们分析了静态线段在缩放后要如何构造出平移到目标点的向量,但是笔者在实际解决问题时,发现几乎所有情况都是动态的,线段在被缩放的同时自身也在平移,就会非常的难以表达,因此专门开出一篇进行讲解,问题就是:已知初始线段的参数方程和缩放比例因子,缩放参考点是原点,该线段在被缩放时自身也在平移,要使用初始线段的参数方程和缩放比例因子表达出初始线段"动态缩放+平移"后线段上的任意一点。最恶心的地方在于原点缩放自带平移效果,而线段自身又在平移,因此就涉及到了平移的叠加,还得考虑平移速度问题,因为在相对于原点进行缩放时,缩放比例因子的大小是会影响到平移的速度的,而在笔者构造出来的具体问题中,缩放比例因子也是动态变化的,因此解决该问题的关键就在于不同速度平移的叠加。变量太多了,我们得先固定几个,将问题变得简单一点,先假定缩放比例因子是固定的,再伪造出一个具备通性的问题实例,假设一条线段的两个端点为(x1,y1),(x2,y2)(x_1, y_1),(x_2, y_2)(x1,y1),(x2,y2),缩放参考点为原点,缩放比例因子为uuu,平移向量为(x,y)(x, y)(x,y),要使用这些已知量表达出平移+缩放后新线段上的任意一点(x3,y3)(x_3, y_3)(x3,y3),如下图:
运用初中物理学的知识,我们可以将上方的平移叠加操作想象为运动学中的运动合成,显然我们可以将向量分解到坐标轴上来进行求解,不过目前我们只知道平移向量(x,y)(x, y)(x,y)作用的平移方向平移的最终效果,将平移向量分解到坐标轴上,容易得知最终的效果是让线段上的每一个点都向xxx平移x的距离,向yyy轴平移y的距离,如果只存在平移向量作用的话,最终得出线段的端点就是(x1+x,y1+y),(x2+x,y2+y)(x_1+x, y_1+y),(x_2+x, y_2+y)(x1+x,y1+y),(x2+x,y2+y),并且我们还容易得知,如果只存在数乘变化的话,那么向量最终的端点就是(ux1,uy1),(ux2,uy2)(ux_1, uy_1),(ux_2, uy_2)(ux1,uy1),(ux2,uy2),如下图:
单个向量作用的效果是非常容易求解的,我们现在要做的就是把它们叠加起来,即使用已知量表示出叠加后真正的最终线段的端点,看整条线段太复杂了,我们先只看其中的一个端点:
显然平移的叠加实质上就是向量加法作用于向量,得出的新向量就是平移几何元素的向量,由此我们求得最终线段的端点为:
由此我们可以总结出:对于任意线段同时进行向量加法与缩放比例因子固定的向量数乘时,得出的新线段的端点为原线段端点数乘缩放比例因子加上平移向量 。并且容易推知,就算缩放比例因子自身是动态变化的,只需要表示出其表示式,上方的性质同样适用,并且对于三维线段,只需要对zzz信息进行相同的操作,同样可以得出目标向量端点,这也就是向量加法作用与向量表示运动叠加的实质了。
10.复杂几何图形的参数方程表示
我们废了那么大的力气分析向量加法与向量数乘,自然得来实操验证一下,先来一个二维的等边三角形开开胃,即求出下面二维等边三角形的参数方程:
首先我们可以表示出底边的参数方程:
{x=1+2ty=10<=t<=1 \begin{cases} x = 1 + 2t\\ y = 1\\ 0 <= t <= 1 \end{cases} ⎩ ⎨ ⎧x=1+2ty=10<=t<=1
伪向量表示为1+2t1\bigl\\begin{smallmatrix} 1+2t \\\\ 1\\end{smallmatrix}\\bigr1+2t1
然后得将底边向上平移,在平移的过程中,线段长度是动态变化的,着意味着缩放比例因子动态变化,因此先求出缩放比例因子的表达式,可以利用等边三角形的几何性质进行求解:
上图的含义就是每当底边向上平移h时,底边长度就变为d,并且d=2∗(1−h/3)d = 2*(1-h/\sqrt{3})d=2∗(1−h/3 ),那么容易得知,使用平移后线段长度表达式除以底边长度就可以得出缩放比例因子为:1−h/31-h/\sqrt{3}1−h/3 ,在平移+缩放后,新线段显然会跑到等边三角形的外面,我们得把它平移回去,具体来说我们得让新线段的中点与上图中h所在的线段中的每一点对应重合,也就是新线段的中点为起点,h所在线段中的每一个点为不同起点对应的终点,两个都是动态变化的,我们得求出这两个点的表达式,以此得出缩放平移向量,把新线段平移到等边三角形中,首先容易求得h线段的伪向量表达式为:21+h\bigl\\begin{smallmatrix} 2 \\\\ 1+h\\end{smallmatrix}\\bigr21+h,其中0<=h<=30<=h<=\sqrt{3}0<=h<=3 ,然后就是求平移+缩放后新线段的中点,首先我们容易求得平移向量为0h\bigl\\begin{smallmatrix} 0 \\\\ h\\end{smallmatrix}\\bigr0h,又由于缩放比例因子为1−h/31-h/\sqrt{3}1−h/3 ,原始向量的端点为:(1,1),(3,1)(1, 1),(3, 1)(1,1),(3,1),那么新向量端点就等于原向量端点数乘缩放比例因子再加上平移向量,即:(1−h/3,1−h/3+h),(3−3h/3,1−h/3+h)(1-h/\sqrt{3}, 1-h/\sqrt{3}+h),(3-3h/\sqrt{3}, 1-h/\sqrt{3}+h)(1−h/3 ,1−h/3 +h),(3−3h/3 ,1−h/3 +h),得出新线段的中点表示为:(2−2h/3,1−h/3+h)(2-2h/\sqrt{3}, 1-h/\sqrt{3}+h)(2−2h/3 ,1−h/3 +h),那么缩放平移向量就等于:(2h/3,h/3)(2h/\sqrt{3}, h/\sqrt{3})(2h/3 ,h/3 ),由此求出线段平移过程中任意一条线段的伪向量表达式为:1+2t+h/3−2ht/31+h\bigl\\begin{smallmatrix} 1+2t+h/\\sqrt{3}-2ht/\\sqrt{3} \\\\ 1+h\\end{smallmatrix}\\bigr1+2t+h/3 −2ht/3 1+h,使用集合符号表示所有线段的集合,得出等边三角形的参数方程的伪向量表示为:{1+2t+h/3−2ht/31+h}\{\bigl\\begin{smallmatrix} 1+2t+h/\\sqrt{3}-2ht/\\sqrt{3} \\\\ 1+h\\end{smallmatrix}\\bigr\}{1+2t+h/3 −2ht/3 1+h},其中0<=t<=1,0<=h<=30 <= t <= 1,0 <= h <= \sqrt{3}0<=t<=1,0<=h<=3 ,让我们来验证一下,首先当h=0h = 0h=0时,表达式得出的应该得是1+2t1\bigl\\begin{smallmatrix} 1+2t \\\\ 1\\end{smallmatrix}\\bigr1+2t1,带入数据得出:1+2t+0/3−20t/31+0=1+2t1\bigl\\begin{smallmatrix} 1+2t+0/\\sqrt{3}-20t/\\sqrt{3} \\\\ 1+0\\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 1+2t \\\\ 1\\end{smallmatrix}\\bigr1+2t+0/3 −20t/3 1+0=1+2t1,结果正确,如果h=3h=\sqrt{3}h=3 的话,那么得出的应该是点21+3\bigl\\begin{smallmatrix} 2 \\\\ 1+\\sqrt{3}\\end{smallmatrix}\\bigr21+3 ,带入数据得出:1+2t+1−2t1+3=21+3\bigl\\begin{smallmatrix} 1+2t+1-2t \\\\ 1+\\sqrt{3}\\end{smallmatrix}\\bigr = \bigl\\begin{smallmatrix} 2 \\\\ 1+\\sqrt{3}\\end{smallmatrix}\\bigr1+2t+1−2t1+3 =21+3 ,结果正确。此时求出的{1+2t+h/3−2ht/31+h}\{\bigl\\begin{smallmatrix} 1+2t+h/\\sqrt{3}-2ht/\\sqrt{3} \\\\ 1+h\\end{smallmatrix}\\bigr\}{1+2t+h/3 −2ht/3 1+h}就是整体参数方程,放到计算机中进行渲染就会得出一个"实心"的等边三角形,从整体参数方程变为外边缘参数方程是非常轻松的,也就是这样:{1+2t1,1+h/31+h,3−h/31+h}\{\bigl\\begin{smallmatrix} 1+2t \\\\ 1\\end{smallmatrix}\\bigr,\bigl\\begin{smallmatrix} 1+h/\\sqrt{3} \\\\ 1+h\\end{smallmatrix}\\bigr,\bigl\\begin{smallmatrix} 3-h/\\sqrt{3} \\\\ 1+h\\end{smallmatrix}\\bigr\}{1+2t1,1+h/3 1+h,3−h/3 1+h},外边缘就由底边,移动过程中线段左侧端点和移动过程中线段右侧端点组成。
本小节到此处就结束了,没有代码,但是当我们把向量理解成描述和操作几何变化的语言后线性代数和编程才算是真正的深度结合了起来,希望本篇文章能够给读者一些启发。






























