[Rcpp-devel] Deep copying a matrix

Etienne B. Racine etiennebr at gmail.com
Thu Jul 14 19:03:27 CEST 2011


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;

Etienne


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
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110714/eca34561/attachment-0001.htm>


More information about the Rcpp-devel mailing list