我正在尝试将一些Fortran代码移动到R,以获得与化学动力学相关的有限差异。
示例Fortran循环:
DOUBLE PRECISION, DIMENSION (2000,2) :: data=0.0
DOUBLE PRECISION :: k1=5.0, k2=20.0, dt=0.0005
DO i=2, 2000
data(i,1) = data(i-1,1) + data(i-1,1)*(-k1)*dt
data(i,2) = data(i-1,2) + ( data(i-1,1)*k1*dt - data(i-1,2)*k2*dt )
...
END DO
类似的R代码:
k1=5
k2=20
dt=0.0005
data=data.frame(cbind(c(500,rep(0,1999)),rep(0,2000)))
a.fun=function(y){
y2=y-k1*y*dt
return(y2)
}
apply(data,2,a.fun)
这会覆盖数据框中的第一个值,并在其他地方留下零。我想运行这个矢量化而不使用for循环,因为它们是所以在R中慢。此外,我的函数只计算到目前为止的第一列。在我第一次使用语法之前,我无法使第二列工作。
答案 0 :(得分:1)
可能这可以帮到你。
我认为您需要具备data[1,2]
的初始条件。在初始条件下,我假设data[1,1]
为500,data[1,2
为0。
代码如下:
> ## Define two vectors x and y
> x <- seq(from=0,length=2000,by=0)
> y <- seq(from=0,length=2000,by=0)
>
> ## Constants
> k1 = 5.0
> dt = 0.0005
> k2 = 20.0
>
> ## Initialize x[1]=500 and y[1]=0
> x[1]=500
> y[1] = 0
>
> for (i in 2:2000){
+ x[i]=x[i-1]+x[i-1]*-k1*dt
+ y[i] = y[i-1]+x[i-1]*k1*dt-y[i-1]*k2*dt
+ }
>
> finaldata <- data.frame(x,y)
> head(finaldata)
x y
1 500.0000 0.000000
2 498.7500 1.250000
3 497.5031 2.484375
4 496.2594 3.703289
5 495.0187 4.906905
6 493.7812 6.095382
我希望这会有所帮助。
答案 1 :(得分:1)
R在循环中不好是不正确的。这在很大程度上取决于你在做什么。使用问题中的k1
,k2
,dt
和data
(即以k1=5
开头的四行),并根据迭代矩阵制定问题,下面最后一行的循环几乎立即在我的电脑上返回:
z <- as.matrix(data)
m <- matrix(c(1-k1*dt, k1*dt, 0, 1-k2*dt), 2)
for(i in 2:nrow(z)) z[i, ] <- m %*% z[i-1, ]
(您也可以尝试将矢量存储在z而不是行的列中,因为R按列存储矩阵。)
以下是结果的第一位:
> head(z)
X1 X2
[1,] 500.0000 0.000000
[2,] 498.7500 1.250000
[3,] 497.5031 2.484375
[4,] 496.2594 3.703289
[5,] 495.0187 4.906905
[6,] 493.7812 6.095382