8

大きな mxn 行列があり、線形従属列を特定しました。ただし、線形に依存する列を線形に独立した列で記述する方法が R にあるかどうかを知りたいです。大行列ですので、検査に基づいて行うことはできません。

これは、私が持っているマトリックスのタイプのおもちゃの例です。

> mat <- matrix(c(1,1,0,1,0,1,1,0,0,1,1,0,1,1,0,1,0,1,0,1), byrow=TRUE, ncol=5, nrow=4)
> mat
      [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    1    0
[2,]    1    1    0    0    1
[3,]    1    0    1    1    0
[4,]    1    0    1    0    1

ここで、x3 = x1-x2、x5=x1-x4 であることは明らかです。より大きなマトリックスに対してそれを取得する自動化された方法があるかどうかを知りたいです。

ありがとう!

4

1 に答える 1

9

もっと良い方法があると確信していますが、これで遊んでみたいと思いました。基本的に、入力行列がフル ランクの場合に不要な計算を避けるために、最初にチェックを行い、入力行列がフル ランクであるかどうかを確認します。その後、最初の 2 つの列から始めて、そのサブマトリックスが完全な列ランクであるかどうかを確認し、そうであれば最初の 3 つの列を確認します。完全な列ランクではない部分行列を見つけたら、その部分行列の最後の列を前の列に回帰させて、最初の列の線形結合を構築して最後の列を取得する方法を示します。

私の関数は今のところあまりきれいではなく、追加のチェックを行うことができますが、少なくともそれは始まりです.

mat <- matrix(c(1,1,0,1,0,1,1,0,0,1,1,0,1,1,0,1,0,1,0,1), byrow=TRUE, ncol=5, nrow=4)


linfinder <- function(mat){
    # If the matrix is full rank then we're done
    if(qr(mat)$rank == ncol(mat)){
        print("Matrix is of full rank")
        return(invisible(seq(ncol(mat))))
    }
    m <- ncol(mat)
    # cols keeps track of which columns are linearly independent
    cols <- 1
    for(i in seq(2, m)){
        ids <- c(cols, i)
        mymat <- mat[, ids]
        if(qr(mymat)$rank != length(ids)){
            # Regression the column of interest on the previous
            # columns to figure out the relationship
            o <- lm(mat[,i] ~ mat[,cols] + 0)
            # Construct the output message
            start <- paste0("Column_", i, " = ")
            # Which coefs are nonzero
            nz <- !(abs(coef(o)) <= .Machine$double.eps^0.5)
            tmp <- paste("Column", cols[nz], sep = "_")
            vals <- paste(coef(o)[nz], tmp, sep = "*", collapse = " + ")
            message <- paste0(start, vals)
            print(message)
        }else{
            # If the matrix subset was of full rank
            # then the newest column in linearly independent
            # so add it to the cols list
            cols <- ids
        }
    }
    return(invisible(cols))
}

linfinder(mat)

を与える

> linfinder(mat)
[1] "Column_3 = 1*Column_1 + -1*Column_2"
[1] "Column_5 = 1*Column_1 + -1*Column_4"
于 2012-10-26T15:19:04.383 に答える