AI底层系列:用C++实现线性代数的公式推导与算法设计-基础篇-4.向量与向量方程
在上三节中我们学习了线性方程组,解线性方程组,行阶梯型矩阵,行化简矩阵,主元等线性代数相关的知识并使用C++实现了相应的函数,在本小节将学习线性代数中的一个重要概念:向量。
线性代数部分
从最简单的代数视角来看,向量本质上就是有序的一组数,在各个维度中都存在向量,其标准的定义是既有大小,又有方向的量,下面让我们从最简单的零维开始,逐步扩充到n维。
1.零维向量
零维只存在一个点,没有方向的概念,那么自然也就不存在有向线段,因此在零维中只存在唯一的一个零维向量,使用数学符号{0}\{\mathbf{0}\}{0}表示,从几何上来看就是一个固定的没有方向的点,要注意的是,零维向量不等同于各个维度中的原点,规定出零维向量主要是为了保证向量体系的完整性。
2.一维向量
一维在几何上就是一条线,可以使用任意一个实数表示一维上唯一的一个点,因此可以使用含有一个元素的实数集R\mathbb{R}R来表示一维上的任意一个点,也就是表示出了整个一维空间,在一维中向量的表示方法就是:[1][1][1],[3.4][3.4][3.4],[−2][-2][−2]…[x][x][x],在代数上,向量是一组有序的数,但是一维向量中只存在一个元素,那么就不存在有序这个概念了,在几何上,向量是从原点指向固定点的有向线段,比如一维向量[3][3][3]和[−4][-4][−4]在几何上的表示就是:
要注意的是,一维中原点的向量表示是[0][0][0],其不等同于{0}\{\mathbf{0}\}{0},因为两者的维度是不同的。
3.二维向量
二维是一个平面,要唯一的表示平面上的一个点,显然需要使用到两个实数,因此可以使用含有两个实数元素的实数集R2\mathbb{R}^2R2来表示二维空间中的所有点,其中R\mathbb{R}R表示实数,2^22表示实数个数是两个,由于要使用两个实数才能够表示出一个点,因此二维向量的表示就是这样的:
u=[12]v=[0−3]w=[41.5] \mathbf{u} =\begin{bmatrix} 1 \\ 2 \end{bmatrix} \quad \mathbf{v} =\begin{bmatrix} 0 \\ -3 \end{bmatrix} \quad \mathbf{w} =\begin{bmatrix} 4 \\ 1.5 \end{bmatrix} \quad u=[12]v=[0−3]w=[41.5]
显然从矩阵的角度来看,上方这些向量就是只存在一列的矩阵,因此我们称只存在一列的矩阵为列向量,简称向量,二维向量就是只存在两个元素的列向量,注意到二维向量中元素的个数大于一了,因此就会体现出有序性,从代数上来看就是:
[12]!=[21] \begin{bmatrix} 1 \\ 2 \end{bmatrix} != \begin{bmatrix} 2 \\ 1 \end{bmatrix} [12]!=[21]
从几何上来看,二维向量同样是从原点出发指向固定点的一条有向线段,比如二维向量[31],[−23],[13]\bigl[\begin{smallmatrix} 3 \\ 1 \end{smallmatrix}\bigr], \bigl[\begin{smallmatrix} -2 \\ 3 \end{smallmatrix}\bigr], \bigl[\begin{smallmatrix} 1 \\ 3 \end{smallmatrix}\bigr][31],[−23],[13] 的几何表示如下:
要说明的是,也可以使用()()()来表示向量,元素之间使用逗号隔开,[][][]中最上方的元素对应()()()中变成最左侧的元素,显然(3,1)(3, 1)(3,1)和(1,3)(1, 3)(1,3)的几何表示是不同的,有序性的体现是很明显的,要注意的是,二维的零向量是(0,0)(0, 0)(0,0),其与原点重合,没有方向,仅表示一个点,虽然性质和零维向量有相似之处,但是显然其与零维向量是不同的,二者所处的维度不同,表示点所需要的信息量是不同的。
考虑下方矩阵:
[12]和[12] \begin{bmatrix} 1 \\ 2 \end{bmatrix} 和 \begin{bmatrix} 1&2 \end{bmatrix} [12]和[12]
这两个矩阵虽然元素值相同,但是表示的几何含义是完全不同的,左侧的矩阵表示的是一个二维向量,几何含义是二维中的一条有向线段,右侧的矩阵表示的是两个一维向量,几何含义是一维坐标轴上的两条有向线段,也就是说矩阵的行数表示的就是矩阵中的一列所处的维度。
3.三维向量
容易得知,在三维中唯一的固定一个点需要三个实数,因此可以使用含有三个元素的实数集R3\mathbb{R}^3R3来表示三维中的所有点,从矩阵的角度看,三维向量就是存在三个元素的列向量,比如下方的三维向量:
a=[123]b=[0−35]c=[41.56]d=[xyz] \mathbf{a} =\begin{bmatrix} 1 \\ 2 \\3 \end{bmatrix} \quad \mathbf{b} =\begin{bmatrix} 0 \\ -3 \\ 5\end{bmatrix} \quad \mathbf{c} =\begin{bmatrix} 4 \\ 1.5 \\ 6\end{bmatrix} \quad \mathbf{d} =\begin{bmatrix} x \\ y \\z\end{bmatrix} a=
123
b=
0−35
c=
41.56
d=
xyz
同样的可以使用(x,y,z)(x, y, z)(x,y,z)来表示三维向量,在几何上,三维向量的表示如下:
4.n维向量
超过了三维后,我们就无法再使用几何去表示了,不过可以总结0,1,2,3维中的规律,容易得知:在n维中需要使用n个实数来表示任意一个点,那么就可以使用含有n个实数的实数集Rn\mathbb{R}^nRn来表示n维中的任意一个点,n维向量的矩阵表示如下:
[x1x2⋮xn] \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}
x1x2⋮xn
当然也可以这样表示:(x1,x2...x3)(x_1, x_2... x_3)(x1,x2...x3),最后要补充的是:如果一个向量中的所有元素都为零,那么就称该向量为零向量,符号表示是0\mathbf{0}0,要注意的是零向量和零维向量是不同的,在任意一个维度都存在零向量,但是只有在零维中才存在零维向量,并且在零维中存在的唯一的零维向量就是零向量。
5.向量加法与向量数乘
对于一个数学定义,如果只有定义,没有规定相应的运算规则,那么定义也就仅仅只是一个用处不大的符号,在有了运算规则后,就可以通过运算规则的组合来进行推导,实现某些神奇的效果,对于向量也是如此,向量加法与向量数乘就是两条最基础的向量运算规则,此处先以二维平面为例来进行向量加法与向量数乘的介绍。
向量加法在代数上就是简单的把向量中对应坐标位置的元素相加,然后得出一个新的向量,假设存在两个向量, 分别是v=[23]\boldsymbol{v} = \begin{bmatrix} 2 \\ 3 \end{bmatrix}v=[23] 和 w=[4−1]\boldsymbol{w} = \begin{bmatrix} 4 \\ -1 \end{bmatrix}w=[4−1],它们的相加过程如下:
v+w=[23]+[4−1]=[2+43+(−1)]=[62] \boldsymbol{v} + \boldsymbol{w} = \begin{bmatrix} 2 \\ 3 \end{bmatrix} + \begin{bmatrix} 4 \\ -1 \end{bmatrix} = \begin{bmatrix} 2 + 4 \\ 3 + (-1) \end{bmatrix} = \begin{bmatrix} 6 \\ 2 \end{bmatrix} v+w=[23]+[4−1]=[2+43+(−1)]=[62]
也可以这样表示:(2,3)+(4,−1)=(6,2)(2, 3) + (4, -1) = (6, 2)(2,3)+(4,−1)=(6,2),任意维度向量加法的操作都是上方那样的,不过要注意的是维度不同的向量是不能相加的,比如(1,2)+(1,2,3)(1, 2) + (1, 2, 3)(1,2)+(1,2,3)就是不被允许的,并且在零维中,由于只存在零向量,因此对零维向量执行向量加法的结果只能是零。对于n维度向量的加法就是这样的:
[x1x2⋮xn]+[y1y2⋮yn]=[x1+y1x2+y2⋮xn+yn] \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} + \begin{bmatrix} y_1 \\ y_2 \\ \vdots \\ y_n \end{bmatrix} = \begin{bmatrix} x_1+y_1 \\ x_2+y_2 \\ \vdots \\ x_n +y_n\end{bmatrix}
x1x2⋮xn
+
y1y2⋮yn
=
x1+y1x2+y2⋮xn+yn
向量加法还有非常明确且有意义的几何含义,也就是平行四边形法则,以向量(2,1)+(1,3)=(3,4)(2, 1) + (1, 3) = (3, 4)(2,1)+(1,3)=(3,4)为例,如下图:
在任意维度下的向量加法都遵守平行四边形法则,对于平行四边形法则的几何证明如下:
1.考虑任意平行四边形:
2.我们都可以将其补全为矩形:
3.补全后进行切割:
4.由平行四边形的性质可知,边2与边4平行且相等,那么在三角形b1与三角形b2中,边2与边4就是相等的,又由于矩形上下两边是平行的,那么边2与矩形下边的夹角1和边4与矩形上边的夹角2就是相等的,并且三角形b1与b2都是直角三角形,由全等三角形的判断依据AAS(角角边)可得三角形b1与b2全等,同理可证三角形a1与a2全等,那么对于矩形c1与c2显然就也是全等的了,最后再补上坐标轴,得出:
因此x1+x2,y1+y2x_1+x_2,y_1+y_2x1+x2,y1+y2就可以得出对角线的顶点C坐标了,平行四边形法则得证。下面来看看向量数乘,在代数的角度依旧非常简单,就是将向量中每一个坐标值都乘以一个指定的标量,比如:c=2,v=[23]c=2,\boldsymbol{v} = \begin{bmatrix} 2 \\ 3 \end{bmatrix}c=2,v=[23] ,那么矩阵数乘cv=2[23]=[2∗23∗2]=[46]c\boldsymbol{v} =2\begin{bmatrix} 2 \\ 3 \end{bmatrix}=\begin{bmatrix} 2*2 \\ 3*2 \end{bmatrix}=\begin{bmatrix} 4 \\ 6 \end{bmatrix}cv=2[23]=[2∗23∗2]=[46] ,总结一下就是:a[xy]=[axay]a\begin{bmatrix} x \\ y \end{bmatrix}=\begin{bmatrix} ax \\ ay \end{bmatrix}a[xy]=[axay] ,对于任意维度的向量,矩形数乘都成立,要注意的是在零维中只存在零向量,而零向量乘以任何标量得出的还是零向量。矩阵数乘同样有明确的几何意义,比如上方的例子在几何中的体现就是:
显然在几何上,就是让向量的长度变长指定标量的倍数,我们可以从代数的角度来证明,对于任意向量(x,y)(x, y)(x,y),由勾股定理可知向量长度为 x2+y2\sqrt{x^2 + y^2}x2+y2,让其数乘任意标量aaa,向量变为(ax,ay)(ax, ay)(ax,ay),再次使用勾股定理,得出a2x2+a2y2\sqrt{a^2x^2 + a^2y^2}a2x2+a2y2,将a2a^2a2提取出了并化简,得出ax2+y2a\sqrt{x^2 + y^2}ax2+y2,原长正好翻了aaa倍。要注意的是,如果一个向量数乘的标量是一个负数,那么向量就会反向,比如:

