将Matlab单元移植到R以收集FOR循环的输出

时间:2013-12-19 20:55:42

标签: r matlab loops port

我在Matlab中有一个ODE模型,我有兴趣执行一些参数扫描。

我正在尝试将以下代码从Matlab移植到R

for i = 1:numel(sweep1)
  initial_conditions(6)=sweep1(i);
    for j = 1:numel(sweep2) 
      parameters(3)=sweep2(j); 
[t,y] = ode23s(@(timespan, initial_conditions) MODEL(timespan, initial_conditions,          parameters), timespan, initial_conditions);
    results_cell{i,j}=[y(end,1),y(end,2)];

上面的2个FOR语句首先改变1个初始条件(i),然后对于每个i改变参数(j)并运行求解器。然后,在循环的每次迭代中求解器的输出被收集在单元格' results_cell'

这在Matlab中运行良好,但我需要将它移植到R.循环是相同的,求解器代码是使用deSolve实现的,但是我不知道如何在循环的每次迭代中从求解器收集结果因为R没有像Matlab这样的单元格,以及如何从每个循环中收集{i,j}以及2个ode输出。

最后,我想绘制一个ode求解器输出的热图与两个参数扫描中的每一个的值。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我会做什么:我运行ode23一次以获得解决方案的结构。

sweep1 =2
sweep2 =3
library(pracma)
f <- function(t, x,i=1,j=0)
  as.matrix(c(x[1] * ((i+j) - x[2]^2) -x[2], x[1]))
t0 <- 0
tf <- 20
x0 <- as.matrix(c(0, 0.25))
sol = ode23(f, t0, tf, x0,1,1)$y
res = tail(sol,1)

然后我使用replicate来创建最终输出矩阵的结构。使用这个技巧可以避免我们处理预分配数组。 replicate会为我们做。

results_cell = replicate(sweep1,replicate(sweep2,res))

我只是运行我的最终模拟并将每个解决方案分配给results_cell

for (i in seq(sweep1))
  for (j in seq(sweep2))
    results_cell[,,j,i] = tail(ode23(f, t0, tf, x0,i,j)$y,1)

答案 1 :(得分:0)

我假设sweep1和sweep2都是数字的向量。您可以做的是使用expand.grid创建其组合的数据框,然后使用apply循环框架一次:

# sweep 1, sweep 2
sweep1 <- c(1, 2, 4)
sweep2 <- c(3, 5, 7)

# expand out the combinations
combinations <- expand.grid(sweep1=sweep1, sweep2=sweep2)

# apply over the data frame
results <- apply(combinations, 1, function(row) {
  # set up the parameters from the row which has been passed in.
  initial_conditions[6] <- row["sweep1"]
  parameters[3]         <- row["sweep2"]

  # call ode23s 
  res <- ode23s(initial_conditons, parameters, function, whatever, ...)

  # there should be a nicer way than calling nrow twice here, but R doesn't
  # seem to have the nice 'end' keyword
  # also, we copy in the row, so that's in the output.
  c(row, one=res[nrow(res), 1], two=res[nrow(res), 2])
})

# because the apply has flipped rows to columns...
results <- as.data.frame(t(results))

results
#     sweep1 sweep2 one  two
#  1  1      3      ...  ...
#  2  2      3      ...  ...
# ...

所有这些的结果是输入组合和输出组合的数据帧。如果您想要更多因素,请添加sweep3,但要注意组合的复杂性......