我正在使用数学模型,其中函数包含在矩阵中以模拟生物种群的动态。这通常需要调用函数来更新矩阵,然后执行矩阵乘法以将系统的动态投影到下一个时间步。我想知道是否有可能直接在矩阵中嵌入函数并跳过显式更新矩阵元素。
模型如下所示: 系统的状态在矩阵X1中,例如
X <- c(0,10)
系统根据矩阵A
进行更改A <- matrix(data = c(0, NA,0.75,0.75),nrow =2,byrow = T)
[,1] [,2]
[1,] 0.00 NA
[2,] 0.75 0.75
元素NA是X1中元素2的函数,如此
f.A.12 <- function(X.2){1 + (1 - X.2/1000)}
所以系统是这样模拟的: 根据X
的状态更新marix A.A[1,2] <- f.A.12(X[2])
使用更新的矩阵迭代模型:
A%*%X
[,1]
[1,] 19.9
[2,] 7.5
然后迭代1000次,在每次乘法之前更新A
真实模型使用包含多个函数的更大的矩阵。 是否有R包允许我直接在矩阵中嵌入函数,例如
A.with.fx <- matrix(data = c(0, f.A.12,
0.75, 0.75), nrow =2,byrow = T)
然后执行常规矩阵运算,例如
A.with.fx%*%X
在每次迭代中,无需在A中显式分配作为X函数的A值?
我想这需要一个函数,它是一个修改过的%*%
操作,可以自己进行必要的查找。
答案 0 :(得分:2)
我认为你可能试图以一种最终不是很干净或标准的方式来解决你的问题。不要考虑包含标量函数的矩阵,而应考虑返回矩阵的函数。
你可以轻而易举地做到:
update <- function(X) matrix(c(0,.75, f.A.12(X[2]), .75), 2)
并且滥用了一些符号:
`%**%` <- function(f, X) f(X) %*% X
X <- update %**% X
请注意%*%
是一个S4泛型,所以重载它有点痛苦。
或者,使用小代数,您可以将A
拆分为X
的常量和函数,并以这种方式处理复杂性:
A = [ [ 0, 2 - x[2]/1000],
[.75, .75] ]
= [[0, 2],[.75, .75]] + [[0, - x[2]/1000],[0, 0 ] ]
= c + g(x)
所以可以重写更新:
X = c * X + g(X) * X
其中g
是矩阵值函数,产生更慢但更清晰的:
g <- function(X) matrix( c(0,0, -x[2]/1000), 0), 2,2)
C <- matrix(c(0,.75,2,.75),2)
X <- c(0,10)
> (X <- C %*% X + g(X) %*% X)
[,1]
[1,] 19.9
[2,] 7.5
我们可以通过将g(X) %*% X
组合成一个函数来做得更好:
f <- function(x) c( -x[2]^2 / 1000, 0 )
,并提供:
> X <- c(0,10)
> (X <- C %*% X + f(X) )
[,1]
[1,] 19.9
[2,] 7.5
以下是几个基准:
microbenchmark(two_step={A <- update(X); A %*% X},
split=(C %*% X + g(X) %*% X),
composed= C %*% X + f(X) )
Unit: microseconds
expr min lq mean median uq max neval
two_step 3.608 4.0900 4.85369 4.3730 4.9290 13.089 100
split 5.587 6.0400 7.72511 6.4900 7.3785 53.047 100
composed 2.266 2.4835 2.78195 2.6815 2.9745 6.697 100