I have a matrix (500x500) of integers. For each entry, I need to look at its surrounding neighbours (so 8 elements) and determine what the integers are, and run a function on these integers.
Here what my function looks like right now (R code with the RCpp package).
fx2<- cppFunction('NumericMatrix getNeighbours(NumericMatrix x) {
int nrow = x.nrow(), ncol = x.ncol();
//create a result matrix of probabilities
NumericMatrix outProb(nrow, ncol);
// some counters needed to calculate probability
int kc = 0; int kpre = 0; int ks = 0;
// i and j loop through the elements one by one.
// - ignore the boundary as I dont know how to handle it for now
for (int i = 1; i < (nrow-1); i++) {
for (int j = 1; j < (ncol-1); j++) {
// go through the neighbours
for(int k = -1; k <= 1; k++){
for(int l = -1; l <= 1; l++){
// check what values the neighbours are
// increment the kc
if(x(i + k, j + l) == 4){
kc++;
}
// increment the ks counter
if(x(i + k, j + l) == 5){
ks++;
}
// more if statements removed for readibility
}
} //end of loop for neighbours
// calculate a probability for the resulting matrix
outProb(i, j) = functionof(kc, ks, kpre);
}
}
return outProb;
}')
I am looking to make this code faster/more efficient.
Example of result: Suppose the functionof
just doubles the value of the counter.
> health
[,1] [,2] [,3] [,4] [,5]
[1,] 4 1 1 1 1
[2,] 1 1 1 1 1
[3,] 1 1 1 1 1
[4,] 1 1 1 1 1
[5,] 1 1 1 1 1
We see that (2, 1)
, (1, 2)
and (2, 2)
have 4
as their neighbours. So the output would be
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 2 0 0 0 0
[2,] 2 2 0 0 0 0
[3,] 0 0 0 0 0 0
[4,] 0 0 0 0 0 0
[5,] 0 0 0 0 0 0
[6,] 0 0 0 0 0 0
Note that there are other elements in the matrix that have 4
as a neighbour. I've omitted that from the result
matrix above.
I currently wrote the code in R but even after vectorizing/parallelizing it is still very slow. So now I've moved on to a C++ function that I can call using R's RCpp
package.