[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':
det
> 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)
SOLVING THE [A^TA] EIGENPROBLEM
NO. OF ROWS = 1850
NO. OF COLUMNS = 712
NO. OF NON-ZERO VALUES = 8755
MATRIX DENSITY = 0.66%
MAX. NO. OF LANCZOS STEPS = 712
MAX. NO. OF EIGENPAIRS = 712
LEFT END OF THE INTERVAL = -1.00E-30
RIGHT END OF THE INTERVAL = 1.00E-30
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
matrix
> 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