I have a small C++ function using Rcpp that replaces elements of one matrix with values from another matrix. It works fine for single cells, or a column as below:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b(_,1) = a(_,1);
return b;
}')
changeC(g,f)
If originally f is the following matrix:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 6 6 6 6 6 6
[2,] 6 6 6 6 6 6
[3,] 6 6 6 6 6 6
[4,] 6 6 6 6 6 6
[5,] 6 6 6 6 6 6
[6,] 6 6 6 6 6 6
and g looks like the following matrix:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 5 5 5 5 5 5
[2,] 5 5 5 5 5 5
[3,] 5 5 5 5 5 5
[4,] 5 5 5 5 5 5
[5,] 5 5 5 5 5 5
[6,] 5 5 5 5 5 5
When I run changeC(g,f) I end up with (as expected):
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 6 5 6 6 6 6
[2,] 6 5 6 6 6 6
[3,] 6 5 6 6 6 6
[4,] 6 5 6 6 6 6
[5,] 6 5 6 6 6 6
[6,] 6 5 6 6 6 6
But what I really want to do is replace a subset of one matrix with a subset of another matrix from a different place (eg rows 1 to 3, columns 1 to 3 of one matrix (3*3) to rows 3 to 6, columns 3 to 6 (also 3*3) of the other matrix). I have tried:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b( Range(0,2), Range(0,2)) = a( Range(3,5), Range(3,5));
return b;
}')
but this doesn't compile. Although:
cppFunction('NumericMatrix changeC(NumericMatrix one, NumericMatrix two) {
NumericMatrix a = one;
NumericMatrix b = two;
b = a( Range(3,5), Range(3,5));
return b;
}')
does compile. What am I doing wrong? In R I would do the following:
f[1:3,1:3] <- g[4:6,4:6] (but this is relatively slow with a very large matrix (hence Rcpp).
Thanks for any help in advance.
EDIT 1
After a bit of playing around I've managed to get my matrix to step east and west (and I assume it would be similar to north and south - possibly a two step approach for North East, North West??):
func <- 'NumericMatrix eastC(NumericMatrix a) {
int acoln=a.ncol();
NumericMatrix out(a.nrow(),a.ncol()) ;
for (int j = 0;j < acoln;j++) {
if (j > 0) {
out(_,j) = a(_,j-1);
} else {
out(_,j) = a(_,0);
}
}
return out ;
}'
cppFunction(func)
Any refinements would be welcome. I would ideally like to leave the first column as zeros rather than column 0. Any ideas?
I don't think the Rcpp subMatrix allows for assignments that way.
Take a look at using RcppArmadillo and Armadillo submatrix views
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace arma;
// [[Rcpp::export]]
mat example( mat m1, mat m2) {
m1.submat( 0,0, 2,2) = m2.submat( 3,3, 5,5 );
return m1;
}
/*** R
m1 <- matrix(1,6,6)
m2 <- matrix(-1,6,6)
example(m1, m2)
*/
> m1 <- matrix(1,6,6)
> m2 <- matrix(-1,6,6)
> example(m1, m2)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] -1 -1 -1 1 1 1
[2,] -1 -1 -1 1 1 1
[3,] -1 -1 -1 1 1 1
[4,] 1 1 1 1 1 1
[5,] 1 1 1 1 1 1
[6,] 1 1 1 1 1 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With