[Rcpp-devel] Deep copying a matrix

Douglas Bates bates at stat.wisc.edu
Thu Jul 14 19:22:41 CEST 2011


On Thu, Jul 14, 2011 at 12:03 PM, Etienne B. Racine <etiennebr at gmail.com> wrote:
> Thanks Douglas,
>
> However just to be sure I get it, const is in fact protecting the pointer on
> origin, but not its values. Is there a way to protect the values ? This is
> running fine :
> const Rcpp::NumericMatrix m_source(origin);
> m_source(0,0) = 0;

We're getting into areas where Dirk and Romain will need to take over
from me as I am out of my depth.  I would have thought that the
compiler should complain about the assignment to elements of a const
matrix.  It may have something to do with whether there is a const
version of operator()

> 2011/7/14 Douglas Bates <bates at stat.wisc.edu>
>>
>> The way to guarantee a deep copy is to use Rcpp::clone().  In general
>> I recommend using a const qualifier on any vectors or arrays
>> constructed directly from the function arguments.  If they need to be
>> coerced to another storage type they will end up being a deep copy of
>> the original but to preserve the functional programming semantics you
>> should regard any arguments passed to C++ function from R as
>> read-only.
>>
>> I would rewrite your code fragment as
>>
>>    const Rcpp::NumericMatrix  m_source(origin);
>>    Rcpp::NumericMatrix m_copy = Rcpp::clone(m_source);
>>
>> On Thu, Jul 14, 2011 at 11:36 AM, Etienne B. Racine <etiennebr at gmail.com>
>> wrote:
>> > Hi list,
>> >
>> > I'm struggling with the copy of my parameters. If I understand
>> > correctly, if
>> > you ship an int matrix to the function, you'll get a deep copy. However
>> > if
>> > it's a numeric matrix, then there's no copy and you get a matrix
>> > pointing on
>> > your R matrix. That's funny when you try to debug as one might work and
>> > the
>> > other not.
>> >
>> > Here's an illustration
>> > library(Rcpp); library(inline)
>> >
>> > f1 <- cxxfunction(signature(origin="numeric"), body = "
>> >                   Rcpp::NumericMatrix m_source(origin);
>> >                   m_source(0,0) = 0;
>> >                   cout << origin << endl << m_source << endl ; ",
>> >                   include = "using namespace std;",
>> >                   plugin="Rcpp")
>> >
>> > m <- matrix(1:4,2,2)
>> > x <- f1(m)
>> >
>> > #0x9c7fe18
>> > #0xb416a1a8  # different
>> > m
>> > #     [,1] [,2]
>> > #[1,]    1    3
>> > #[2,]    2    4
>> > m <- matrix(1:4/2,2,2)
>> > x <- f1(m)
>> > #0xb416a090
>> > #0xb416a090  # no different
>> > m
>> > #     [,1] [,2]
>> > #[1,]    0  1.5
>> > #[2,]    1  2.0
>> >
>> > Now, what I'd like is to have a (deep) copy of that matrix, whatever the
>> > type. I've tried
>> > Rcpp::NumericMatrix m_copy = m_source; // of course it did not work, but
>> > never know with vectorisation ;-)
>> > sdt::copy(m_source.begin(), m_source.end(), std::back_inserter(m_copy))
>> > //
>> > nope
>> >
>> > The closer I got was with
>> > f2 <- cxxfunction(signature(origin="numeric"), body = "
>> >                   Rcpp::NumericMatrix m_source(origin);
>> >                   Rcpp::NumericMatrix m_copy;
>> >                   Rcpp::NumericMatrix::iterator itr;
>> >                   cout << m_copy << endl << endl;
>> >                   m_source(0,0) = 0;
>> >                   for(itr = m_source.begin(); itr != m_source.end();
>> > ++itr)
>> >                     m_copy.push_back(*itr);
>> >                   m_copy[3] = 1; // matrix structure is lost or never
>> > existed;
>> >                   cout << origin << endl << m_source << endl << m_copy ;
>> >                   return wrap(m_copy);",
>> >                   include = "using namespace std;",
>> >                   plugin="Rcpp", verbose= FALSE)
>> >
>> > Main drawback is that I loose the matrix structure. I'm sure there's a
>> > correct way to do this, but I couldn't find it.
>> >
>> > Etienne
>> >
>> > _______________________________________________
>> > Rcpp-devel mailing list
>> > Rcpp-devel at lists.r-forge.r-project.org
>> > https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>> >
>> >
>
>


More information about the Rcpp-devel mailing list