用递归函数实现R
我对线性代数非常陌生,我正在尝试实现一个递归函数,该函数使用 无需使用R库“solve”即可从头开始的分块反演技术 以下帖子已经回答了这个问题: 但是,它对我不起作用,我尝试实现我自己的版本:用递归函数实现R,r,recursion,matrix,matrix-inverse,R,Recursion,Matrix,Matrix Inverse,我对线性代数非常陌生,我正在尝试实现一个递归函数,该函数使用 无需使用R库“solve”即可从头开始的分块反演技术 以下帖子已经回答了这个问题: 但是,它对我不起作用,我尝试实现我自己的版本: matrixInversion <- function(M){ if(nrow(M) == 2){ a <- M[1,1] b <- M[1,2] c <- M[2,1] d <- M[2,2] deter &
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))
}
}
matrixInversion除了评论中的观点外,您还错误地否定了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
matrixInversion您能否提供(a)样本数据(工作和不工作),以及(b)错误或故障?我的第一个猜测是它与nrow(M)==2
有关。对于奇数行数矩阵,对matrixInversion
的第三次调用发送1x1矩阵,使第一个条件失败,并尝试再次对矩阵进行分区。(使用它可以处理:M=matrix(rnorm(4^2),4,4),但不能处理M2=matrix(rnorm(5^2),5,5)。两件事。(1)“它可以处理…但不能处理…”。通过在本地运行代码,我想我知道发生了什么,但您的问题不包括您看到的内容。(2)不管怎样,问题是你的函数错误地处理了1x1矩阵。解决了这个问题,你应该会很好。嗨!对不起,这是我在运行M2=矩阵(rnorm(5^2),5,5)时的输出:错误:计算嵌套太深:无限递归/选项(表达式=)?封装期间的错误:计算嵌套太深:无限递归/选项(表达式=)?我还包括了一个额外的if,用于通过包括以下条件来求解1x1矩阵:if(nrow(M)==1){InverseMatrix
m1 <- matrix(runif(150^2), nr=150)
i <- 4; all.equal(solve(m1[1:i,1:i]), matrixInversion(m1[1:i,1:i]))