http://222.179.234.149/eol/common/blog/index.jsp?blogid=2924
矩阵在初等行变换下的标准型
一、矩阵在初等行变换下的标准型---行标准型
m×n矩阵A=
a11 a12 ... a1n
a21 a22 ... a2n
... ... ... ...
am1 am2 ... amn
的行标准形式是满足一定条件的特殊上三角形, 例如:
0 1 2 3 0 0 0 0
0 0 0 1 -3 2 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
需要满足的条件为:
1. 仅前r行非0, 其中某r列构成单位阵E,其余各列构成 r×s矩阵B, s=n-r.
2. 对应于E的任一个非零元素, 1,不仅其所在列只有一个非零, 而且其所在行的左边全部为0.
行标准型是特殊的阶梯形, 称为(标准)阶梯型.
经过列的简单交换Q,A成为
E B
0 0
其中E是r阶单位阵, 下边是n-r行0. B是 r×s 矩阵.
并且在交换列的过程中, E对应的列先后顺序不变. 加入E对应A的j1,j2,...,jr列, 则 jk≥k.
标准型中, E对应于阶梯顶点.
二、行标准型的例子
1. 简单的例子是分成4块的m×n矩阵
E B
0 0
其中E是r阶单位阵, 下边是m-r行0. B是 r×(n-r) 矩阵.
2. 稍微复杂一点的例子是E、B的若干列交错情况. 例如
1 1 0 0 0
0 1 0 1 0
此时E对应于1,4列.
但此时要通过进一步实施行变换, 以便满足限制2:
1 0 0 -1 0
0 1 0 1 0
此时E对应于1,2列。
可以看出,标准型中, E总是对应于阶梯顶点.
3. 具有一般性的例子:
1 0 1 0 0 1
0 0 0 0 1 3
其中E对应于1,5列.
三、行标准型的性质
因为阶梯顶点1列号不小于行号, 所以A的前r行r列子阵F为E, 当且仅当F非退化 . 即
性质① 若A的行标准型是
F B
0 0
F是r×r子阵. 那么 F=E 当且仅当 F满秩.
性质② 如果A=(B C), B为满秩m×r阵, 则A的行标准型为(F D), 其中F的前r行为r×r单位阵, 其余元素为0.
性质③ 如果A的行标准型是B, 那么A的任何包含B的顶点所在列的子阵, 行标准型也B的包含顶点所在列的子阵.
性质④ 如果A的行标准型是B,PA=B, a 为A的包含B的顶点所在列的子阵, 则a的行标准型为等价标准型F, 并且Pa=F.
* 等价标准型即
Er 0
0 0
四、行标准型的存在性
行标准型基本上就是分成4块的m×n矩阵
E B
0 0
在下面的例子中,E可取为1,4列:
1 1 3 0 0
0 0 1 1 0
但此时违背限制条件2,需要进一步实行变换,化为
1 1 0 -3 0
0 0 1 1 0
此时E对应于1,3列。
可以看出,通过实施行变换,阶梯型总是可以规范化,即满足限制条件2.
百度主页对于数学格式支持较差,因此转到 http://222.179.234.149/eol/common/blog/index.jsp?blogid=2924 继续......
严格说明行标准型的存在性并不难,可以使用归纳法。
从r=0开始, r=0表示第一行,
[i] 如果a11≠0, 则利用初等行变换把它化为1, 同时把第一列其余元素化0.
[ii] 如果a11=0, 则检查第一列, 遇到有非0元素, 交换到第一行.转到[i].
[iii] 如果第一列全部为0, 则检查第二列, 如此直到遇到非0元, 换到第一行. 针对首先发现非0元的列, 实施变换[i].
如果没有非0元, 那么A=0, 已经是标准型.
否则行号 r加1, 针对A的 m-r 行子句中, 重复上述步骤. 但是注意, 步骤[i]中化0操作要针对原矩阵A执行, 而不是仅处理r行以下的子阵.
如果A只有1行, 那么这种操作显然导致A的标准型. 否则, 先处理第1行,然后假设从第2行开始的子矩阵化为标准型, 归纳得到A的标准型.
归纳假设前r-1行已经成为标准阶梯型,如果A不足r行,或者r行以后全部为0, 那么A就是标准阶梯型了。
现在然后考虑第r行的第一个非0元素ars. 如果ars上方有顶点元素,则可以把ars化为0, 然后继续讨论。
如果r行全部为0了,则考虑下边的行,并且必要时把下边的行移动成为第r行。
现在假设ars上方没有顶点元素, 可以简单地把ars化为1, 并把s列其余元素化0, 得到标准阶梯型。
下边通过具体例子说明上述证明过程:
2 0 4 0 0 0 0 0
1 0 2 -1 -1 3 12 -5
0 0 0 1 3 0 0 5
-1 0 -2 0 0 2 8 0
1、 ====>
1 0 2 0 0 0 0 0
0 0 0 -1 -1 3 12 -5
0 0 0 1 1 0 0 5
0 0 0 0 0 2 8 0
2、 第3行加于第2行,然后交换2、3行 ====>
1 0 2 0 0 0 0 0
0 0 0 1 1 0 0 5
0 0 0 0 0 3 12 0
0 0 0 0 0 2 8 0
3、====>
1 0 2 0 0 0 0 0
0 0 0 1 1 0 0 5
0 0 0 0 0 1 4 0
0 0 0 0 0 2 8 0
4、====>
1 0 2 0 0 0 0 0
0 0 0 1 1 0 0 5
0 0 0 0 0 1 4 0
0 0 0 0 0 0 0 0
化标准型,实际过程可以灵活一些,不严格按照证明中的步骤进行。如前例第2步。
五、行标准型的唯一性
如果A有一个行标准型 (E B), 那么A的所有行标准型都是(E B).
证明: 设(F C)是A的任一其他标准型, 则有行变换P,Q, 使得 A=P(E B) = Q(F C) . Q(F C)=P(E B) ==> P=QF, PB=QC ==> P=Q, B=C.
一般情况证明关键如下.
设A为m×n矩阵, 不妨假设A满秩. 设A有两个行标准型B,C,相应的行变换为P,Q.
仅考虑A的对应于标准型顶B的点的列, 同时再添加包含C的顶点的列, 所构成的子矩阵a, 则Pa=(E D). Qa=(F G). ===>
PE=QF, P=Q, B=C.
即A的任意两个行标准型相同.
六、行标准型的实现代码
更新: Eqt.rar
关键代码:注意, 正确复制代码需要打开编辑页面.
// trizw, 梯形化矩阵A, 同时记录过程 P. 返回 r(A). D3DXMatrixInverse
// 注意: P 初始化必须令*P =0, 所返回内存指针通过 delete[] 释放.
// 调用方法示例: float* p=0; trizw(... , p);
// 参考:
// 1. HRESULT CreateDevice(..., IDirect3DDevice9** ppReturnedDeviceInterface);
// 2. FormatMessage(..., LPTSTR lpBuffer, ...);
int trizw(float*A, int m, int n, float*& P){ if(!A) return 0;
if(!P){
P=(float*)LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT,m*m*sizeof(float)); // *(float**)P=po;
// P=new float[m*n*sizeof(float)]; // 也可以
for(int i=0; i<m; glloadmatrixf
// printf("P0=\n"); show_matrix(P,m, m); printf("\n");
} // if(!*P)
static int r=0; // 递归过程中, 矩阵的秩 r 起着关键作用...
if(r>=m) return r;
float t, *p, *q, *s; int i,j,k,u;
for(j=r; j<n; span="" 开始仍然可能会遇到(r,r)之下全部为0的列.<="" 列开始.="" j="r" 从="" j++){="">
p=A+r*n+j; // 指r行j列元素 A[r,j]
for(i=r; i
if(*p!=0){ // break
if(i!=r){ q=A+r*n+j; s=A+i*n+j; // 交换 r、i行. 可以从第 j 列开始.
for(k=j; k<n; t="*q;" span="" }<="" s++;="" q++;="" *s="t;" *q="*s;" {="" k++)="">
for(k=0; k<m; t="P[r*m+k]; " span="" {="" k++)="" m×m="" <="" 并且注意p阶是="" 这里不可以从j列开始,="" ......="" 初等变换="" 记录1,="" }="" p[i*m+k]="t;" p[r*m+k]="P[i*m+k];">
} // if(i!=r)
t=A[r*n+j]; q=A+r*n+j;
for(k=j; k<n; span="" k++)="" 改变了a[r,j]的值.<="" a[r,j].="" 行除以="" r="" *q++="">
for(k=0; k<m; span="" k++)="" m×m="" <="" 并且注意p阶是="" 这里不可以从j列开始,="" p[r*m+k]="" ...="" 记录2="">
break; // from for i.
} // if(*p!=0)
p+=n;
} // for i
if(A[r*n+j]!=0){ // 用 A[r,j]=1 将 j-列其他元素化0, 即除r行外,各行减去r行*A[r,j]. 且跳出 for j 循环.
for(k=0; k<m; {="" k++)="" continue;=""
t=A[k*n+j]; // 其他行减去r行的适当倍数.
for(u=j; u<n;u++) span="" 从="" 因为r行j列之前为0<="" u="j列开始," a[k*n+u]-="A[r*n+u]*t; ">
for(u=0; u<m;u++) span="" ...="" u="0" 不同<="" [m×n]="" 可能与a的="" 阶,="" m×m="" 注意p是="" 列开始,="" 这里必须从="" 记录3="" p[k*m+u]-="P[r*m+u]*t; ">
} // for u
r++; break; // from for j. 必须 break from for(j).
} // if(A[r*n+j]!=0)
} // for j
if(j==n) return r; // 情况 break 没有发生.
static int ic=0; ic++; \
printf("A%d=(Rank=%d)\n", ic,r); show_matrix(A,m, n,3); printf("\n"); \
//printf("P%d=\n", ic); show_matrix(P,m, m); printf("\n");
return trizw(A,m,n,P);
}