R语言求解矩阵极大无关组并检验是否线性相关

刚上手R一个月,前两天为了交作业实现了极大无关组的求解,看网上并没有相关的代码所以分享一下。不足之处还有很多,希望各位大佬多多指教~

求解的大体思想就是化阶梯形,并且把每个阶梯的第一个元素的索引取出,利用索引得到原矩阵的一组极大无关组,验证是否线性无关只需要利用索引得到化为阶梯形后的子矩阵,子矩阵的秩是否为Min{行秩,列秩}

求解方法改进了一下选取列主元的高斯消去法,在其基础上为列主元的坐标定位指针[i, j],这样可以判断对该列进行高斯消去之后,下一列的主元位置和该列的主元位置,是在同一行还是在同一对角线上。倘若这两列线性相关则在同一行平移,若线性无关则对角线移动。

先简单介绍一下列主元高斯消元法,估计高斯看了棺材板会盖不住的。

在化阶梯形的过程中,比如从A[1, 1](不等于0)开始,将A[i, 1](i = 2, 3, 4....)的元素都化为0,这个过程就是在实现高斯消元。在消元的过程中,被用来消其他元素的那个元素叫做主元。而列主元的高斯消去法指的是每一列消元时,都选择本列绝对值最大的元素作为主元,并把那一行换到指针所在的位置。

为什么在列主元的高斯消去法里没有提指针的事请呢?因为它常用来实现n阶方阵的LU分解,指针默认方向是对角线,不用考虑横向平移的过程。

话不多说分享代码~

 

清空变量,导入数据清洗包dplyr

rm(list = ls())
library(dplyr)

定义行交换函数

# Reorder rows
rarrange = function(dtf, i1, i2){
  dtf.i1 = dtf[i1, ]
  dtf[i1, ] = dtf[i2, ]
  dtf[i2, ] = dtf.i1
  return(dtf)
}

主题函数部分,tg.tick是主元所在的行标,貌似which可以直接获取行标行交换更方便

(为了逻辑而放弃了美观,在函数体里加了注释,原谅一只菜鸡)

# Function
MLIG = function(mtx){
  mdtf = as.data.frame(mtx)
  i = 1
  j = 1
  tg.tick = i
  m = dim(mdtf)[1]
  n = dim(mdtf)[2]
  index = NA
  while ((i <= (m-1)) & (j <= n)){
    colmax = mdtf[i, j]
    
# Find column principal and row.numbers it is in
    for (t in (i+1) : m){
      if (abs(as.numeric(mdtf[t, j])) > abs(as.numeric(colmax))){
        colmax = abs(as.numeric(mdtf[t, j]))
        tg.tick = t
      }else{
        tg.tick = i
      }
    }
    
# If column principal not equal to mdtf[i, j], no arrange operations
    if (as.numeric(colmax) != mdtf[i, j]){
      mdtf = rarrange(mdtf, i, tg.tick)
    }else{}
    
# If column principal not equal to zero
    if (colmax != 0){
      for (t in (i+1):m){
        k = mdtf[t, j] / mdtf[i, j]
        mdtf[t, j:n] = mdtf[t, j:n] - mdtf[i, j:n]*k
      }
      index = c(index, j)
      i = i + 1
      j = j + 1
    }else{
      j = j + 1
    }
  }
  index = na.omit(index)
  result.dtf = select(as.data.frame(mtx), index)
  check.dtf = mdtf
  return(list(result.dtf = result.dtf, check.dtf = check.dtf))
}

用两个矩阵检验效果

# Effect test
MLIG(matrix(1:24, 4, 6))
MLIG(matrix(sample(1:10, 30, replace = T), 5, 6))

运行结果为

> MLIG(matrix(1:24, 4, 6))
$result.dtf
  V1 V2
1  1  5
2  2  6
3  3  7
4  4  8

$check.dtf
  V1 V2 V3 V4 V5 V6
1  4  8 12 16 20 24
2  0  3  6  9 12 15
3  0  0  0  0  0  0
4  0  0  0  0  0  0

> MLIG(matrix(sample(1:10, 30, replace = T), 5, 6))
$result.dtf
  V1 V2 V3 V4
1  4  5  6  7
2  9  7  3  8
3  7  2  7  9
4  9  4  4  9
5  7  3  8  4

$check.dtf
  V1    V2        V3        V4        V5         V6
1  4  5.00   6.00000  7.000000  6.000000  4.0000000
2  0 -4.25 -10.50000 -7.750000 -4.500000 -5.0000000
3  0  0.00  13.17647  9.058824  6.647059  7.9411765
4  0  0.00   0.00000 -5.812500 -1.316964  0.7098214
5  0  0.00   0.00000  0.000000 -5.222734 -1.4562212

 

你可能感兴趣的:(R)