Reputation: 843
I have a large data set consisting of two matrices and a vector. One of the two matrices and the vector have elements that change. I would like to loop over every possible vector-matrix combination, add over every column and row for each iteration, and finally store these results in a vector.
The vector has one element with "1", the rest 0's. The matrix has 1's everywhere apart from one smaller block of 0's along its diagonal.
The vector and the matrix are not independent from each other, the location of the 0's of the matrix depends on the location of the 1 in the vector.
For example, the elements of the matrix is grouped with size 2*2, then when the vector has 1 in the first or second element, the matrix has 0's in the first 2*2 block along the diagonal. If the 1 is located in the third element of the vector, the block of 0's in the matrix moves to [3:4 , 3:4], and so on.
I give a small example with matrices a
and b
, and vector c
:
a <- matrix(1:36, nrow = 6, byrow = TRUE)
In this example, I group together elements along blocks of size 3*3. As I don't know how to loop very well, I already prepare all the combinations for b
and c
:
b <- matrix(rep(1, times = 36), nrow = 6, byrow = TRUE)
b1 <- b
b1[1:3,1:3] <- 0
b2 <- b
b2[4:6,4:6] <- 0
c1 <- rep(0, times = 6)
c1[1] <- 1
c2 <- rep(0, times = 6)
c2[2] <- 1
c3 <- rep(0, times = 6)
c3[3] <- 1
c4 <- rep(0, times = 6)
c4[4] <- 1
c5 <- rep(0, times = 6)
c5[5] <- 1
c6 <- rep(0, times = 6)
c6[6] <- 1
d1 <- sum(colSums(b1 * diag(as.vector(a %*% c1), nrow = 6)))
d2 <- sum(colSums(b1 * diag(as.vector(a %*% c2), nrow = 6)))
d3 <- sum(colSums(b1 * diag(as.vector(a %*% c3), nrow = 6)))
d4 <- sum(colSums(b2 * diag(as.vector(a %*% c4), nrow = 6)))
d5 <- sum(colSums(b2 * diag(as.vector(a %*% c5), nrow = 6)))
d6 <- sum(colSums(b2 * diag(as.vector(a %*% c6), nrow = 6)))
The multiplication between both matrices is an element wise one.
I store the results in results
results <- cbind(d1, d2, d3, d4, d5, d6)
that gives:
d1 d2 d3 d4 d5 d6
[1,] 75 78 81 30 33 36
Is there a way to do this efficiently using loops? I would also really appreciate if I could define inside of the code how big the blocks are. In my data, the blocks are around 50*50. Also, I have several blocks in my dataset..
Upvotes: 0
Views: 304
Reputation: 26
a <- matrix(1:36, nrow = 6, byrow = TRUE)
b <- matrix(rep(1, times = 36), nrow = 6, byrow = TRUE)
b1 <- b
b1[1:3,1:3] <- 0
b2 <- b
b2[4:6,4:6] <- 0
my loop codes...
for (i in seq(6)){
temp = rep(0, 6)
temp[i] = 1
assign(paste('c', i, sep = ''), temp)
}
for (i in seq(6)){
cx = get(paste('c', i, sep = ''))
if(i<4){
px = sum(colSums(b1 * diag(as.vector(a %*% cx), nrow = 6)))
assign(paste('d', i, sep = ''), px)
} else{
px = sum(colSums(b2 * diag(as.vector(a %*% cx), nrow = 6)))
assign(paste('d', i, sep = ''), px)
}
}
then the results
results <- cbind(d1, d2, d3, d4, d5, d6)
Upvotes: 1