写作业时算行阶梯形矩阵想偷懒一下,一时兴起写的R代码。
需要的函数:
#确认一个向量中第1个非零元素前0的个数
test_0<-function(z){
s=0
for (i in z){
if (i) {break}else{s=s+1}
}
return(s)
}
#根据第一个非零元素前0的个数,对行进行重新排序
rerank<-function(B){
p<-apply(B, 1, test_0)
p<-order(p)
q=1;C<-B
for (i in p){
C[q,]=B[i,];q=q+1
}
return(C)
}
#将矩阵A的第k列的第i和第j行减为0的函数,默认保留第i行
minus<-function(A,k,i,j){
if (A[i,k]!=0&A[j,k]!=0) {
a<-A[i,]*A[j,k]-A[j,]*A[i,k]
A[j,]<-a
return(A)
} else {
return(A)
}
}
#最终的函数
rowmat<-function(A){
k=1;i=1
while (k<ncol(A)&i<nrow(A)) {
A<-rerank(A)
if (i==5) {break}else{
for (j in (i+1):nrow(A)) A<-minus(A,k,i,j)
}
i=i+1;k=k+1
}
A<-rerank(A)
#行数大于列数时,秩小于行数,多出的那几行应该都为0
if (nrow(A)>ncol(A)) A[nrow(A),]=diag(ncol(A))[1,]*0
A<-rerank(A)
return(A)
}
进一步改善
如果你需要再简化一些,可使用求最大公约数的函数gcd()
#求最大公约数的函数gcd()
gcd<-function(l){
#返回除0以外的最小值,并考虑负数的出现
s<-abs(min(l[l!=0]))
i=1
while (i<=length(l)){
if (l[i]%%s!=0) {
i=1;s=s-1
}else{
i=i+1
}
}
return(s)
}
测试一下:
A<-matrix(c(1,2,3,4,1,1,3,4,1,1,3,8,9,0,3,2,0,2,0,3),5,4,byrow = T)
B<-rowmat(A)
l<-apply(B, 1, gcd)
for (i in 1:nrow(B)) B[i,]=B[i,]/l[i]
还需改进之处
行阶梯形矩阵不唯一,如果还想得到行最简形矩阵,可能还要自己再处理一下,对于行最简形如何求,还在考虑中。
最近才刚刚学的R,写的还是比较生涩,代码还不是很简练。