向量加法与向量数乘是可以组合运算的,组合运算的基本运算规则如下:
| 运算规则 |
|---|
| 对于Rn\mathbb{R}^nRn中的一切向量u,v,w\boldsymbol{u},\boldsymbol{v},\boldsymbol{w}u,v,w和任意标量c,dc,dc,d,有: |
| 1:u+v=v+u\boldsymbol{u} + \boldsymbol{v} = \boldsymbol{v} + \boldsymbol{u}u+v=v+u |
| 2:u+0=0+u=u\boldsymbol{u} + \boldsymbol{0} = \boldsymbol{0} + \boldsymbol{u} = \boldsymbol{u}u+0=0+u=u |
| 3:(u+v)+w=u+(v+w)(\boldsymbol{u} + \boldsymbol{v}) +\boldsymbol{w} = \boldsymbol{u} + (\boldsymbol{v} + \boldsymbol{w})(u+v)+w=u+(v+w) |
| 4:u+(−1u)=u+(−u)=−u+u=0\boldsymbol{u} + (-1\boldsymbol{u}) = \boldsymbol{u} + (\boldsymbol{-u}) = \boldsymbol{-u} + \boldsymbol{u} = \boldsymbol{0}u+(−1u)=u+(−u)=−u+u=0 |
| 5:c(u+v)=cu+cvc(\boldsymbol{u}+\boldsymbol{v}) = c\boldsymbol{u}+c\boldsymbol{v}c(u+v)=cu+cv |
| 6:c(du)=(cd)uc(d\boldsymbol{u}) = (cd)\boldsymbol{u}c(du)=(cd)u |
| 7:(c+d)u=cu+du(c+d)\boldsymbol{u} = c\boldsymbol{u} + d\boldsymbol{u}(c+d)u=cu+du |
| 8:1u=u1\boldsymbol{u} = \boldsymbol{u}1u=u |
要注意的是,上方所有运算的向量都必须是处于同一维度的,就算是零向量也一样,只有同维度的向量才能够进行运算。
6.向量方程
6.1线性组合
对于Rn\mathbb{R}^nRn下同维度的向量v1,v2,v3...vp\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}v1,v2,v3...vp和任意标量c1,c2,c3...cpc_1,c_2,c_3...c_pc1,c2,c3...cp,我们称:c1v1+c2v2+c3v3+...+cpvpc_1\boldsymbol{v_1}+c_2\boldsymbol{v_2}+c_3\boldsymbol{v_3}+...+c_p\boldsymbol{v_p}c1v1+c2v2+c3v3+...+cpvp是向量v1,v2,v3...vp\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}v1,v2,v3...vp以标量c1,c2,c3...cpc_1,c_2,c_3...c_pc1,c2,c3...cp为权的线性组合,线性组合中的权可以是任意实数,包括零,比如下方的组合都是v1,v2\boldsymbol{v_1},\boldsymbol{v_2}v1,v2的线性组合:
−5v1+3v2,10v1+3v2,0v1+0v2-5\boldsymbol{v_1}+3\boldsymbol{v_2}, \sqrt{10}\boldsymbol{v_1}+3\boldsymbol{v_2},0\boldsymbol{v_1}+0\boldsymbol{v_2}−5v1+3v2,10v1+3v2,0v1+0v2
显然线性组合就是使用向量加法与向量数乘把同维度的任意个向量组合起来,下面以二维为例,看看线性组合与维度之间的关系,首先是在线性组合中只存在一个二维向量v1\boldsymbol{v_1}v1的情况,如果这个唯一的向量是零向量,那么显然零向量的任意线性组合得出来的都是零向量,此时组合出了二维中的一个点,如果这个向量是非零向量,那么对其进行线性组合,得出:c1v1+c2v1+...+cnv1c_1\boldsymbol{v_1}+c_2\boldsymbol{v_1}+...+c_n\boldsymbol{v_1}c1v1+c2v1+...+cnv1,由向量加法与向量数乘的运算规则,显然可以将其化为:(c1+c2+...+c3)v1(c_1+c_2+...+c_3)\boldsymbol{v_1}(c1+c2+...+c3)v1,明显得出了一条线,此时就组合出了二维平面中的一条线。
然后是存在两个向量v1,v2\boldsymbol{v_1},\boldsymbol{v_2}v1,v2的情况,此时如果两个向量都是零向量,那么就落入了唯一向量是零向量的情况,如果其中有一个是非零向量,另一个是零向量,那么就落入了唯一向量是非零向量的情况,因此只需要考虑两个向量都是非零向量的情况,此时还得分情况,分为两向量平行与两向量不平行的情况,如果两向量平行,在不存在零向量的情况下,那么显然一个向量可以使用数乘变化变为另一个向量,那么就落入了唯一向量非零的情况,所以最终需要讨论的情况就只有两个向量都是非零向量且不平行的情况,从几何的角度看,对于任意的二维向量a\boldsymbol{a}a,可以将其视为一个平行四边形的对角线,该对角线从原点出发指向a点,如图:
此时由向量加法可知,该任意向量a=[xy]\boldsymbol{a} = \begin{bmatrix} x \\ y \end{bmatrix}a=[xy] 必然能够由xxx轴上的向量ax=[x0]\boldsymbol{a_x} = \begin{bmatrix} x \\ 0 \end{bmatrix}ax=[x0]和yyy轴上的向量ay=[0y]\boldsymbol{a_y} = \begin{bmatrix} 0 \\ y \end{bmatrix}ay=[0y]通过向量加法得出,也就是说使用二维坐标轴上的两条向量进行线性组合,是能够表示出整个二维平面空间中的所有向量的,那么如果是两条非坐标轴上的不平行向量呢,也就是向量v1,v2\boldsymbol{v_1},\boldsymbol{v_2}v1,v2,同样从几何来进行分析,由平行四边形对角线的互相平分性质可知,取其中一条对角线的中点为圆心画圆,在圆上的任意一条与原对角线不重合的直径,都可以是另外一条对角线,圆的大小是任意的,当两条对角线都确定了后,平行四边形就固定了,如下图:

