在R

时间:2016-11-26 00:36:08

标签: r recursion matrix matrix-inverse

我对线性代数很新,我正在尝试实现一个递归函数,它可以反转任何矩阵 在不使用R库的情况下从头开始逐块反演技术"解决"。

以下帖子已经回答了这个问题:function for matrix

然而,它对我不起作用,我试图实现我自己的版本:

matrixInversion <- function(M){
   if(nrow(M) == 2){
      a <- M[1,1]
      b <- M[1,2]
      c <- M[2,1]
      d <- M[2,2]
      deter <- ((a*d)-(b*c))
      InverseMatrix <- ((1/deter)*matrix(c(d,-c,-b,a),nrow=2,ncol=2))
   } else {
      x <- (floor(nrow(M) / 2))
      A <- M[1:x, 1:x, drop=F]
      B <- M[1:x, -1:-x, drop=F]
      C <- M[-1:-x, 1:x, drop=F]
      D <- M[-1:-x, -1:-x, drop=F]

      Ainv <- matrixInversion(A)
      common <- matrixInversion(D - C %*% Ainv %*% B)
      newA <- Ainv+Ainv%*%B%*%common%*%C%*%Ainv
      newB <- (-Ainv)%*%B%*%common
      newC <- (-common)%*%C%*%Ainv
      newD <- (-common)

      result <- cbind(rbind(newA, newC), rbind(newB, newD))
    }
}

此版本适用于具有偶数列的矩阵,但不适用于具有奇数列的矩阵。我无法理解如何正确实现它。有什么建议吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

除了评论中提出的观点外,您还错误地否定了newD。现在,带有更改的函数适用于奇数行和偶数行矩阵:

matrixInversion <- function(M){
  if (nrow(M) == 1){
    return(1/M)
  } else if (nrow(M) == 2){
    a <- M[1,1]
    b <- M[1,2]
    c <- M[2,1]
    d <- M[2,2]
    deter <- ((a*d)-(b*c))
    return((1/deter)*matrix(c(d,-c,-b,a),nrow=2,ncol=2))
  } else {
    x <- (floor(nrow(M) / 2))
    A <- M[1:x, 1:x, drop=F]
    B <- M[1:x, -1:-x, drop=F]
    C <- M[-1:-x, 1:x, drop=F]
    D <- M[-1:-x, -1:-x, drop=F]
    Ainv <- matrixInversion(A)
    common <- matrixInversion(D - C %*% Ainv %*% B)
    newA <- Ainv+Ainv%*%B%*%common%*%C%*%Ainv
    newB <- (-Ainv)%*%B%*%common
    newC <- (-common)%*%C%*%Ainv
    newD <- common
    return(cbind(rbind(newA, newC), rbind(newB, newD)))
  }
}

## random seed not relevant here ...
m1 <- matrix(runif(150^2), nr=150)
all.equal(solve(m1), matrixInversion(m1))
# [1] TRUE
any(is.nan(matrixInversion(m1))) # based on your comment
# [1] FALSE

m2 <- matrix(runif(151^2), nr=151)
all.equal(solve(m2), matrixInversion(m2))
# [1] TRUE
any(is.nan(matrixInversion(m2)))
# [1] FALSE

为了记录,我通过逐步检查更大的矩阵来发现这一点。类似的东西:

m1 <- matrix(runif(150^2), nr=150)
i <- 4; all.equal(solve(m1[1:i,1:i]), matrixInversion(m1[1:i,1:i]))

2,它是平等的,它开始超越它。我使用debugonce(matrixInversion)检查前两个条件块,但它们没问题。然后我将您的方程与最初引用的wiki-page进行了比较,并注意到您的计算结果不正确。当然,这是我检查的最后一个: - )