Fast correlation in R using C and parallelization

泄露秘密 提交于 2019-12-03 03:40:19

Using a fast BLAS (via Revolution R or Goto BLAS) you can calculate all these correlations fast in R without writing any C code. On my first generation Intel i7 PC it takes 16 seconds:

n = 400;
m = 1e6;

# Generate data
mat = matrix(runif(m*n),n,m);
# Start timer
tic = proc.time();
# Center each variable
mat = mat - rowMeans(mat);
# Standardize each variable
mat = mat / sqrt(rowSums(mat^2));   
# Calculate correlations
cr = tcrossprod(mat);
# Stop timer
toc = proc.time();

# Show the results and the time
show(cr[1:4,1:4]);
show(toc-tic)

The R code above reports the following timing:

 user  system elapsed 
31.82    1.98   15.74 

I use this approach in my MatrixEQTL package.
http://www.bios.unc.edu/research/genomic_software/Matrix_eQTL/

More information about various BLAS options for R is available here:
http://www.bios.unc.edu/research/genomic_software/Matrix_eQTL/runit.html#large

A few things.

First, if you are using the .C interface for external calls, then by default it makes copies of all of the arguments. That's why the object corr isn't being modified. If you want to avoid this then you have to set DUP=false in the .C call. However, in general using .C to modify existing R objects is not the preferred way to do things. Instead, you probably want to create a new array and allow the external call to fill it in, like this.

corr<-.C("rCorrelationWrapper2", as.double(X), as.integer(dim(X)), 
        as.double(mu), as.double(sd), 
        as.integer(Rows), as.integer(Cols), 
        result=double(p*q))$result
corr<-array(corr,c(p,q))

Second, as far as writing a fast correlation function, the first thing you should try is compiling R with an efficient BLAS implementation. This will not just make your correlation function faster, it will make all of your linear algebra faster. Good free candidates are ACML from AMD, or ATLAS. Either of those will be able to compute correlation matrices very quickly. The speedup is more than just parallelization -- these libraries also are smart about things cache usage and are optimized at the assembly level so even with just one core you'll see a big improvement. http://developer.amd.com/tools-and-sdks/cpu-development/amd-core-math-library-acml/ http://math-atlas.sourceforge.net/

Finally, if you really want to write your own C code, I would suggest using openMP to automatically split up the computation among different threads, rather than doing it by hand. But, for something as basic as matrix multiplication, it's probably better to go with an available optimized library.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!