【问题标题】:Create matrix with for-loop用for循环创建矩阵
【发布时间】:2020-01-02 13:46:31
【问题描述】:

我正在尝试为 n 行和 n+1 列创建以下矩阵 A。 n 可能在 20 或 30 左右,但出于问题的目的,我将其放在 4 和 5 之间。

这是我目前所拥有的:

N <- 5             # n+1
n <- 4             # n
columns <- list()

# first column:
columns[1] <- c(-1, 1, rep(0, N-2))

# all other columns:
for(i in N:2) { 
 columns[i] <- c((rep(0, N-i), 1, -2, 1, rep(0, i-3)))
}

# combine into matrix:

A <- cbind(columns)

我不断收到以下错误消息:

In columns[1] <- c(-1, 1, rep(0, N - 2)) :
  number of items to replace is not a multiple of replacement length

后来

"for(i in N:2) { 
  columns[i] <- c((rep(0, N-i),"
 }
Error: unexpected '}' in "}"

【问题讨论】:

  • 您是否有理由为此特别需要一个 for 循环?
  • 不,不一定是 for 循环,而是自动化的东西,我可以指定 n 并创建矩阵。接受其他想法...

标签: r for-loop matrix


【解决方案1】:
  • 我想你可以试试下面的for 循环来创建你的矩阵A
N <- 5
n <- 4
A <- matrix(0,n,N)
for (i in 1:nrow(A)) {
  if (i == 1) {
    A[i,1:2] <- c(-1,1)
  } else {
    A[i,i+(-1:1)] <- c(1,-2,1)
  }
}

这样

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]   -1    1    0    0    0
[2,]    1   -2    1    0    0
[3,]    0    1   -2    1    0
[4,]    0    0    1   -2    1
  • 另一个解决方案是使用outer,这种方法比for循环方法更快,看起来更紧凑,即,
A <- `diag<-`(replace(z<-abs(outer(1:n,1:N,"-")),!z %in% c(0,1),0),
              c(-1,rep(-2,length(diag(z))-1)))

【讨论】:

    【解决方案2】:

    我认为这与循环相比会更快,但是当我在 5000x5001 示例上进行测试时,ThomasIsCoding 的答案中的循环大约快 5 倍。和那个一起去!

    N = 5
    n = N - 1
    
    A = matrix(0, nrow = n, ncol = N)
    
    delta = row(A) - col(A)
    
    diag(A) = -2
    A[delta %in% c(1, -1)] = 1
    A[1, 1] = -1
    A
    #      [,1] [,2] [,3] [,4] [,5]
    # [1,]   -1    1    0    0    0
    # [2,]    1   -2    1    0    0
    # [3,]    0    1   -2    1    0
    # [4,]    0    0    1   -2    1
    

    【讨论】:

      【解决方案3】:

      您可以使用 data.table::shift 将向量 c(1, -2, 1, 0) 从 -1(向后移位 / 前移 1)移动到 n - 1(前移 / 滞后 n - 1),然后 cbind 所有移位的一起输出。第一行第一列元素不遵循此模式,因此在最后固定。

      library(data.table)
      
      out <- do.call(cbind, shift(c(1, -2, 1, 0), seq(-1, n - 1), fill = 0))
      out[1, 1] <- -1
      
      out
      #      [,1] [,2] [,3] [,4] [,5]
      # [1,]   -1    1    0    0    0
      # [2,]    1   -2    1    0    0
      # [3,]    0    1   -2    1    0
      # [4,]    0    0    1   -2    1
      

      【讨论】: