矩阵乘法研究
1.准备
1.1什么是矩阵
百度一下:在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合 ,最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。
但是并不是很明白,所以再进一步探究一下。
1.2从二元一次方程说起
1.2.1一些概念
对于一个二元一次方程组,我们可以采用加减消元法和代入消元法来解这个方程,而这两种方法的实质就是减少未知数个数,从而求解,这种方法叫做高斯消元法(Gaussian Elimination)。
从解析几何来说,二元一次方程组的解的意义就是两条直线的交点的坐标,而当未知数指数都是1时,这个方程组通常称为线性方程组,如:
就是一个线性方程组。
而
这些都不是线性方程组。(线性方程应该也可以通过求导检验,因为一次未知数求导后就是常数了,但是也不确定对不对,暂留)
那么,当线性方程组的常数项都是0的时候,就称为齐次线性方程组,反之就是非齐次线性方程组,对于$$2x+9y=10$$即$$2x+9y-10=0$$常数项为\(-10\),所以这个是非齐次线性方程。
而$$2x+9y=0$$就是一个齐次线性方程。
1.2.2线性方程组解的类型
对于齐次线性方程组,如果解均为\(0\),那么称其只有零解,否则就称为存在非零解,而且其一定存在无穷多个非零解,也就是各个方程表示的等同于同一方程。
对于非齐次线性方程组,根据解的个数,我们分为唯一解,无穷解和无解,分别表示各个直线只有一个交点,直线重合,直线平行。
对于我们熟知的有几个未知数就要有几个方程只适用于齐次线性方程组的只有零解和非齐次线性方程组的唯一解情形。
1.3 矩阵(1)
1.3.1基础知识
首先介绍一下齐次线性方程组的一般形式:
举一个具体例子:
而我们可以发现,$$x_1+3x_2+5x_3=0\Rightarrow(1\quad 3\quad 5)·(x_1\quad x_2\quad x_3)=0 $$
每一个方程都可以转化为向量的点乘运算,所以,有:
然后,对于这么一个很整齐的式子,自然会把这些行向量转化为列向量:
左边这个长方形数表就是矩阵(Matrix),从函数方面理解,就有:
二者等价,从这里我们也能明白,线性方程组就是统一将列向量映射为另一列向量。
等式左边的矩阵称为系数矩阵用A表示,全是未知数的向量为未知数向量,右侧的向量称为结果向量,所以原式还可以表示为:
函数表示的方式也可以借此表示为:
此二者比较,可以得出:系数矩阵的功能就是将未知数向量映射到全零向量。
接下来介绍一下非齐次线性方程组的一般形式:
其中,\(b_1,...,b_m\)不全为\(0\)。
也举一个具体的例子:
转化为矩阵,为:
与齐次线性方程组类似的,也可以称为:
1.3.2用矩阵进行高斯消元法求解
先看较简单的齐次线性方程组,还是上面的那个例子,因为齐次线性方程右侧都是\(0\),所以高斯消元法不会影响其结果向量,所以只看系数向量:
于是乎,我们得到了矩阵初等行变化之1:给某行同时乘以一个非零常数\(k\)
根据自己的认识,我们也可以轻松得到矩阵初等行变化之2:交换某两行的位置,这仅仅相当于将方程组中的方程互换位置,自然等价。
假设对于一个方程组,从上至下依次记作\(A,B,C...\),箭头左侧下标为\(1\),右侧下标为\(2\),那么,\(B_2=-A_1+B_1,C_2=-2A_1+C_1\)(\(Latex\)里没找到一般用的圆圈里加数字,只能这样勉强表示一下了)。
系数向量变化如下:
于是我们得到了矩阵初等行变化之3:把某一行的\(k\)倍加到另一行上,此时已经消去下面两式子的\(x_1\),重复变化3即可继续进行高斯消元:
最后我们再把矩阵变为方程组:
令\(x_3=1\),有\(x_2=-2,x_1=1\),这是这个齐次方程组的一个解,所以它属于存在非零解。
注意:一般从最简单的方程求起,最下面的方程最简单,自底向上求出每一个未知数。
通过这个,我们又引入一个名词阶梯矩阵,如:
这是一个阶梯矩阵,中间的黑线叫做阶梯线,矩阵初等行变换的目的就是将矩阵变为阶梯矩阵。
阶梯矩阵特征为:阶梯线右侧的第一个元素不为0,阶梯线下面的所有元素为0,对应的方程组中,越靠近底部的方程越简单。
这一过程,就相当于有目的地对方程组进行高斯消元,将方程组变为容易求解的形式。
接下来是非齐次性方程组的求解,仍选取上方例子:
右侧矩阵称为增广矩阵,所有对于非齐次线性方程组,需要对增广矩阵进行初等行变换,化为阶梯矩阵。
将它进行变化(省略过程)得到:
其有无穷解。
1.4求解齐次线性方程组
需要解决问题:
1.如何判断齐次线性方程组解的情况?
2.如何求出具有无穷解方程的通解?
1.4.1 解决问题1
其实在1.3中,我们已经发现了一些“端倪”,明显当最后的阶梯矩阵有一行全为0的时候,存在非零解。我们先看看只有零解的情况:
它对应的矩阵是:
可以发现其非\(0\)行数与未知数个数相等,这样就只有零解。
而1.3中的那个齐次线性方程的阶梯矩阵为:
可以发现未知数有\(3\)个,而非\(0\)行数只有\(2\)个,所有它存在非零解,也就是有无穷解。
总结:
将系数矩阵进行初等行变换后变为阶梯矩阵,如果非\(0\)行数和未知数个数相等,则齐次线性方程组只有零解。
如果非\(0\)行数小于未知数个数,则齐次线性方程组存在非零解。
(那么如果大于呢,觉得不存在,应该还能进行初等行变换,但是不是很清楚,先搁置一下)解决见1.7
1.4.2 解决问题2
先举一个存在非零解的齐次线性方程组:
我们把\(x_3\)当作已知数,来表示其他未知数,然后就能得到:
其中令\(x_3=-4k\),对于第一个向量,可知取任意\(x_3\),都有不同的解。对于第二个纯数字向量,它们组成了齐次线性方程组的基础解系。基础解系可以按任意比例缩放,第三个纯数字向量就是通解。
但是这个太特殊了,还有不同的一种情况:
这里,我们得用\(x_2\)和\(x_3\)表示\(x_1\),有:
然后,只需要用正交赋值\((1,0)(0,1)\)即可求出通解,可以赋值别的,但是这个最方便。这里用的是二阶单位矩阵。
一些新的定义:
简化方程组中,每行第一个系数不为0的未知数称为主变量。
其余的未知数称为自由变量。
设系数矩阵为\(A\),主变量个数等于阶梯矩阵中非\(0\)行数,记为\(r(A)\)。
若未知数个数为\(n\),则自由变量的个数\(t=n-r(A)\)。
自由变量的个数就决定了用几阶的单位矩阵,\(k\)阶就是一个\(k×k\)的矩阵,其中第\(i\)行的第\(i\)个为\(1\),其余都是\(0\)。然后进行正交赋值,次数等于自由变量个数。
自由变量的个数=基础解系里包含的向量个数。
求基础解系,必须先对自由变量赋值(单位矩阵),再自底向上反解出主变量。
下面提供一个例题和解题过程:
\(\therefore\) $$n=4$$
对于
1.5求解非齐次线性方程组
1.5.1根据矩阵判断解的情况
首先,可以想象,对非齐次线性方程组进行高斯消元,相当于对增广矩阵进行初等行变换。因为无论是初等行变换1,2还是3都同时影响常数项,所以方程不会产生错误。
其增广矩阵为:
进行初等行变换后:
其有唯一解,\(r(A\mid b)=r(A)=3\),所以如果阶梯增广矩阵和阶梯系数矩阵的非0行数相等,且等于未知数个数,则非齐次线性方程组有唯一解,那看到这么多限制条件,自然也可以猜测下面的一些结论了。
再给出另一组方程:
其有无穷解,观察发现\(r(A\mid b)=r(A)=2<3\),如果阶梯增广矩阵和阶梯系数矩阵的非0行数相等,但小于未知数个数,则非齐次线性方程组具有无穷解。
再再给出另一组方程:
其无解,\(r(A\mid b)=3\ne r(A)=2\),如果阶梯增广矩阵和阶梯系数矩阵的非零行数不相等,则非齐次线性方程组无解。
1.5.2求无穷解的通解
我们还是会看无穷解的那个方程:
我们发现这个通解由两部分组成,一个带有常数\(k\),一个没有。但看前者,我们把\(x_1,x_2,x_3\)代入,发现方程左侧都为\(0\),所以这是非齐次线性方程组对应的齐次线性方程组的通解,而后者代入原方程正好成立,所以它是非齐次线性方程组的特解。特解求法一般是令自由变量都为0.
所以,非齐次线性方程组通解=齐次线性方程组通解+非齐次线性方程组特解。
1.6 思考(1)——完成P3389 【模板】高斯消元法
既然我们知道了齐次线性方程组与非齐次线性方程组的解法,那我们能不能借用这个思路编一个程序,来帮我们解一个很复杂的方程组呢?换而言之,就是在程序中用高斯消元法来解方程组。感觉可行,那么尝试尝试。不过这里求解的是非齐次线性方程组唯一解的情况,这也是我们大多数时候实际学习中遇到的情况。
第一步,我选择先读取矩阵:
const int N=800+10, INF=0x3f3f3f3f;
int in[N][N];//存放系数
int f_num,x_num;//存放方程数和一共的未知数个数
void Get(){
cin>>f_num>>x_num;
x_num++;//这里因为是非齐次线性方程组,所以是增广矩阵,还要加个常数项的位置
for(int i=1;i<=f_num;i++)
for(int j=1;j<=x_num;j++){
cin>>in[i][j];
if(in[i][j]==0)in[i][j]=INF;//将0作为最大值,是为下面排序做铺垫
}
}
第二步,根据矩阵初等行变换2,我希望将他们降序排列,但是非0系数多的排前面:
void Swap(int x,int y){
for(int i=1;i<=x_num;i++)
swap(in[x][i],in[y][i]);
}
void Sort(){
int minf=1;
bool mark[N][N];memset(mark,0,sizeof(mark));
mark[0][1]=0;
for(int i=1;i<=x_num;i++){
int minx=in[minf][i];
for(int j=2;j<=f_num;j++){
if(in[j][i]<minx&&!mark[i-1][j]){//标记希望如果前面一次已经排序过了就不要排序
mark[i][j]=1;
minx=in[j][i];
Swap(j,minf);
minf=j;
}
}
}
}
但是,很快就发现了这样并不能实现排序,于是洛谷搜题,没想到这是一个模板题,里面似乎用系数的绝对值大小来进行排序,之后就是和前文解非齐次线性方程组一样的过程。所以排序暂时不管,看看能不能写出加减消元的代码。
好的,并不能。那就先看这份题解,概括一下整体思路:写出矩阵,然后从第一个系数开始依次按系数的绝对值大小的顺序找出最大值即可,不需要排序(关键,与我的想法不同,但是这个极具合理性),之后进行加减消元,消去除了第一个方程以外的所有方程的第一个系数,然后不断重复下去,就能够得到一个系数递减的方程组(如果有唯一解)然后一步步回代即可。并不是很抽象。
鏖战半个多小时,终于AC了:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100+10, INF=0x3f3f3f3f;
int n;
double in[N][N];
void Gauss(){
int r;
for(int i=1;i<=n;i++){
r=i;
for(int j=i+1;j<=n;j++){
if(fabs(in[j][i])>fabs(in[r][i])) r=j;//加减消元产生浮点型的系数
}
if(r!=i)for(int j=1;j<=n+1;j++)swap(in[r][j],in[i][j]);
for(int j=n+1;j>i;j--){
for(int k=i+1;k<=n;k++){
if(in[i][i]!=0)
in[k][j]-=in[k][i]/in[i][i]*in[i][j];//加减消元:in[k][i]/in[i][i]表示的就是最前面那个系数的比,后面都要按这个比例才能消去第i个系数,这个比*in[i][j]就是最上面的方程按比例扩大后的第j个系数,再用原来的系数减去即可。很形象。
else{
puts("No Solution");
exit(0);
}
}
}
}
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
in[i][n+1]-=in[j][n+1]*in[i][j];//将下面已知的未知数代入方程,也就是k1x1+k2x2+...+knxn=a变为knxn=a(代码中的n+1很巧妙)
}
if(in[i][i]!=0)
in[i][n+1]/=in[i][i];//kx=b,求x
else{
puts("No Solution");
exit(0);
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
cin>>in[i][j];
}
}
Gauss();
for(int i=1;i<=n;i++)cout<<fixed<<setprecision(2)<<in[i][n+1]<<endl;
return 0;
}
不过判无解的过程是根据程序输出nan的提示改的,不明白为什么这样(以后看能不能证明)。
明白求解非齐次线性方程组的过程后,其实这个代码很好理解,十分形象。但是我们现实中一般保留分数,能否实现这个特点呢?(很明显能,只要把代码中的加减乘除全部变为分数计算,系数按分数形式记录即可,但是很麻烦(逃))。
1.7矩阵的秩
前面说到过的\(r(A)\)本质上就是矩阵的秩,对于矩阵\(A\),将其进行初等行变换后变为阶梯矩阵,阶梯矩阵的非零行数就是矩阵\(A\)的秩(Rank),记为\(r(A)\)。
注意:矩阵的秩不超过矩阵的行数,也不超过矩阵的列数。
所以,秩与线性方程组的解有下面关系:
下面讨论一些特殊的秩:
\(r(A)=0\)的矩阵:
- 如果矩阵\(A\)所有元素都是0,则它不存在非零行,\(r(A)=0\)。
- 此时称之为零矩阵,记为\(A=0\)。
- \(A=0\)与\(r(A)=0\)是等价关系(充要条件)。
\(r(A)=1\)的矩阵:
- \(r(A)=1\)的矩阵各行和各列成比例。
- 比例系数可以是0,且至少保证矩阵内有1个元素不为0。
所以,我们发现向量是只有一行或一列的矩阵。
而根据下面的式子,我们可以发现,它的秩也是1,所以对于所有不为0的向量,不论行向量还是列向量,秩都是1。
向量\(a\ne 0\)与\(r(a)=1\)相互等价(充要条件)。
1.8矩阵乘法
1.8.1 如何计算
- 线性方程组的复合
对此,我们一般采用代入法,如下:
同时,我们可以用矩阵来表示上面三个方程组:
根据最初我们知道的映射关系,又可得下面的几个式子:
所以,第三个方程组的矩阵可以是下面这个形式:
于是,三者对照可以得到下面的映射关系:
然后我们发现下面这个:
为了方便,省略中间的圆圈,得到了:
这就是矩阵乘法。
对于下面式子:
我们将左侧式子的左矩阵第一行记作\(r_{L1}\),第二行记作\(r_{L2}\),左侧式子的右矩阵的第一列记作\(c_{R1}\),第二列记作\(c_{R2}\),将等号右侧的矩阵内元素记为\(a_{11},a_{12},a_{21},a_{22}\),下标为行数+列数。于是有:
所以,令
则
记忆:左取行,右取列,对应相乘再相加,行数列数定位置。
而
说明:矩阵乘法无交换律,需要区分左矩阵和右矩阵。
再举一个例子:
我们发现\(A\)为\(2\times 3\),\(B\)为\(3\times 4\),\(AB\)为\(2\times 4\)。
归纳发现:一个\(m\times n\)的左矩阵乘以一个\(n\times s\)的右矩阵,乘积矩阵大小为\(m\times s\)。
而看\(BA\)会发现一个四维向量要与一个二维向量进行数量积运算,很明显无法进行。所以矩阵乘法有一个前提为:左矩阵的列数与右矩阵的行数相等。
再当我们回顾最初的引入矩阵部分时会发现,那时我们就已经做了矩阵乘法(((
1.8.2矩阵乘法的一些性质
(由于大多都是计算得来的,而打矩阵过于麻烦,这里只给出结论,可以通过矩阵乘法算出这些结论)
一些新的定义
\(O=\begin{bmatrix}0&0&0&0\\0&0&0&0\\0&0&0&0\end{bmatrix}\),将纯零矩阵记作\(O\)。
如果一个矩阵每个行数与列数不等的元素均为零,那么这个矩阵叫做对角矩阵。当对角矩阵非零元素都为1时,叫做单位阵,记为\(E\)。
如果\(A=\begin{bmatrix}1&2&3&4\\5&6&7&8\end{bmatrix}\),那么\(A^T=\begin{bmatrix}1&5\\2&6\\3&7\\4&8\end{bmatrix}\)
- \(A_{m\times n}B_{n\times s}=C_{m\times s}\)
- \(AB\ne BA\)
- \(AO=OA=O\)
- \(AB=O\nRightarrow A=O\ or\ B=O\)
- \(AE=EA=A\)
- \(a_{1\times n}b_{n\times 1}=\lambda(\lambda为数字,等于a和b向量的数量积运算的结果)\)
- \(a_{n\times 1}b_{1\times m}=X_{n\times m}\)
- \(r(AB)\le min\{r(A),r(B)\}\)
- \((AB)C=A(BC)\)
- \((AB)^T=B^TA^T\)
- \(A^k=A^{k-1}·A=A·A^{k-1}\quad k\in N\)
- \(A^k·A^m=A^{k+m}\quad k,m\in N\)
- \((A^k)^m=A^{km}\quad k,m\in N\)
至此,学习完毕。但是关于矩阵还有很多很多知识没学。
2.例题
所有例题的分析过程请点击链接查看。
P3390 【模板】矩阵快速幂
P5550 Chino的数列
P7318 「PMOI-4」人赢の梦
P1962 斐波那契数列
[NOI2012] 随机数生成器
P2129 L 国的战斗续之多路出击