是否可以对 R 中向量元素的顺序更新进行向量化?

发布于 2024-10-12 06:02:09 字数 377 浏览 2 评论 0原文

是否可以像下面这样对代码进行矢量化?

length(x) <- 100;
x[1]      <- 1;
y         <- rnorm(100);

for(i in 2:100) {
    x[i] <- 2 * y[i] * x[i-1];
}

我明白这是一个微不足道的例子,但它可以说明这个想法。

我经常需要编写代码,其中向量中的第 i 个值取决于第 (i-1) 个值,如果可能的话,我想在不需要 for 循环的情况下编写此代码,分析表明,具有此类操作的函数是我的代码中的主要瓶颈。

此操作是否可向量化,因此我不需要在计算中使用 for() 循环?

Is it possible to vectorise code like the following?

length(x) <- 100;
x[1]      <- 1;
y         <- rnorm(100);

for(i in 2:100) {
    x[i] <- 2 * y[i] * x[i-1];
}

I appreciate that this is a trivial example, but it serves to illustrate the idea.

I often need to write code where the i-th value in a vector depends on the (i-1)-th value and if possible, I'd like to write this without needing a for loop, as profiling suggests the functions with this type of operation are the major bottlenecks in my code.

Is this operation vectorizable so I do not need to use a for() loop in the calculation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

泅人 2024-10-19 06:02:09

一般来说,如果您想要矢量化解决方案,则需要解决递归关系

In general, if you want a vectorised solution you need to solve the recurrence relation.

内心激荡 2024-10-19 06:02:09

在您的示例中,您可以计算出 x[i] 的公式并查看它是否可以矢量化。在这种情况下,我认为 cumprod 可能会起作用。

x <- c(1, cumprod(2*y)[1:99])

对于某些情况,您还可以在卷积或递归模式下使用 filter 命令。请参阅 ?filter

但是,如果无法计算出适合上述模型之一的第 n 个值的公式,您可以尝试使用像 inline 这样的包code> 或 Rcpp 在 C/C++ 中循环编写。

In the example you have you could work out the formula for x[i] and see if it can be vectorized. In this case I think cumprod might work.

x <- c(1, cumprod(2*y)[1:99])

For some cases case you can also use the filter command in convolution or recursive mode. See ?filter

However if it is isn't possible to work out a formula for the n'th value that fits one of the molds above, you could try using a package like inline or Rcpp to write this in loop in C/C++.

万劫不复 2024-10-19 06:02:09

该绘图命令的内部是等效的。重复运行它相当有趣:

plot(c(1, 2^(2:length(x)-1)*cumprod(rnorm(99) )) )

The interior of this plot command is equivalent. Rather interesting to repeatedly run it:

plot(c(1, 2^(2:length(x)-1)*cumprod(rnorm(99) )) )

女皇必胜 2024-10-19 06:02:09

您可以用 C++ 编写非垂直化代码:

library(inline)
myfun <- cxxfunction(signature(y="numeric"), body='
Rcpp::NumericVector yvec(y);
int ysize = yvec.size();
Rcpp::NumericVector result(ysize);
if (ysize > 0) {
    result[0] = 1;
    for (int i = 1; i < ysize; i++) {
        result[i] = 2 * yvec[i] * result[i-1];
    }
}
return result;
', plugin="Rcpp")

然后从 R 调用此函数:

y <- rnorm(100);
x <- myfun(y);

You can write the non-vertorized code in C++:

library(inline)
myfun <- cxxfunction(signature(y="numeric"), body='
Rcpp::NumericVector yvec(y);
int ysize = yvec.size();
Rcpp::NumericVector result(ysize);
if (ysize > 0) {
    result[0] = 1;
    for (int i = 1; i < ysize; i++) {
        result[i] = 2 * yvec[i] * result[i-1];
    }
}
return result;
', plugin="Rcpp")

Then call this function from R:

y <- rnorm(100);
x <- myfun(y);
謌踐踏愛綪 2024-10-19 06:02:09

我还没有这方面的完整细节,但看起来函数 filter() 对于完成我需要的事情很有用。

I don't have full details on this yet, but it looks the function filter() is going to be useful to do what I need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文