[Rcpp-devel] Building/linking trouble with cxxfunction()

Douglas Bates bates at stat.wisc.edu
Wed Feb 16 22:55:02 CET 2011

On Wed, Feb 16, 2011 at 2:03 PM,  <Ken.Williams at thomsonreuters.com> wrote:

> On 2/16/11 12:18 PM, "Douglas Bates" <bates at stat.wisc.edu> wrote:

>>The dgCMatrix object is of an S4 class.  It's best to use the S4 class
>>from Rcpp so you can extract the slots as Rcpp::IntegerVector and
>>Rcpp::NumericVector objects.  Once you get them in that form the
>>pointers are best obtained through the begin() method.

> Thanks Doug.

> I feel silly asking this, but could you please point me to the docs for
> the S4 class? I assume that's the Rcpp::S4 class?  I've seen it mentioned
> various places (e.g. the Rcpp-introduction vignette) but I can't seem to
> find a list of its methods & API.  begin() is a method I'd never heard of,
> I assume it returns a pointer to the first element of the vector?

I decided that it would be simple enough to write a small package to
show exactly how you would pass a dgCMatrix to an Rcpp-based C++
function and create a smat object.  The package is at
http://www.stat.wisc.edu/~bates/spSVD_1.0.tar.gz  It manages to pass
the values from the dgCMatrix object to the smat struct, although this
was somewhat more difficult than I had anticipated because the smat
structure uses long int and not int values.  So if you look at SVD.cpp
in that package you will see that I allocate std::vector<long> objects
then copy the contents of the Rcpp::IntegerVector objects into them.

There was one more "gotcha".  There is a C function called "machar"
defined in the las2.c file and there is one in the R API.  The one in
the R API wins because R is loaded before the dll for the package and
the calls are not compatible.  I changed the name of the one in las2.c
to svd_machar.  I'm currently running a test case

> library(Matrix)
Loading required package: lattice

Attaching package: 'Matrix'

The following object(s) are masked from 'package:base':


> library(spSVD)
Loading required package: Rcpp
Warning message:
In loadNamespace(package, c(which.lib.loc, lib.loc), keep.source =
keep.source) :
  package 'spSVD' contains no R code
> data(KNex)
> str(KNex$mm)
Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:8755] 0 2 25 27 163 165 1258 1261 1276 1278 ...
  ..@ p       : int [1:713] 0 13 17 26 38 43 52 56 61 67 ...
  ..@ Dim     : int [1:2] 1850 712
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ x       : num [1:8755] 0.277 0.277 0.277 0.277 0.277 ...
  ..@ factors : list()
> .Call("spSVD", KNex$mm, 713L)
NO. OF ROWS               =   1850
NO. OF COLUMNS            =    712
NO. OF NON-ZERO VALUES    =   8755
MATRIX DENSITY            =   0.66%
MAX. NO. OF EIGENPAIRS    =    712
KAPPA                     =  1.00E-06

but it is taking a long time.  I don't know if it is a programming
error or the wrong calling sequence or just a slow algorithm but it
has been chugging away for 7 minutes.  In constrast, it takes about 2
seconds to calculate the singular values of that matrix as a dense

> data(KNex)
> mm1 <- as(KNex$mm, "matrix")
> str(mm1)
 num [1:1850, 1:712] 0.277 0 0.277 0 0 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : NULL

> system.time(dsvd <- La.svd(mm1, nu=0, nv=0))
   user  system elapsed
  2.280   0.030   2.664

More information about the Rcpp-devel mailing list