在时间 t-1 将列表中的矩阵按顺序乘以向量(递归)
Sequentially multiply matrices from a list by a vector at time t-1 (recursively)
我正在尝试将矩阵列表相乘,按照它们在从矩阵 1 开始的列表中出现的顺序,乘以初始向量,然后递归;所以列表中的矩阵 2 乘以该结果向量。我尝试了 lapply
和 map
的各种迭代,但无法向前投影并递归执行此操作。更明确地说:A[[1]] % * % allYears[,1]
,然后是 A[[2]] % * % allYears[,2],.....,A[[4]] % * % allYears[,4]
,它在 "allYears"
中生成最后的第 5 列。下面是示例代码,在 A[[i]]
索引处的 for 循环中存在已知错误,因为未明确引用 i
。
A <- lapply(1:4, function(x) # construct list of matrices
matrix(c(0, 0, 10,
rbeta(1, 5, 4), 0, 0,
0, rbeta(1, 10, 2), 0), nrow=3, ncol=3, byrow=TRUE, ))
n <- c(1000, 100, 10) # initial vector of abundances
nYears <- 4 # define the number of years to project over
allYears <- matrix(0, nrow=3, ncol=nYears+1) # build a storage array for all abundances
allYears[, 1] <- n # set the year 0 abundance
for (t in 1:(nYears + 1)) { # loop through all years
allYears[, t] <- A[[i]] %*% allYears[, t - 1]
}
根据描述,也许我们需要遍历序列 - 即 A
的长度为 4
,而 'allYears' 的列数为 5。创建一个索引从2到'allYears'的ncol
,然后遍历该索引的序列,根据序列提取'A'对应的元素,得到allYears
前一列
i1 <- 2:(nYears + 1)
for(t in seq_along(i1)) {
allYears[,i1[t]] <- A[[t]] %*% allYears[,i1[t]-1]
}
-输出
> allYears
[,1] [,2] [,3] [,4] [,5]
[1,] 1000 100.00000 817.24277 2081.08322 333.6702
[2,] 100 261.46150 55.44237 423.22095 1244.6680
[3,] 10 81.72428 208.10832 33.36702 355.5175
备选方案,可能太聪明了,解决方案:
构造一个列表 (A[[1]]
, A[[1]] %*% A[[2]]
, ... )
Alist <- Reduce("%*%", A, accumulate=TRUE)
将这些中的每一个乘以初始值
vlist <- lapply(Alist, "%*%", n)
合并:
do.call(cbind, vlist)
[,1] [,2] [,3] [,4]
[1,] 100.00000 856.66558 4864.20044 486.420
[2,] 569.23739 56.92374 543.02451 3307.690
[3,] 78.55101 553.62548 55.36255 445.619
@MikaelJagan 指出这可以用更少的步骤完成:
do.call(cbind,
rev(Reduce("%*%", rev(A), init = n, right = TRUE, accumulate = TRUE)))
或(在最新版本的 R 中)
(A
|> rev()
|> Reduce(f = "%*%", init = n, right = TRUE, accumulate = TRUE)
|> rev()
|> do.call(what = cbind)
)
(最后一步可以用|> unlist() |> matrix(nrow = length(n))
代替。)
我正在尝试将矩阵列表相乘,按照它们在从矩阵 1 开始的列表中出现的顺序,乘以初始向量,然后递归;所以列表中的矩阵 2 乘以该结果向量。我尝试了 lapply
和 map
的各种迭代,但无法向前投影并递归执行此操作。更明确地说:A[[1]] % * % allYears[,1]
,然后是 A[[2]] % * % allYears[,2],.....,A[[4]] % * % allYears[,4]
,它在 "allYears"
中生成最后的第 5 列。下面是示例代码,在 A[[i]]
索引处的 for 循环中存在已知错误,因为未明确引用 i
。
A <- lapply(1:4, function(x) # construct list of matrices
matrix(c(0, 0, 10,
rbeta(1, 5, 4), 0, 0,
0, rbeta(1, 10, 2), 0), nrow=3, ncol=3, byrow=TRUE, ))
n <- c(1000, 100, 10) # initial vector of abundances
nYears <- 4 # define the number of years to project over
allYears <- matrix(0, nrow=3, ncol=nYears+1) # build a storage array for all abundances
allYears[, 1] <- n # set the year 0 abundance
for (t in 1:(nYears + 1)) { # loop through all years
allYears[, t] <- A[[i]] %*% allYears[, t - 1]
}
根据描述,也许我们需要遍历序列 - 即 A
的长度为 4
,而 'allYears' 的列数为 5。创建一个索引从2到'allYears'的ncol
,然后遍历该索引的序列,根据序列提取'A'对应的元素,得到allYears
前一列
i1 <- 2:(nYears + 1)
for(t in seq_along(i1)) {
allYears[,i1[t]] <- A[[t]] %*% allYears[,i1[t]-1]
}
-输出
> allYears
[,1] [,2] [,3] [,4] [,5]
[1,] 1000 100.00000 817.24277 2081.08322 333.6702
[2,] 100 261.46150 55.44237 423.22095 1244.6680
[3,] 10 81.72428 208.10832 33.36702 355.5175
备选方案,可能太聪明了,解决方案:
构造一个列表 (A[[1]]
, A[[1]] %*% A[[2]]
, ... )
Alist <- Reduce("%*%", A, accumulate=TRUE)
将这些中的每一个乘以初始值
vlist <- lapply(Alist, "%*%", n)
合并:
do.call(cbind, vlist)
[,1] [,2] [,3] [,4]
[1,] 100.00000 856.66558 4864.20044 486.420
[2,] 569.23739 56.92374 543.02451 3307.690
[3,] 78.55101 553.62548 55.36255 445.619
@MikaelJagan 指出这可以用更少的步骤完成:
do.call(cbind,
rev(Reduce("%*%", rev(A), init = n, right = TRUE, accumulate = TRUE)))
或(在最新版本的 R 中)
(A
|> rev()
|> Reduce(f = "%*%", init = n, right = TRUE, accumulate = TRUE)
|> rev()
|> do.call(what = cbind)
)
(最后一步可以用|> unlist() |> matrix(nrow = length(n))
代替。)