【问题标题】:How to vectorize complex iterative loop in r如何在r中矢量化复杂的迭代循环
【发布时间】:2015-04-24 04:07:30
【问题描述】:

我通常对 r 中的向量化没有任何问题,但是在下面的示例中我遇到了困难,因为 for 循环中同时存在迭代和非迭代组件。

在下面的代码中,我必须基于一组常量 (Dini) 执行计算,该计算是一个值向量 (Xs),其中输出向量 (Ys) 的第 i 个值也取决于i-1 值:

Dini=128 #constant
Xs=c(6.015, 5.996, 5.989, 5.911, 5.851, 5.851, 5.858, 5.851)
Y0=125.73251 #starting Y value

Ys=c(Y0) #starting of output vector, first value is known
for (Vi in Xs[2:length(Xs)]){
  ytm1=Ys[length(Ys)]
  y=(955.74301-2*((Dini+ytm1-Vi)^2-ytm1^2)^0.5+2*ytm1*acos(ytm1/(Dini+ytm1-Vi)))/pi/2
  Ys=c(Ys, y)
} 
df=data.frame(Xs, Ys)
df

    Xs       Ys
1 6.015 125.7325
2 5.996 125.7273
3 5.989 125.7251
4 5.911 125.7036
5 5.851 125.6859
6 5.851 125.6849
7 5.858 125.6868
8 5.851 125.6850

对于这种情况,在 for 循环中混合了迭代和非迭代组件的情况下,我的思想陷入了一个非矢量化的结。

有什么建议吗?

【问题讨论】:

  • 您可以为此使用data.table;创建一个额外的列,其中 Ys 移动了 1。
  • @sheffien 但循环之前不存在 Y。有一个值。我不确定我是否理解你的建议。你能把它变成一个有效的答案吗?
  • @MrFlick 你是对的......我错过了。

标签: r vectorization


【解决方案1】:

在这种情况下,您可能需要考虑使用 Reduce。例如

Ys<-Reduce(function(prev, cur) { 
  (955.74301-2*((Dini+prev-cur)^2-prev^2)^0.5 + 2*prev*acos(prev/(Dini+prev-cur)))/pi/2
}, Xs, init=Y0, accumulate=T)[-1]

来自?Reduce 帮助页面:“Reduce 使用二元函数连续组合给定向量的元素和可能给定的初始值。”这使得创建给定值取决于先前值的向量变得更加容易。

【讨论】:

  • 不错。您能否添加一些有关您使用Reduce() 做什么的信息以及为什么它是这项工作的最佳工具?这对未来的读者和 OP 都有帮助。
猜你喜欢
  • 1970-01-01
  • 2016-02-11
  • 2012-12-10
  • 2020-05-03
  • 1970-01-01
  • 2018-12-08
  • 2019-02-28
  • 2012-06-11
相关资源
最近更新 更多