I have written the following .cpp file to draw samples from Dirichlet distribution using the random number distribution function in GSL. The filename is C_functions.cpp. I am doing everything in Windows 10.
#include <RcppArmadillo.h>
#include <RcppGSL.h>
// #include <Rcpp.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppGSL)]]
using namespace arma;
// [[Rcpp::export]]
vec rdirichlet_arma(vec a){
const gsl_rng_type * T;
gsl_rng * r;
/* create a generator chosen by the
environment variable GSL_RNG_TYPE */
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
/* print n random variates chosen from
the poisson distribution with mean
parameter mu */
int n=a.size();
vec results(n);
gsl_ran_dirichlet(r, n, a.begin(), results.begin());
gsl_rng_free (r);
a.reset();
return results;
}
// [[Rcpp::export]]
double pow2(double x){
return gsl_pow_2(x);
}
I have created an environmental variable LIB_GSL and set its value as "C:/Users/nkc10/Documents/R/local323". This is the location where I unzipped the local323.zip folder downloaded from this link .
However, when I compile it with sourceCpp the following error is shown
>C:/RBuildTools/3.5/mingw_64/bin/g++ -std=gnu++11 -I"C:/PROGRA~1/R/R-35~1.2/include" -DNDEBUG -I../inst/include -fopenmp -I/include -I"C:/Users/nkc10/Documents/R/win-library/3.5/Rcpp/include" -I"C:/Users/nkc10/Documents/R/win-library/3.5/RcppArmadillo/include" -I"C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include" -I"C:/Users/nkc10/Dropbox/Research/sparse_bayesian_infinite_factor_models-master" -O2 -Wall -mtune=generic -c C_functions.cpp -o C_functions.o
In file included from C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include/RcppGSL.h:25:0,
from C_functions.cpp:2:
C:/Users/nkc10/Documents/R/win-library/3.5/RcppGSL/include/RcppGSLForward.h:26:29: fatal error: gsl/gsl_vector.h: No such file or directory
#include <gsl/gsl_vector.h>
^
compilation terminated.
make: *** [C:/PROGRA~1/R/R-35~1.2/etc/x64/Makeconf:215: C_functions.o] Error 1
Error in sourceCpp("C_functions.cpp") :
Error 1 occurred building shared library.
You are close, since you already got the local323 file.
Two more steps:
Copy the c:\local323\include\gsl folder into your RcppGSL folder (i.e., C:\Users\YOU\Documents\R\win-library\3.6\RcppGSL\include) OR into your project directory. I tried the latter, but I think it should work either way.
From the local323 package, copy libgsl.a libgslcblas.a to c:\Rtoools\mingw_64\libs. I have no idea why it doesn't find it in your c:\local323 folder, but this will work.
And I tested it, your code works.
Related
This question already has answers here:
Rcpp - sourceCpp - undefined symbol
(2 answers)
Closed 4 years ago.
I have existing C code that consists of three files: a header file ( a ".h" file), a library file (a ".o" file), and a source file. They currently run under UNIX and as compiled "mex files" in Matlab. I would like to port them to R using Rcpp. They are all long and complex, so I made a minimal example to help me understand how to port them to R.
The simplified header file (my_header.h) is:
typedef unsigned int ui4;
ui4 add_one( ui4 );
The simplified "library" file (my_lib.cpp) is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "my_header.h"
ui4 add_one(ui4 x) {
return(x+1);
}
The simplified function program (my_program.cpp) is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <Rcpp.h>
#include <cmath>
#include "my_header.h"
using namespace Rcpp;
// [[Rcpp::export]]
ui4 my_program_r () {
//int main (int argc, const char * argv[]) {
//
// As a MATLAB mex file, this function calls "main(..."
//
ui4 value = add_one( (ui4)1 );
printf( "%d", value );
return value;
}
From the terminal (I'm on a Mac), I can compile these without an error:
$ g++ my_lib.cpp -c -o my_lib.o
$ g++ my_program.cpp -o my_program my_lib.o
When I try to compile them in RStudio, I get:
> library(Rcpp)
> sourceCpp( "my_program.cpp" )
Warning message:
In sourceCpp("my_program.cpp") :
No Rcpp::export attributes or RCPP_MODULE declarations found in source
>
Why isn't this compiling under Rcpp? How do I specify the linked file (the ".o" library file) in the "sourceCpp" command? Do I need to specify the header file?
The sourceCpp command is meant for single files only. If you have multiple files, you have to use a package:
Call Rcpp::Rcpp.package.skeleton(...) to create a skeleton package.
Copy *.h, *.c and *.cpp to the src folder.
Call Rcpp::compileAtrributes().
Use R CMD build ..., R CMD check ... and R CMD INSTALL ... to build, check and compile the package. (The check will complain about undocumented functions ...)
For more details see Rcpp-package vignette and for example this question. BTW, since R does not have an unsigned int type, I am not sure if your return value will work. You might have to switch to an int or double. I also get a different error message than you:
Error in dyn.load("/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so") :
unable to load shared object '/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so':
/tmp/RtmpSbvXHx/sourceCpp-i686-pc-linux-gnu-0.12.17/sourcecpp_625ad24a943/sourceCpp_2.so: undefined symbol: _Z7add_onej
Are you sure the above code is exactly what you used?
I have header-only library, and I'm getting the strangest compilation error. The problem in proceeding is that I'm not getting this error in a representative minimal example, and not on all compilers (on macOS everything compiles and runs like a charm). I am not sure if I should be worried about something in my code, or if it is an upstream bug. Regardless, I'm not sure how to work around this.
I'm getting the following compiler error:
In file included from /home/tdegeus/opt/include/eigen3/Eigen/SparseCore:59:0,
from /home/tdegeus/opt/include/eigen3/Eigen/Sparse:26,
from /home/tdegeus/opt/include/eigen3/Eigen/Eigen:2,
from /home/tdegeus/prog/src/GooseFEM/docs/examples/Statics/Periodic/LinearElasticity/main.cpp:1:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h: In function ‘void Eigen::internal::permute_symm_to_symm(const MatrixType&, Eigen::SparseMatrix<typename MatrixType::Scalar, DestOrder, typename MatrixType::StorageIndex>&, const typename MatrixType::StorageIndex*) [with int SrcMode = 1; int DstMode = 2; MatrixType = Eigen::SparseMatrix<double>; int DestOrder = 0]’:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h:517:6: internal compiler error: in predicate_mem_writes, at tree-if-conv.c:2252
void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::StorageIndex>& _dest, const typename MatrixType::StorageIndex* perm)
^~~~~~~~~~~~~~~~~~~~
0xb3530b predicate_mem_writes
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2252
0xb3530b combine_blocks
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2377
0xb359bb tree_if_conversion(loop*)
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2883
0xb3663b execute
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2961
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Which disappears if I comment this line (obviously breaking functionality):
m_solver.compute(m_ACuu);
Note that:
Eigen::SparseMatrix<double> m_ACuu;
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> m_solver;
I tried a minimal example:
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/SparseCholesky>
int main()
{
size_t N = 11;
// allocate system
Eigen::SparseMatrix<double> A(N,N);
Eigen::VectorXd f(N);
// set force
f *= 0.0;
f((N-1)/2) = 1.0;
// construct list of Triplets (row,col,data) that from the matrix "A"
std::vector<Eigen::Triplet<double>> Atr;
// - first equation
Atr.push_back(Eigen::Triplet<double>(0,0,+2.0));
Atr.push_back(Eigen::Triplet<double>(0,1,-1.0));
// - body
for ( size_t i=1; i<N-1; ++i ) {
Atr.push_back(Eigen::Triplet<double>(i,i-1,-1.0));
Atr.push_back(Eigen::Triplet<double>(i,i ,+2.0));
Atr.push_back(Eigen::Triplet<double>(i,i+1,-1.0));
}
// - last equation
Atr.push_back(Eigen::Triplet<double>(N-1,N-2,-1.0));
Atr.push_back(Eigen::Triplet<double>(N-1,N-1,+2.0));
// build matrix from Triplets
A.setFromTriplets(Atr.begin(),Atr.end());
// solve the linear system
// - define solver (according to type above)
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver;
// - analyze the system, and factorize (one could solve different right-hand-sides)
// solver.analyzePattern(A);
solver.factorize(A);
// - solve "A * x = f"
Eigen::VectorXd u = solver.solve(f);
// print to screen
std::cout << A << std::endl;
std::cout << u << std::endl;
return 0;
}
Compiled on the same system with the same libraries and with similar options:
g++ -march=native -O3 test.cpp
But this compiles and runs like a charm!?
Note that I've tried several Eigen versions, including 3.3.90.
Edit
Also note that this problem occurs with
g++ --version
g++ (GCC) 7.3.0
But is gone for
g++ (GCC) 6.4.0
I think that this question is not specifically on OpenCV, it seems more an include problem, so please read it even if you don't know the library.
There is an old version of a library (OpenCV) that's installed in /usr/local on the remote machine where I'm working on and where I don't have sudo access.
I've installed an updated version in my local environment /home/spm1428/local and I'm compiling it by using -I/home/spm1428/local/include/opencv and -I/home/spm1428/local/include/opencv2.
However, in a file where #include "opencv/opencv.hpp" I get this error:
In file included from /usr/local/include/opencv2/opencv.hpp:77:0,
from /home/spm1428/CloudCache/Utilities/Utility.hpp:11,
from ../Descriptors/Descriptor.cpp:17:
/usr/local/include/opencv2/highgui/highgui.hpp:165:25: error: redeclaration of ‘IMREAD_UNCHANGED’
It's an error given by the old version of the library installed in /usr/local, but I told him to use the local version using -I!
So it seems that the compiler ignores my -I directives and instead gives the priority to /usr/local/include
Why this happens?
If you wonder the whole compiling command is:
g++ -DCC_DISABLE_CUDA -I/home/spm1428/CloudCache -I/home/spm1428/local/include/opencv -I/home/spm1428/local/include/opencv2 -I/usr/include/boost -I/home/spm1428/vlfeat -O3 -g -Wall -c -fopenmp -std=c++11 -c -o Descriptor.o ../Descriptors/Descriptor.cpp
This error happens both using #include <opencv2/core.hpp> and include "opencv2/core.hpp".
UPDATE OF NEW ERROR:
Changing: #incldue <opencv2/opencv.hpp> to #include "opencv2/core.hpp"
#include "opencv2/imgproc/imgproc.hpp" solved the problem for some reason. However, now when I compile:
g++ -DCC_DISABLE_CUDA -I/home/spm1428/local/include -I/home/spm1428/CloudCache -I/home/spm1428/local/include/opencv -I/home/spm1428/local/include/opencv2 -I/usr/include/boost -I/home/spm1428/vlfeat -O3 -g -Wall -c -fopenmp -std=c++11 -c -o SIFTOpenCV.o ../Descriptors/SIFTOpenCV.cpp
I get this error:
../Descriptors/SIFTOpenCV.cpp:31:9: error: ‘class cv::Feature2D’ has no member named ‘detectAndCompute’
sift->detectAndCompute(img, cv::Mat(), pts, descriptors);
SIFTOpenCV.cpp includes SIFTOpenCV.hpp, which includes #include "opencv2/xfeatures2d.hpp". I think that this error is related somehow to the previous one.
The weirdest thing is that this compiles correctly on my local machine (where I have sudo access and I installed it /usr/local)
This is the class SIFTOpenCV.hpp:
#include "Descriptors/Descriptor.hpp"
#include <opencv2/xfeatures2d.hpp>
namespace cc{
class SIFTOpenCV : public Descriptor{
public:
SIFTOpenCV(int nFeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04, double edgeThreshold=10, double sigma=1.6);
void mapParams(std::vector<std::pair<std::string,std::string>> ¶ms);
void ComputeDescriptors(cv::Mat &img, cv::Mat1f &descriptors);
private:
cv::Ptr<cv::xfeatures2d::SIFT> sift;
int nFeatures, nOctaveLayers;
double contrastThreshold, edgeThreshold, sigma;
};
}
While Descriptor.hpp:
#include "opencv2/core.hpp"
#include <string>
#include <map>
namespace cc{
class Descriptor{
public:
virtual void mapParams(std::vector<std::pair<std::string,std::string>> ¶ms) = 0;
virtual void ComputeDescriptors(cv::Mat &img, cv::Mat1f &descriptors) = 0;
virtual void ComputeDescriptors(const std::string &fileName, const std::string &imgExt, cv::Mat1f &descriptor);
virtual void ComputeDescriptors(const std::string &dirPath, const std::string &imgExt, std::vector<cv::Mat1f> &descriptors);
void setResizeDim(const size_t resizeDim);
void setSamples (const size_t samples);
void setOMP(const bool omp);
virtual ~Descriptor();
private:
void ComputeDescriptorsRange(const std::vector<std::string> &files, std::vector<cv::Mat1f> &descriptors, const int start, const int finish, size_t errors);
size_t resizeDim = 0; //comput full-size image
int samples = 0;
bool omp = true;
};
}
I found the solution by myself: executing cpp -v returned me:
/usr/local/include
/usr/include
/home/spm1428/local/include
...
This means that using -I/home/spm1428/local/include was ignored because already included, but the priority was given to the old version in /usr/local/include.
Installing OpenCV in a new local directory and include it with -I gave the priority to the new version and solved the problem.
I have a C++ function called "file1.cpp" that looks like:
#include <cmath>
#include <stdio.h>
#include <RcppArmadillo.h>
#include <boost/math/special_functions/gamma.hpp>
#include <mpi.h>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
using namespace std;
using namespace arma;
using namespace boost::math;
const double PIVAL = std::acos(0.0)*2;
class function1
{
...
}
extern "C"
void functin2
{
...
}
I want to call it from an R function. In order to do that I needed to compile it first to get the "file1.so", which I can use it later in the R command:
dyn.load("file1.so.so")
So it ubuntu 16.10 terminal I wrote:
$ R CMD SHLIB file1.cpp -O2 -larmadillo -llapack -lblas
when I press enter I will get the follwing error message:
g++ -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-rAT5Oi/r-base-3.3.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -c file1.cpp -o file1.o
file1.cpp:12:81: fatal error: RcppArmadillo.h: No such file or directory
#include <RcppArmadillo.h>
I couldn't find solution for that error. So, I tried to call the C++ function from inside Rstudio. I wrote the follwing commands:
library(Rcpp)
library(RcppArmadillo)
sourceCpp("file1.cpp")
function2()
When executing it I will get this error:
file1.cpp:11:81: fatal error: RcppArmadillo.h: No such file or directory
Anybody have an idea about how to solve it? Thanks in advance.
Best Regards,
Please read some of the many existing examples on RcppArmadillo here, at the Rcpp Gallery or, heaven forbid, in the package documentation.
You could of course just call RcppArmadillo.package.skeleton() and have a working package created for you to start from and place your local changes in.
See this:
R> setwd("/tmp")
R> RcppArmadillo::RcppArmadillo.package.skeleton("demoPkg")
Calling kitten to create basic package.
Creating directories ...
Creating DESCRIPTION ...
Creating NAMESPACE ...
Creating Read-and-delete-me ...
Saving functions and data ...
Making help files ...
Done.
Further steps are described in './demoPkg/Read-and-delete-me'.
Adding pkgKitten overrides.
Deleted 'Read-and-delete-me'.
Done.
Consider reading the documentation for all the packaging details.
A good start is the 'Writing R Extensions' manual.
And run 'R CMD check'. Run it frequently. And think of those kittens.
Adding RcppArmadillo settings
>> added Imports: Rcpp
>> added LinkingTo: Rcpp, RcppArmadillo
>> added useDynLib and importFrom directives to NAMESPACE
>> added Makevars file with Rcpp settings
>> added Makevars.win file with RcppArmadillo settings
>> added example src file using armadillo classes
>> added example Rd file for using armadillo classes
>> invoked Rcpp::compileAttributes to create wrappers
R>
which creates, _inter alia, this file:
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
// we only include RcppArmadillo.h which pulls Rcpp.h in for us
#include "RcppArmadillo.h"
// via the depends attribute we tell Rcpp to create hooks for
// RcppArmadillo so that the build process will know what to do
//
// [[Rcpp::depends(RcppArmadillo)]]
// simple example of creating two matrices and
// returning the result of an operatioon on them
//
// via the exports attribute we tell Rcpp to make this function
// available from R
//
// [[Rcpp::export]]
arma::mat rcpparma_hello_world() {
arma::mat m1 = arma::eye<arma::mat>(3, 3);
arma::mat m2 = arma::eye<arma::mat>(3, 3);
return m1 + 3 * (m1 + m2);
}
// another simple example: outer product of a vector,
// returning a matrix
//
// [[Rcpp::export]]
arma::mat rcpparma_outerproduct(const arma::colvec & x) {
arma::mat m = x * x.t();
return m;
}
// and the inner product returns a scalar
//
// [[Rcpp::export]]
double rcpparma_innerproduct(const arma::colvec & x) {
double v = arma::as_scalar(x.t() * x);
return v;
}
// and we can use Rcpp::List to return both at the same time
//
// [[Rcpp::export]]
Rcpp::List rcpparma_bothproducts(const arma::colvec & x) {
arma::mat op = x * x.t();
double ip = arma::as_scalar(x.t() * x);
return Rcpp::List::create(Rcpp::Named("outer")=op,
Rcpp::Named("inner")=ip);
}
and that should be enough to get you going.
I am trying to use XCppRefl lib to achieve reflections in c++. http://www.extreme.indiana.edu/reflcpp/. I could successfully install this library in linux and run the tests given with the source code of the library.
Here is the code that I have written --
#include <iostream>
using namespace std;
#include <reflcpp/ClassType_tmpl.hpp>
#include <reflcpp/BoundClassType_tmpl.hpp>
#include <reflcpp/Exceptions.hpp>
using namespace reflcpp;
#include "Complex.h"
int main()
{
//ClassType ct = ClassType::getClass( string("Complex") );
////PtrHolder_smptr_t obj = ct.createInstance();
//assert(ct.name() == "B");
Complex x;
int ret;
Complex a;
ClassType c = ClassType::getClass( string("Complex") );
//cout<<"name :: "<<c.name()<<endl;
}
It seems to compile just fine --
$ g++ -g -I /usr/local/include/reflcpp-0.2/ -L /usr/local/include/reflcpp-0.2/ -lreflcpp main.cpp
However when I execute the executable (a.out), I get a core-dump
a.out: Type.cpp:87: static const reflcpp::Type_body* reflcpp::Type_body::getType(const std::string&): Assertion `s_class_name_map' failed.
Aborted (core dumped)
Does anyone has used this lib before? Please help.
you have to link your main.o to libreflcpp.a . after compiling use this:
g++ -p -pg -o"project_name" ./A.o ./A_reflection.o ./main.o /usr/local/lib/libreflcpp.a