Speed ​​up matrix assembly by interleaving vectors?

I have two vectors of arbitrary and equal length

a <- c(0.8,0.8,0.8) b <- c(0.4,0.4,0.4) n <- length(a) 

Of these, I need to assemble a 2n by 2n matrix of the form

 x = [1-a1 b1 1-a2 b2 1-a3 b3 a1 1-b1 a2 1-b2 a3 1-b3 1-a1 b1 1-a2 b2 1-a3 b3 a1 1-b1 a2 1-b2 a3 1-b3 1-a1 b1 1-a2 b2 1-a3 b3 a1 1-b1 a2 1-b2 a3 1-b3] 

I am currently using

 x <- matrix(rep(as.vector(rbind( c(1-a,a), c(b, 1-b))), n), ncol=n*2, byrow=TRUE) 

How to speed up this operation? Profiling indicates that matrix takes the most time:

 Rprof("out.prof") for (i in 1:100000) { x <- matrix(rep(as.vector(rbind( c(1-a,a), c(b, 1-b))), n), ncol=n*2, byrow=TRUE) } Rprof(NULL) summaryRprof("out.prof") ##$by.self ## self.time self.pct total.time total.pct ##"matrix" 1.02 63.75 1.60 100.00 ##"rbind" 0.24 15.00 0.36 22.50 ##"as.vector" 0.18 11.25 0.54 33.75 ##"c" 0.10 6.25 0.10 6.25 ##"*" 0.04 2.50 0.04 2.50 ##"-" 0.02 1.25 0.02 1.25 ## ##$by.total ## total.time total.pct self.time self.pct ##"matrix" 1.60 100.00 1.02 63.75 ##"as.vector" 0.54 33.75 0.18 11.25 ##"rbind" 0.36 22.50 0.24 15.00 ##"c" 0.10 6.25 0.10 6.25 ##"*" 0.04 2.50 0.04 2.50 ##"-" 0.02 1.25 0.02 1.25 ## ##$sample.interval ##[1] 0.02 ## ##$sampling.time ##[1] 1.6 
+4
source share
2 answers

I don't think the matrix alternative is the slowest part of your profile, but you can save a little time by optimizing the rest. For instance:

 x <- matrix(rbind(c(1-a,a), c(b, 1-b)), 2*n, 2*n, byrow=TRUE) 

In addition, although I would not recommend it, you can save extra time by using the internal matrix function:

 x <- .Internal(matrix(rbind(c(1-a,a), c(b, 1-b)), n*2, n*2, TRUE, NULL, FALSE, FALSE)) 

Here are a few steps:

 benchmark( method0 = matrix(rep(as.vector(rbind(c(1-a,a), c(b, 1-b))), n), ncol=n*2, byrow=TRUE), method1 = matrix(rbind(c(1-a,a), c(b, 1-b)), 2*n, 2*n, byrow=TRUE), method2 = .Internal(matrix(rbind(c(1-a,a), c(b, 1-b)), n*2, n*2, TRUE, NULL, FALSE, FALSE)), replications = 100000, order = "relative") # test replications elapsed relative user.self sys.self user.child sys.child # 3 method2 100000 1.00 1.00 0.99 0 NA NA # 2 method1 100000 1.13 1.13 1.12 0 NA NA # 1 method0 100000 1.46 1.46 1.46 0 NA NA 
+3
source

I get a little acceleration with the following:

 f = function(a, b, n){ z = rbind( c(rbind(1 - a, b)), c(rbind(a, 1 - b)) ) do.call(rbind, lapply(1:n, function(i) z)) } 

I will continue to search.

Change I'm at a standstill. If this is not enough, I would recommend inserting some rcpp.

0
source

Source: https://habr.com/ru/post/1445612/


All Articles