那么就可以得出,对于二维平面中任意两条不平行的向量,一定可以通过线性组合表示出二维平面中的任意一条向量。最后来看看不平行向量的个数大于两条时,此时由于两条不平行的向量能够表示出二维平面中的任意向量,因此多出来的那些向量反过来也可以分解到这两条向量上,因此最终就落入两条不平行向量的情况,要说明的是,我们一般习惯使用坐标轴上的xxx向量与yyy向量的线性组合来表示二维平面中的任意向量。可以进行高维泛化,得出在n维空间中的n条不平行的向量的线性组合能够表示出n维空间中的任意向量,每当不平行向量的条数少一条,能够表示的维度就降低一维,但是表示出来的低维一定是位于n维的,必然三维中三条不平行向量的线性组合能够表示出三维中的任意一条向量,三维中的两条不平行向量的线性组合能够表示出三维中的一个二维平面上的任意一条向量,三维中的一条非零向量能够表示出三维中的一个一维线上的任意一条向量,在只存在零向量时,就只能表示出三维中一个零维的零维向量。用专业的术语来说就是:
| 定义 |
|---|
| 若v1,v2,v3...vp\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}v1,v2,v3...vp是Rn\mathbb{R}^nRn下同维度的向量,则v1,v2,v3...vp\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}v1,v2,v3...vp的所有线性组合组成的集合表示为Span{v1,v2,v3...vp}Span\{{\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}}\}Span{v1,v2,v3...vp},称为由v1,v2,v3...vp\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}v1,v2,v3...vp所张成的Rn\mathbb{R}^nRn的子集,也就是说Span{v1,v2,v3...vp}Span\{{\boldsymbol{v_1}, \boldsymbol{v_2},\boldsymbol{v_3}...\boldsymbol{v_p}}\}Span{v1,v2,v3...vp}是所有形如:c1v1+c2v2+c3v3+...+cpvpc_1\boldsymbol{v_1}+c_2\boldsymbol{v_2}+c_3\boldsymbol{v_3}+...+c_p\boldsymbol{v_p}c1v1+c2v2+c3v3+...+cpvp的向量组成的集合,其中c1,c2,c3...cnc_1,c_2,c_3...c_nc1,c2,c3...cn是任意实数标量 |
6.2向量方程
先来看一个具体的实例,对于向量a1=[23],a2=[35],b=[74]\boldsymbol{a_1} = \begin{bmatrix} 2 \\ 3 \end{bmatrix}, \boldsymbol{a_2} = \begin{bmatrix} 3 \\ 5 \end{bmatrix},\boldsymbol{b} = \begin{bmatrix} 7 \\ 4 \end{bmatrix}a1=[23],a2=[35],b=[74],我们希望使用向量a1,a2\boldsymbol{a_1}, \boldsymbol{a_2}a1,a2的线性组合表示出向量b\boldsymbol{b}b,也就是求:c1a1+c2a2=bc_1\boldsymbol{a_1}+c_2\boldsymbol{a_2}=\boldsymbol{b}c1a1+c2a2=b,写成矩阵形式就是:c1[23]+c2[35]=[74]c_1\begin{bmatrix} 2 \\ 3 \end{bmatrix}+c_2 \begin{bmatrix} 3 \\ 5 \end{bmatrix}= \begin{bmatrix} 7 \\ 4 \end{bmatrix}c1[23]+c2[35]=[74],把标量使用向量数乘的规则放入向量中,得出:[2c13c1]+[3c25c2]=[74]\begin{bmatrix} 2c_1 \\ 3c_1 \end{bmatrix}+ \begin{bmatrix} 3c_2 \\ 5c_2 \end{bmatrix}= \begin{bmatrix} 7 \\ 4 \end{bmatrix}[2c13c1]+[3c25c2]=[74],再使用向量加法的规则可以把方括号去掉,得出:
{2c1+3c2=73c1+5c2=4 \begin{cases} 2c_1+3c_2=7\\ 3c_1+5c_2=4 \end{cases} {2c1+3c2=73c1+5c2=4
还不够明显的话就再把标量符号c替换x,得出:
{2x1+3x2=73x1+5x2=4 \begin{cases} 2x_1+3x_2=7\\ 3x_1+5x_2=4 \end{cases} {2x1+3x2=73x1+5x2=4
神奇的事情发生了,我们最终得出了一个线性方程组,也就是说所谓的向量方程起始就是线性方程组的另一种表示形式,线性方程组是偏向代数的表示,而向量方程的偏向几何的表示,所谓的解线性方程组在向量的视角来看就是对指定的一组同维度向量a1,a2,a3...ap\boldsymbol{a_1}, \boldsymbol{a_2},\boldsymbol{a_3}...\boldsymbol{a_p}a1,a2,a3...ap进行线性组合,目的是得出目标向量b\boldsymbol{b}b,通过前三节的学习我们得知,线性方程组的解存在三种情况,分别是:无数解,唯一解与无解,既然向量方程是线性方程组的另一种表示,那么这三种解的情况必然也是存在对应的表示的,下面以三维空间为例来进行讨论。
考虑线性方程组:
{2x1+3x2+x3=73x1+5x2=4 \begin{cases} 2x_1+3x_2+x_3=7\\ 3x_1+5x_2=4 \end{cases} {2x1+3x2+x3=73x1+5x2=4
其对应的增广矩阵就是:
[23173504] \left[ \begin{array}{ccc|c} 2&3&1&7\\ 3&5&0&4 \end{array} \right] [23351074]
化成向量线性组合的表示就是:x1[23]+x2[35]+x3[10]=[74]x_1\begin{bmatrix} 2 \\ 3 \end{bmatrix}+x_2 \begin{bmatrix} 3 \\ 5 \end{bmatrix} +x_3 \begin{bmatrix} 1 \\ 0 \end{bmatrix}= \begin{bmatrix} 7 \\ 4 \end{bmatrix}x1[23]+x2[35]+x3[10]=[74]
现在的第一个问题是,上方的线性方程组到底是位于哪一个维度的,依据前三节中笔者的推理,线性方程组所处的维度就是线性方程组中最大的未知数下标,那么上方的线性方程组就是位于三维的,但是从向量的角度来看,明显是对二维向量进行处理,首先2x1+3x2+x3=72x_1+3x_2+x_3=72x1+3x2+x3=7表示的是一个三维中的平面,这是毋庸置疑的,那么线性方程组的所处维度一定就是三维的,不然就无法表示出三维的平面了,那么现在的问题就是要如何从向量的角度进行解释?目前从未知数个数的角度看,线性方程组绝对是位于三维空间中的,但是从向量的角度来看,绝对是对二维向量进行的线性组合,这两个视角都是没错的,那么或许我们不应该强行将它们统一,而是要分情况讨论,也就是说对于一个线性方程组,是存在两种维度的,这应该是线性代数后面的知识,现在还没学,但是并不影响我们进行推理,从未知数个数的角度来看,线性方程组的维度显然等于系数矩阵的列数,我们简称为列维度,从向量的角度来看,线性组合的维度显然等于系数矩阵的行数,我们简称为行维度(这是笔者为了便于表达而定义的,不属于教材上的内容),那么一个线性方程组就应该同时是存在列维度与行维度的,列维度视角的解线性方程组的重点是未知数,具体操作就是将未知数消去,最终将线性方程组表示为使用自由变量表示基变量的形式,而行维度的解线性方程组的重点是系数,将一列系数视为一个向量,解线性方程组就是使用线性组合表示出目标向量,目前还无法明确的推出两者的关系,又或者说以我们现在已有的知识来看,列维度与行维度应该是没什么关系的,完全是两个不同的视角,当然话也不能说的太死了,说不定只是笔者目前的level太低了,不过推理到这里已经能够解答问题了,既然线性方程组有两种维度,那么我们在解线性方程组时只需要多从一个角度进行考量就行了,下面回到向量方程中:
对于线性方程组:
{2x1+3x2+x3=73x1+5x2=4 \begin{cases} 2x_1+3x_2+x_3=7\\ 3x_1+5x_2=4 \end{cases} {2x1+3x2+x3=73x1+5x2=4
我们分别从行维度与列维度进行求解,首先是列维度,此时线性方程组系数矩阵有三列,即三个未知数,因此线性方程组所处维度就是三维,根据前三节所学到的知识,我们可以先把线性方程组的增广矩阵化为行化简矩阵,得出:
[1052301−3−13] \left[ \begin{array}{ccc|c} 1&0&5&23\\ 0&1&-3&-13 \end{array} \right] [10015−323−13]
再回代到线性方程组中,得出解:
{x1=23−5x3x2=3x3−13 \begin{cases} x_1 = 23 - 5x_3\\ x_2=3x_3-13 \end{cases} {x1=23−5x3x2=3x3−13
存在一个自由变量,解出了了一条三维空间中的直线,解的情况是存在无数个解,下面来看看行维度的角度,也就是使用线性组合解线性方程组:
x1[23]+x2[35]+x3[10]=[74]x_1\begin{bmatrix} 2 \\ 3 \end{bmatrix}+x_2 \begin{bmatrix} 3 \\ 5 \end{bmatrix} +x_3 \begin{bmatrix} 1 \\ 0 \end{bmatrix}= \begin{bmatrix} 7 \\ 4 \end{bmatrix}x1[23]+x2[35]+x3[10]=[74]
从线性组合的视角来看,就是要使用二维平面上的三个向量表示出目标向量,我们已知在二维平面中的两个不平行向量能够通过线性组合表示出二维平面上的任意一个向量,那么显然上方向量方程左侧的三个向量都是不平行的,因此一定能够使用线性组合表示出来,对应到解的情况就是线性方程组相容,在实际求解时,可以利用向量加法先把向量分解到坐标轴上,得出:
x1([20]+[03])+x2([30]+[05])+x3[10]=[70]+[04]x_1(\begin{bmatrix} 2 \\ 0 \end{bmatrix}+\begin{bmatrix} 0 \\ 3 \end{bmatrix})+x_2(\begin{bmatrix} 3 \\ 0 \end{bmatrix} +\begin{bmatrix} 0 \\ 5 \end{bmatrix})+x_3 \begin{bmatrix} 1 \\ 0 \end{bmatrix}= \begin{bmatrix} 7 \\ 0 \end{bmatrix}+\begin{bmatrix} 0 \\ 4 \end{bmatrix}x1([20]+[03])+x2([30]+[05])+x3[10]=[70]+[04]
那么由向量加法与向量数乘的运算规律可以把上方的线性组合分为两部分:
x1[20]+x2[30]+x3[10]=[70]x_1\begin{bmatrix} 2 \\ 0 \end{bmatrix}+x_2 \begin{bmatrix} 3 \\ 0 \end{bmatrix} +x_3 \begin{bmatrix} 1 \\ 0 \end{bmatrix}= \begin{bmatrix} 7 \\ 0 \end{bmatrix}x1[20]+x2[30]+x3[10]=[70]
x1[03]+x2[05]+x3[00]=[04]x_1\begin{bmatrix} 0 \\ 3 \end{bmatrix}+x_2 \begin{bmatrix} 0 \\ 5 \end{bmatrix} +x_3 \begin{bmatrix} 0 \\ 0 \end{bmatrix}= \begin{bmatrix} 0 \\ 4 \end{bmatrix}x1[03]+x2[05]+x3[00]=[04]
已经很明显了,我们找到了线性组合与线性方程组的一个联系:线性方程组中的每一条线性方程都对应着向量分解到坐标轴上的一个线性组合,从行与列的视角来看,就是矩阵中的每一行都是列向量分解到坐标轴上的一个线性组合,让我们继续求解上方的向量方程,对上方的线性组合继续化简,得出:
[2x1+3x2+x30]=[70]\begin{bmatrix} 2x_1+3x_2+x_3 \\ 0 \end{bmatrix}= \begin{bmatrix} 7 \\ 0 \end{bmatrix}[2x1+3x2+x30]=[70]
[03x1+5x2+0x3]=[04]\begin{bmatrix} 0 \\ 3x_1+5x_2+0x_3 \end{bmatrix}= \begin{bmatrix} 0 \\ 4 \end{bmatrix}[03x1+5x2+0x3]=[04]
去掉方括号,得出:
{2x1+3x2+x3=73x1+5x2=4 \begin{cases} 2x_1+3x_2+x_3=7\\ 3x_1+5x_2=4 \end{cases} {2x1+3x2+x3=73x1+5x2=4
绕了一大圈又绕回来了,不过我们对于线性方程组与向量方程直接的联系有了更加深刻的理解,那么解同样是将增广矩阵化为行化简矩阵,得出:
{x1=23−5x3x2=3x3−13 \begin{cases} x_1 = 23 - 5x_3\\ x_2=3x_3-13 \end{cases} {x1=23−5x3x2=3x3−13
我们显然可以将解表示成向量的形式,得出:
[x1x2]=[23−5x33x3−13]\begin{bmatrix} x_1 \\ x_2 \end{bmatrix}= \begin{bmatrix} 23-5x_3 \\ 3x_3-13 \end{bmatrix}[x1x2]=[23−5x33x3−13]
化简一下:
[x1x2]=x3[−53]+[23−13]\begin{bmatrix} x_1 \\ x_2 \end{bmatrix}= x_3\begin{bmatrix} -5 \\ 3 \end{bmatrix} + \begin{bmatrix} 23 \\ -13 \end{bmatrix}[x1x2]=x3[−53]+[23−13]
可以从几何角度证明x3[−53]+[23−13]x_3\begin{bmatrix} -5 \\ 3 \end{bmatrix} + \begin{bmatrix} 23 \\ -13 \end{bmatrix}x3[−53]+[23−13]表示的是一条直线,证明如下:
考虑任意一条定长向量L1与一条变长向量L2:
由于是向量,因此往右上方箭头向上,左下方箭头向下,在变长向量L2中任意取一段长度作为向量长度,与定长向量L1相加,得:
由平行四边形的性质可以得出,解集中的每一个点都是位于绿色直线上的,也就是说解确实是一条直线。那么可以推测:线性方程组存在无数解在向量方程中的体现就是线性组合中不平行向量的个数大于向量的维度,比如在上方向量方程中向量的维度都是二维的,但是存在三个不平行的向量,因此就得出了无数解,为了验证这一点,让我们再来看一个存在无数解的简单线性方程组:
{x1+x2+x3=3 \begin{cases} x_1+x_2+x_3=3 \end{cases} {x1+x2+x3=3
显然该线性方程组的解是:
{x1=3−x2−x3 \begin{cases} x_1=3-x_2-x_3 \end{cases} {x1=3−x2−x3
从向量方程的视角来看,该线性方程组就是x1[1]+x2[1]+x3[1]=3x_1[1]+x_2[1]+x_3[1] = 3x1[1]+x2[1]+x3[1]=3,显然向量是位于一维的,在一维中要表示任意向量只需要使用一个向量的线性组合就可以了,上方的表示中多了两个,但是此时又出现了一个问题:这三个向量显然是平行的,在一维空间中是不存在不平行的向量的。我们可以明确的是x1=3−x2−x3x_1=3-x_2-x_3x1=3−x2−x3表示的一定是三维空间中的一个平面,那么在向量方程中就应该要有相同的表示,但是一维怎么可能表示出平面呢?也就是说解的向量表示:3+x2[−1]+x3[−1]3+x_2[-1]+x_3[-1]3+x2[−1]+x3[−1]怎么可能是一个平面呢?得好好的梳理一下了。
我们先不看线性方程组,只看单个线性方程与向量之间的关系,考虑任意二维平面的线性方程:a1x1+a2x2=ba_1x_1+a_2x_2=ba1x1+a2x2=b,该线性方程表示的一定是二维平面中的一条直线,而二维平面中的直线必然能够使用二维向量来进行表示,那么a1x1+a2x2=ba_1x_1+a_2x_2=ba1x1+a2x2=b就必然有对应的向量表示,但是该式子是纯标量的式子,要先引入向量,我们假定x1x_1x1表示xxx轴,x2x_2x2表示yyy轴,那么x1,x2x_1,x_2x1,x2就能够表示为x1[10]+x2[01]x_1\begin{bmatrix} 1 \\ 0 \end{bmatrix} + x_2\begin{bmatrix} 0 \\ 1 \end{bmatrix}x1[10]+x2[01],带入到线性方程中得出a1[x10]+a2[0x2]=ba_1\begin{bmatrix} x_1 \\ 0 \end{bmatrix} + a_2\begin{bmatrix} 0 \\ x_2 \end{bmatrix} = ba1[x10]+a2[0x2]=b,但是显然向量不可能等于标量,我们学习的向量加法与向量数乘都是操作向量,得出向量,可以推测在后面必然存在一个运算法则,要么是能够操作向量,得出标量,要么是能够操作标量,得出向量,似乎到达我们线性代数知识的边界的,但是当年的数学家能够定义出具体的运算法则,我们为什么不可以,来试试看吧(不保证正确性)。
首先标量是只有大小,没有方向的,而向量是既有大小,又有方向的,因此思路一就是操作标量,为其加上方向变成向量,思路二就是操作向量,将其去除方向,变为标量。很明显,关键就是方向,那么首先就要明确数学中的方向到底是什么,可以认为方向本质上就是一种状态吧,是点的一种状态,对于一个固定点,在不同的视角看会存在不同的方向,所谓的视角就是我们规定出来的坐标原点,比如:
点是固定的,但是视角不同,方向不同,我们将一个未被观察的标量视为一个固定点,在规定了原点后使用原点到该固定点的长度表示标量的值并为其添加上观察的方向,比如对于标量5:
此时标量不就变为向量了吗,标量的值属性成功表示了出来并且人为的为其添加上了方向,标量5就等于[30]+[04]=[34]\begin{bmatrix} 3 \\ 0 \end{bmatrix} + \begin{bmatrix} 0 \\ 4 \end{bmatrix} = \begin{bmatrix} 3 \\ 4 \end{bmatrix}[30]+[04]=[34],对于任意标量b,其向量表示就是:[bxby]\begin{bmatrix} b_x \\ b_y \end{bmatrix}[bxby]且满足bx2+by2=b2b_x^2+b_y^2=b^2bx2+by2=b2,按照这个理解,再次尝试使用向量表示出线性方程a1x1+a2x2=ba_1x_1+a_2x_2=ba1x1+a2x2=b,首先假定x1,x2x_1,x_2x1,x2分别对应xxx轴和yyy轴,再把标量bbb变为向量形式,得出:a1[x10]+a2[0x2]=[bxby]a_1\begin{bmatrix} x_1 \\ 0 \end{bmatrix} + a_2\begin{bmatrix} 0 \\ x_2 \end{bmatrix} = \begin{bmatrix} b_x \\ b_y \end{bmatrix}a1[x10]+a2[0x2]=[bxby],化简后得出:[a1x1a2x2]=[bxby]\begin{bmatrix} a_1x_1 \\ a_2x_2 \end{bmatrix} = \begin{bmatrix} b_x \\ b_y \end{bmatrix}[a1x1a2x2]=[bxby],最终可以得出三条式子:
{a1x1=bxa2x2=bya12x12+a22x22=b2 \begin{cases} a_1x_1=b_x\\ a_2x_2=b_y\\ a_1^2x_1^2+a_2^2x_2^2=b^2 \end{cases} ⎩
⎨
⎧a1x1=bxa2x2=bya12x12+a22x22=b2
我们应该得让向量方程表示与线性方程表示能够互相转换,现在已经能够讲线性方程转为向量方程,那么还得要反过来使用向量方程转为线性方程,具体来说就是使用上方三条式子得出a1x1+a2x2=ba_1x_1+a_2x_2=ba1x1+a2x2=b,两边平方后得出:a12x12+2a1a2x1x2+a22x22=b2a_1^2x_1^2+2a_1a_2x_1x_2 + a_2^2x_2^2=b^2a12x12+2a1a2x1x2+a22x22=b2,显然与上方的式子不相等,但是我们的所有规定都是成功的表示出了所有属性的,不是瞎猜的,因此可以人为的加上一些规定,注意到x1x2x_1x_2x1x2的向量表示是坐标轴,是两条互相垂直的直线,那么我们规定:两条互相垂直的向量相乘会得出标量,并且标量值为零。好了,得出我们需要的了,再次回到线性方程组:
{x1+x2+x3=3 \begin{cases} x_1+x_2+x_3=3 \end{cases} {x1+x2+x3=3
其解集是:3−x2−x33-x_2-x_33−x2−x3,考虑把3,x2,x33,x_2,x_33,x2,x3化为向量形式,得出:
[030]−x2[010]−x3[001]\begin{bmatrix} 0 \\ 3\\0 \end{bmatrix}- x_2\begin{bmatrix} 0 \\ 1\\0 \end{bmatrix} - x_3\begin{bmatrix} 0 \\ 0\\1 \end{bmatrix}
030
−x2
010
−x3
001
,
显然两条不平行向量的线性组合能够得出一个平面,结果正确,但是感觉哪里怪怪的,等到学习了后面的线性代数知识再来解惑吧。现在我们已经得出:线性方程组存在无数解在向量方程中的表现就是线性组合中不平行向量的个数大于向量所处的维度,下面来看看存在唯一解的情况,考虑线性方程组:
{3x1+0x2+2x3=163x1+x2+2x3=193x1+x2+4x3=29 \begin{cases} 3x_1+0x_2+2x_3=16\\ 3x_1+x_2+2x_3=19\\ 3x_1+x_2+4x_3 = 29 \end{cases} ⎩
⎨
⎧3x1+0x2+2x3=163x1+x2+2x3=193x1+x2+4x3=29
其解为:
{x1=2x2=3x3=5 \begin{cases} x_1= 2\\ x_2= 3\\ x_3 =5 \end{cases} ⎩
⎨
⎧x1=2x2=3x3=5
不存在自由变量,属于唯一解的情况,解出来了三维空间中的一个点,把线性方程化为向量方程的形式,得出:
x1[333]+x2[011]+x3[224]=[161929]x_1\begin{bmatrix} 3 \\ 3\\ 3 \end{bmatrix} + x_2\begin{bmatrix} 0 \\ 1\\ 1 \end{bmatrix} + x_3\begin{bmatrix} 2 \\ 2 \\ 4 \end{bmatrix} = \begin{bmatrix} 16 \\ 19 \\ 29 \end{bmatrix}x1
333
+x2
011
+x3
224
=
161929
我们已知,三维中三条不平行向量的线性组合能够表示出三维中的任意向量,并且此时只存在三条不平行向量,可以得出:线性方程组只存在唯一解在向量方程中的体现就是线性组合中不平行向量的个数等于向量所在的维度,最后来看看无解的情况,考虑线性方程组:
{2x1+0x2=20x1+5x2=20x1+0x2=7 \begin{cases} 2x_1+0x_2=2\\ 0x_1+5x_2=2\\ 0x_1+0x_2= 7 \end{cases} ⎩
⎨
⎧2x1+0x2=20x1+5x2=20x1+0x2=7
行化简矩阵为:
[100010001] \left[ \begin{array}{cc|c} 1&0&0&\\ 0&1&0&\\ 0&0&1& \end{array} \right]
100010001
在增广矩阵的最左侧存在主元列,因此线性方程组无解,将线性方程组变为向量方程的形式,得出:
x1[200]+x2[050]=[227]x_1\begin{bmatrix} 2 \\ 0\\0 \end{bmatrix} + x_2\begin{bmatrix} 0 \\ 5\\ 0 \end{bmatrix} = \begin{bmatrix} 2 \\ 2 \\ 7\end{bmatrix}x1
200
+x2
050
=
227
可以得出:线性方程组中的无解在向量方程中的体现就是线性组合中不平行向量的个数小于向量所在的维度吗?考虑下方行化简矩阵:
[100011000] \left[ \begin{array}{cc|c} 1&0&0&\\ 0&1&1&\\ 0&0&0& \end{array} \right]
100010010
向量表示为:
x1[100]+x2[010]=[010]x_1\begin{bmatrix} 1 \\ 0\\0 \end{bmatrix} + x_2\begin{bmatrix} 0 \\ 1\\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \\ 0\end{bmatrix}x1
100
+x2
010
=
010
此时线性方程组显然有唯一解(不存在自由变量),但是在线性方程中的情况是:线性组合中不平行向量的个数小于向量所在维度,看来无解的情况是比较特殊了,让我们从几何的角度来分析,首先设v1=[200],v2=[050]\boldsymbol{v_1}=\begin{bmatrix} 2 \\ 0\\0 \end{bmatrix} ,\boldsymbol{v_2}=\begin{bmatrix} 0 \\ 5\\ 0 \end{bmatrix}v1=
200
,v2=
050
那么v1,v2\boldsymbol{v_1},\boldsymbol{v_2}v1,v2线性组合的集合Span{v1,v2}Span\{{\boldsymbol{v_1}, \boldsymbol{v_2}}\}Span{v1,v2}表示出来的就是三维空间中的一个平面,如下图:
显然要表示的向量不在Span{v1,v2}Span\{{\boldsymbol{v_1}, \boldsymbol{v_2}}\}Span{v1,v2}中,因此无解,那么反过来看,如果向量位于Span{v1,v2}Span\{{\boldsymbol{v_1}, \boldsymbol{v_2}}\}Span{v1,v2}中,就是有解,也就是说线性方程组无解在向量方程中的表示就是目标向量不在系数向量的Span{}Span\{\}Span{}空间中,那么最终的结论就是:
| 解情况的表示(前提条件:目标向量不与任何系数向量平行) |
|---|
| 1.如果线性方程组存在唯一解,那么在线性方程的角度就是不存在自由变量且增广矩阵最右侧一列不是主元列;在向量方程中的表示就是系数向量的线性组合中不平行向量的个数等于向量所在的维度数 |
| 2.如果线性方程组存在无数解,那么在线性方程的角度就是存在自由变量且增广矩阵最右侧一列不是主元列;在向量方程中的表示就是系数向量的线性组合中不平行向量的个数大于向量所在的维度数 |
| 3.如果线性方程组无解,那么在线性方程中角度就是增广矩阵最右侧一列是主元列;在向量方程中的表示就是目标向量不在系数向量的Span{....}Span\{....\}Span{....}中。 |
但是还存在一个特例,那就是目标向量与系数向量平行的情况,比如下方的向量方程:
x[12]=[36]x\begin{bmatrix} 1 \\ 2\end{bmatrix} =\begin{bmatrix} 3 \\ 6\end{bmatrix}x[12]=[36]
此时显然有解且存在唯一解,又比如向量方程:
x1[12]+x2[24]=[36]x_1\begin{bmatrix} 1 \\ 2\end{bmatrix} + x_2\begin{bmatrix} 2 \\ 4\end{bmatrix} =\begin{bmatrix} 3 \\ 6\end{bmatrix}x1[12]+x2[24]=[36]
此时显然存在无数解,
也就是说:
| 特殊情况 |
|---|
| 如果目标向量与系数向量平行,此时如果仅与一条系数向量平行,那么存在唯一解,如果与多条系数向量平行,那么存在无数解 |
笔者的奇思妙想
笔者的奇思妙想:
1.向量的平移
在判断解情况的时候,我们发现可以使用向量加法让二维向量进行平移,考虑该情况是否具备普适性?首先在一维中不存在平移的概念,所有向量都是共线的,而二维向量我们已经验证过了,因此在此处验证三维向量的情况,考虑任意三维向量:
再加上任意三维向量:
此时三维中的两条向量组成二维平面,落入二维中两向量相加的情况,显然在任意存在平移概念的维度中,向量加法最终都会落入二维中向量相加的情况,因此向量加法是可以让向量平移的,是几何视觉上的体现就是把一个向量向其相加向量的方向平移相加向量长度的距离,如图:
由向量加法的可交换性,还可以有另外一种视角,也就是把红色的向量平移到上方:
2.向量的旋转
自然的,我们想到向量是否能够进行旋转,考虑下面两条二维向量:
在上图中就是把向量(0,3)(0, 3)(0,3)变为向量(3,0)(3, 0)(3,0),可以使用向量加法,也就是:(0,3)+(3,−3)(0, 3)+(3, -3)(0,3)+(3,−3),如图:
我们发现,向量加法似乎有两种几何含义,从加数与被加数的角度来看是平移,从结果的角度来看是旋转,再配合上向量数乘伸缩向量的几何含义,我们似乎可以使用这两种向量运算表示出所有几何变化。我们还可以从单个点与整条线的角度理解向量加法,从整条线的角度看就是从向量起点开始,将一个向量分成无数个子向量,然后对每一个子向量使用向量加法,如图:
从整线角度看,每一个向量中的每一个点都被平移了,因此整个向量就被平移了,从单点角度看就是对向量中的一个点使用向量加法,此时在向量中就只有一个点被平移了,我们从起点连接该点,得出的就是一条新向量。
4.原点的意义
在文章之初就说明了,向量是既有大小,又有方向的量,这意味着只要两个向量的大小和方向是相同的,那么这两个向量就是等价的,比如下方的向量都是等价的:
也就是说平移完全不改变一个向量本身的任何性质,仅改变了向量所处的空间位置,向量本身并不要求从原点开始,原点仅仅只是一个观察的位置,我们习惯将向量平移到原点进行观察,因为此时可以将向量分解到坐标轴上进行方便的处理。既然原点仅仅只是一个观察位置,也就是说原点本身也是可以移动的,相对应的,坐标轴也可以进行移动,但是无论从哪一个原点进行观察,同一个向量的大小和方向都是不会改变的,因为这是向量的基本属性。
编程部分
本节的理论部分比较复杂,但是复杂的主要是几何知识,涉及到的计算反而是非常少的,因此并没有很复杂的程序算法需要设计,首先我们得表示出任意维度的向量,其次要实现向量加法与向量数乘并实现运算规律,最后由于线性方程组与向量方程之间是可以互相转换的,因此我们要实现二者的相互转换。
首先是向量的表示,由于向量可以被视为单列矩阵,因此显然可以使用数组表示,由于还要实现向量加法与向量数乘,因此考虑设计一个向量类,使用类对象表示单个向量,利用运算符重载实现直观的向量加法与向量数乘,由于算法非常简单,此处不再详细讲解,向量类实现如下:
namespace MATRIX_MOD
{
using PUBLIC_MOD::MyVector;
class Vector
{
public:
//向量数乘
friend Vector operator*(Vector& v, double num);
friend Vector operator*(double num, Vector& v);
Vector(){};
Vector(MyVector vector)
: _vector(std::move(vector))
{
}
Vector(Vector &vector)
{
_vector = vector._vector;
}
Vector(Vector &&vector) noexcept
{
_vector = std::move(vector._vector);
}
Vector &operator=(Vector vector)
{
_vector = std::move(vector._vector);
return *this;
}
Vector &operator=(Vector &&vector) noexcept
{
_vector = std::move(vector._vector);
return *this;
}
void ShowVector()
{
std::cout << "One Vector: " << std::endl;
for (int i = 0; i < Size(); i++)
{
std::cout << "[" << std::setw(3) << std::setprecision(3) << _vector[i] << "]" << std::endl;
}
}
void operator*=(double d)
{
for(int i = 0; i < Size(); i++)
{
_vector[i] += d;
}
}
// 向量加法
Vector operator+(Vector& vector)
{
Vector tmp(*this);
tmp+=vector;
return std::move(tmp);
}
void operator+=(Vector& vector)
{
if (_vector.size() != vector.Size())
{
std::cout << "Can not add" << std::endl;
exit(1);
}
for (int i = 0; i < Size(); i++)
{
_vector[i] += vector._vector[i];
}
}
size_t Size() const
{
return _vector.size();
}
private:
MyVector _vector;
};
Vector operator*(Vector& v, double num)
{
Vector tmp(v);
tmp*=num;
return std::move(tmp);
}
Vector operator*(double num, Vector& v)
{
return v*num;
}
}
测试用例如下:
static void VectorTest()
{
Vector v1({1, 2, 3});
Vector v2({0, 2, 1});
Vector v3 = 2 * (v1 + v2) + v2;
v3.ShowVector();
}
通过简单的口算,可以得出答案是:(2,10,9)(2, 10, 9)(2,10,9),测试结果如下:
结果正确,下面来实现矩阵与向量之间的互相转换,首先是将矩阵转换为向量表示,函数实现如下:
// 将矩阵转换为向量表示
static Vectors MatrixToVectors(matrix &m)
{
Vectors ret;
int row_sz = m.size();
int col_sz = m[0].size();
for (int col = 0; col < col_sz; col++)
{
MyVector mv;
mv.reserve(row_sz);
for (int row = 0; row < row_sz; row++)
{
mv.push_back(m[row][col]);
}
ret.push_back(mv);
}
return ret;
}
测试代码如下:
static void TestMatrixToVector()
{
matrix m = {{1, 2, 3}, {3, 3, 3}, {0, 0, 4}};
Vectors vs = UTIL_MOD::MatrixUtil::MatrixToVectors(m);
for (int i = 0; i < vs.size(); i++)
{
vs[i].ShowVector();
}
}
结果如下:
最后是将一组向量转换为矩阵表示,代码如下:
// 将一组向量转换为矩阵表示
static matrix VectorsToMatrix(Vectors &&vs)
{
int col_sz = vs[0].Size();
for (int i = 1; i < vs.size(); i++)
{
if (vs[i].Size() != col_sz)
{
std::cout << "Can not change" << std::endl;
exit(1);
}
}
int row_sz = vs.size();
matrix ret;
for (int row = 0; row < row_sz; row++)
{
std::vector<double> tmp;
tmp.reserve(col_sz);
for (int col = 0; col < col_sz; col++)
{
tmp.push_back(vs[col][row]);
}
ret.emplace_back(std::move(tmp));
}
return ret;
}
测试用例如下:
static void TestVectorsToMatrix()
{
Vector v1({1, 2, 3}); // 1 3
Vector v2({3, 4, 1}); // 2 4
Vector v3({0, 3, 9}); // 3 1
v1.ShowVector();
v2.ShowVector();
v3.ShowVector();
matrix m = UTIL_MOD::MatrixUtil::VectorsToMatrix({v1, v2, v3});
UTIL_MOD::MatrixUtil::ShowMatrix(m);
}
结果如下:
本节函数的算法都不复杂,但是语法挺复杂的,本系列文章不是讲语法的,因此不做详细的分析,如果像学习具体的语法,可以去看看笔者其它系列的文章,至此本节结束,看似简单的向量水却是非常的深,在推理时笔者明显可以感觉到知识的边界,最后希望这篇文章能够给读者一些启发。
更多推荐








所有评论(0)