Vectorize min()用于矩阵

drj*_*rm3 2 r matrix vectorization

我希望能够对以下循环进行矢量化:

for (i in 1:n) {
    for (j in 1:m) {
        temp_mat[i,j]=min(temp_mat[i,j],1);
    }
}  
Run Code Online (Sandbox Code Playgroud)

我以为我能做到temp_mat=min(temp_mat,1),但这并没有给我预期的结果.有没有办法对这个循环进行矢量化以使其更快?

李哲源*_*李哲源 10

只是用temp_mat <- pmin(temp_mat, 1).有关?pmin并行最小值的更多用法,请参阅.

例:

set.seed(0); A <- matrix(sample(1:3, 25, replace = T), 5)
#> A
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    3    1    1    3    3
#[2,]    1    3    1    2    3
#[3,]    2    3    1    3    1
#[4,]    2    2    3    3    2
#[5,]    3    2    2    2    1
B <- pmin(A, 2)
#> B
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    2    1    1    2    2
#[2,]    1    2    1    2    2
#[3,]    2    2    1    2    1
#[4,]    2    2    2    2    2
#[5,]    2    2    2    2    1
Run Code Online (Sandbox Code Playgroud)

更新

由于您具有计算科学的背景,我想提供更多信息.

pmin很快,但远没有高性能.它的前缀"平行"只表明element-wise.R中"矢量化"的含义与HPC中的"SIMD矢量化"不同.R是一种解释型语言,因此R中的"向量化"意味着选择C级循环而不是R级循环.因此,pmin只是用一个简单的C循环编码.

真正的高性能计算应该受益于SIMD矢量化.我相信你了解SSE/AVX内在函数.因此,如果您编写一个简单的C代码,使用_mm_min_pdfrom SSE2,您将获得〜2倍的加速pmin; 如果你_mm256_min_pd从AVX 看到,你将获得~4倍的加速pmin.

不幸的是,R本身无法做任何SIMD.我有一个答案,在做R矢量化计算时,是否利用SIMD?关于这个问题.对于您的问题,即使您将R链接到HPC BLAS,pmin也不会从SIMD中受益,只是因为pmin不涉及任何BLAS操作.所以更好的选择是自己编写编译代码.

  • 虽然它不是OP所要求的,但是有许多方法可以在R中实现大规模并行计算.例如包括`snow`,`multicore`,`foreach`,`Rmpi`,`Rth`,`gputools`和基本包`parallel`,它已经合并了一些以前独立的包.这是关于此主题的最新技术的[好参考](https://books.google.com/books/about/Parallel_Computing_for_Data_Science.html?id=SsbECQAAQBAJ). (2认同)