Reputation: 20147
I have the following .cpp
file, which I want to use within R:
#include <Rcpp.h>
#include <RcppEigen.h>
using Eigen::Map;
using Eigen::EigenBase;
using Eigen::HouseholderQR;
using Eigen::MatrixXd;
using Eigen::SparseMatrix;
using Eigen::SparseQR;
using Eigen::COLAMDOrdering;
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::export]]
SEXP qr_dense_residop(Map<MatrixXd> X, Map<MatrixXd> Y){
const HouseholderQR<MatrixXd> QR(X);
return Rcpp::wrap(Y - (X * QR.solve(Y)));
}
// [[Rcpp::export]]
SEXP qr_sparse_residop(Map<SparseMatrix<double>> X, Map<SparseMatrix<double>> Y){
const SparseQR<SparseMatrix<double>, COLAMDOrdering<int>> QR(X);
return Rcpp::wrap(Y - (X * QR.solve(Y)));
}
If I compile it with Rcpp::sourceCpp()
, it compiles correctly. However, I want to include the source code in an Rmarkdown document, and so I instead am including it like this:
```{Rcpp, file="resid.cpp"}
```
Then, when I knit the document, I get the following error:
using C++ compiler: ‘g++ (GCC) 11.3.0’
/stornext/System/data/apps/gcc/gcc-11.3.0/bin/g++ -std=gnu++17 -I"/stornext/System/data/apps/R/R-4.3.2/lib64/R/include" -DNDEBUG -I"/home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/Rcpp/include" -I"/home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/RcppEigen/include" -I"/vast/scratch/users/milton.m/tmp/RtmpABumCC/sourceCpp-x86_64-pc-linux-gnu-1.0.12" -I/usr/local/include -fpic -g -O2 -w -c file153c34131d6db.cpp -o file153c34131d6db.o
In file included from /home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/RcppEigen/include/RcppEigenForward.h:26,
from /home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/RcppEigen/include/RcppEigen.h:25,
from file153c34131d6db.cpp:1:
file153c34131d6db.cpp: In function ‘SEXPREC* qr_sparse_residop(Eigen::Map<Eigen::SparseMatrix<double, 0, int> >, Eigen::Map<Eigen::SparseMatrix<double, 0, int> >)’:
/home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/Rcpp/include/RcppCommon.h:140:27: error: expected unqualified-id before string constant
140 | #define RcppExport extern "C" attribute_visible
| ^~~
file153c34131d6db.cpp:33:1: note: in expansion of macro ‘RcppExport’
33 | RcppExport SEXP sourceCpp_1_qr_dense_residop(SEXP XSEXP, SEXP YSEXP) {
| ^~~~~~~~~~
/home/users/allstaff/milton.m/R/x86_64-pc-linux-gnu-library/4.3/Rcpp/include/RcppCommon.h:140:27: error: expected unqualified-id before string constant
140 | #define RcppExport extern "C" attribute_visible
| ^~~
file153c34131d6db.cpp:45:1: note: in expansion of macro ‘RcppExport’
45 | RcppExport SEXP sourceCpp_1_qr_sparse_residop(SEXP XSEXP, SEXP YSEXP) {
| ^~~~~~~~~~
file153c34131d6db.cpp:54:2: error: expected ‘}’ at end of input
54 | }
| ^
file153c34131d6db.cpp:20:81: note: to match this ‘{’
20 | SEXP qr_sparse_residop(Map<SparseMatrix<double>> X, Map<SparseMatrix<double>> Y){
| ^
make: *** [file153c34131d6db.o] Error 1
What is happening here, and how can I avoid this error?
Upvotes: 1
Views: 43
Reputation: 1265
You are doing something wrong but it is not clear what. If you look at the existing documentation for knitr and its Rcpp engine, it is clear that having the // [[Rcpp::depends(RcppEigen)]]
that is used by sourceCpp()
should be enough ... as that is what knitr
uses!
Here is a complete Rmd file setting up something simpler: the getEigenValues()
from the README of the RcppEigen
repo. It works. Maybe you can build up from this.
---
title: "RcppEigen in RMarkdown"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Standard `getEigenValue` example from README
```{Rcpp, eigenValues}
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::Map; // 'maps' rather than copies
using Eigen::MatrixXd; // variable size matrix, double precision
using Eigen::VectorXd; // variable size vector, double precision
using Eigen::SelfAdjointEigenSolver; // one of the eigenvalue solvers
// [[Rcpp::export]]
VectorXd getEigenValues(Map<MatrixXd> M) {
SelfAdjointEigenSolver<MatrixXd> es(M);
return es.eigenvalues();
}
```
From `?eigen`:
```{r}
M <- cbind(c(1,-1), c(-1,1))
eigen(M) # base R
getEigenValues(M)
```
It does the trick. (Eigen values are invariant to ordering so c(2,0)
is equivalent to c(0,2)
.)
Upvotes: 2