簡體   English   中英

將矩陣對角線轉換為r的高效算法

[英]Efficient algorithm to turn matrix subdiagonal to columns r

我有一個非正方形矩陣,需要對其次對角線進行一些計算。 我發現最好的方法是將對角線也轉換為列/行,並使用cumprod之類的函數。 現在,我使用for循環和exdiag定義如下:

exdiag <- function(mat, off=0) {mat[row(mat) == col(mat)+off]}

但是,它並不是真正有效的。 您是否知道其他任何算法可以達到這種效果。

一個小例子來說明我在做什么:

exdiag <- function(mat, off=0) {mat[row(mat) == col(mat)+off]}
mat <- matrix(1:72, nrow = 12, ncol = 6)
newmat <- matrix(nrow=11, ncol=6)
for (i in 1:11){
   newmat[i,] <- c(cumprod(exdiag(mat,i)),rep(0,max(6-12+i,0)))
}

最好的問候,阿圖爾

您可以修改diag()函數。

exdiag <- function(mat, off=0) {mat[row(mat) == col(mat)+off]}

exdiag2 <- function(matrix, off){diag(matrix[-1:-off,])}

速度測試:

mat = diag(10, 10000,10000)

off = 4

> system.time(exdiag(mat,4))

  user  system elapsed 
  7.083   2.973  10.054 

> system.time(exdiag2(mat,4))

   user  system elapsed 
  5.370   0.155   5.524 

> system.time(diag(mat))

   user  system elapsed 
  0.002   0.000   0.002

看起來矩陣的子集需要花費很多時間,但是它的性能仍然比您的實現更好。 可能還有很多其他子設置方法,這些方法優於我的解決方案。 :)

要從非正方形矩陣中獲取所有可能的對角線,最快,但到目前為止最隱秘的解決方案是將矩陣視為向量,並簡單地構造一個id向量以進行選擇。 最后,您可以根據需要將其轉換回矩陣。

以下功能可以做到這一點:

exdiag <- function(mat){

  NR <- nrow(mat)
  NC <- ncol(mat)
  smalldim <- min(NC,NR)
  if(NC > NR){
    id <- seq_len(NR) + 
      seq.int(0,NR-1)*NR +
      rep(seq.int(1,NC - 1), each = NR)*NR


  } else if(NC < NR){
    id <- seq_len(NC) + 
      seq.int(0,NC-1)*NR +
      rep(seq.int(1,NR - 1), each = NC)

  } else {
    return(diag(mat))
  }
  out <- matrix(mat[id],nrow = smalldim)
  id <- (ncol(out) + 1 - row(out)) - col(out) < 0
  out[id] <- NA
  return(out)
}

請記住,您必須考慮矩陣的形成方式。

在兩種情況下,我都遵循相同的邏輯:

  • 首先構造一個序列,指示沿最小維度的位置
  • 對於此序列,將行長度加0、1、2,...。

這將創建第一個對角線。 完成此操作后,您只需添加一個序列即可將整個先前序列移位1(向下或向右),直到到達矩陣的末尾。 要右移,我需要將此序列乘以行數。

最后,您可以使用這些索引從墊中選擇正確的位置,並將所有結果作為矩陣返回。 由於此代碼的矢量化性質,您必須檢查最后一個對角線是否正確。 這些元素包含的元素少於第一個元素,因此您必須用NA替換不屬於該對角線的值。 同樣在這里,您可以簡單地使用索引技巧。

您可以按以下方式使用它:

> diag1 <- exdiag(amatrix)
> diag2 <- exdiag(t(amatrix))
> identical(diag1, diag2)
[1] TRUE

為了得出您的結果

amatrix <- matrix(1:72, ncol = 6)
diag1 <- exdiag(amatrix)
res <- apply(diag1,2,cumprod)
res[is.na(res)] <- 0
t(res)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM