Skip to content

[Rcpp-devel] type mismatch between NumericMatrix and IntegerMatrix

3 messages · Kaspar Märtens, JJ Allaire, Dirk Eddelbuettel

#
Hi,

When experimenting with the following toy function,

// [[Rcpp::export]]
void modify_matrix(NumericMatrix A){
  A(0, 0) = 5;
}

and applying this on matrices defined in R, I occasionally noticed
unexpected behaviour (as it turns out, on integer matrices).

### Example 1 (works as expected)

A = matrix(0, 2, 2)
modify_matrix(A)
A

##      [,1] [,2]
## [1,]    5    0
## [2,]    0    0

### Example 2 (does not modify the matrix)

A = matrix(1:4, 2, 2)
modify_matrix(A)
A

##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4

I realised that in the latter case, A consists of integers, so I guess I
should be using an IntegerMatrix version of my function instead. However,
shouldn't Rcpp detect the type mismatch between NumericMatrix and
IntegerMatrix?

Best,
Kaspar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160807/5d3ce18c/attachment.html>
#
In the latter case the integer matrix is "converted" to a numeric matrix
via a copy which is why your modification doesn't work.

That said, modifying an object in place violates R's language semantics and
could lead to incorrect computations (i.e. users expect that objects are
immutable and this is part of what ensures the integrity of computations)
so this is strongly discouraged.

On Sun, Aug 7, 2016 at 7:00 AM, Kaspar M?rtens <kaspar.martens at gmail.com>
wrote:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160807/44d0d180/attachment.html>
#
On 7 August 2016 at 07:17, JJ Allaire wrote:
| In the latter case the integer matrix is "converted" to a numeric matrix via a
| copy which is why your modification doesn't work.

"What he said..."

This is a known issue which we presented many times in talks. Something from
the most recent one is below.
 
| That said, modifying an object in place violates R's language semantics and
| could lead to incorrect computations (i.e. users expect that objects are
| immutable and this is part of what ensures the integrity of computations) so
| this is strongly discouraged.

"What he said..."

But this is something we cannot enforce from the Rcpp
side, nor can we enforce it as you had hope for. C/C++ just don't work that way.


The promised example is here. Run the two examples to the output, and study
the difference:

-----------------------------------------------------------------------------
## NumericVector: A Second Example

A second example alters a numeric vector:

```cpp
#include <Rcpp.h>

// [[Rcpp::export]]
NumericVector f(NumericVector m) {
    m(0) = 0;
    return m;
}
```        


## NumericVector: A Second Example

Calling the last example with an integer vector:

\small

```{r numVecEx3-a}
Rcpp::sourceCpp("code/numVecEx3.cpp")

x <- 1:3        # same as c(1L, 2L, 3L)
print(data.frame(x=x, fx=f(x)), row.names=FALSE)
```

## NumericVector: A Second Example

Calling the last example with a numeric vector:

```{r numVecEx3-b}
x <- c(1.0, 2.0, 3.0)
print(data.frame(x=x, fx=f(x)), row.names=FALSE)
```

We pass `x` as a `SEXP` which is a pointer.  
Use `Rcpp::clone()` for deep copy.
-----------------------------------------------------------------------------

For what it is worth that is on slides 74 to 76 of
http://dirk.eddelbuettel.com/papers/jsm2016_rcpp_course.pdf


Hth,  Dirk