[Rcpp-devel] Deep copying a matrix

Douglas Bates bates at stat.wisc.edu
Thu Jul 14 18:46:21 CEST 2011


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