I'm trying to call a C routine from the cubature package in a c++ function to perform multidimensional integration.
The basic R example I'm trying to reproduce is
library(cubature)
integrand <- function(x) sin(x)
adaptIntegrate(integrand, 0, pi)
I could just call this R function from Rcpp following this recipe from the gallery, but there would be some performance penalty in switching back and forth from c/c++ to R. It seems more sensible to directly call the C function from C++.
The C routine adapt_integrate is exported from cubature with
// R_RegisterCCallable("cubature", "adapt_integrate", (DL_FUNC) adapt_integrate);
I don't understand how to call it from c++, however. Here's my lame attempt,
sourceCpp(code = '
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double integrand(double x){
return(sin(x));
}
// [[Rcpp::depends(cubature)]]
// [[Rcpp::export]]
Rcpp::List integratecpp(double llim, double ulim)
{
Rcpp::Function p_cubature = R_GetCCallable("cubature", "adapt_integrate");
Rcpp::List result = p_cubature(integrand, llim, ulim);
return(result);
}
'
)
integratecpp(0, pi)
This fails to compile; clearly I'm doing something very silly and missing some important steps to convert the output of R_GetCCallable into an Rcpp::Function (or call it directly?). I've read several related posts dealing with function pointers, but haven't seen an example using an external C function.
Unfortunately cubature does not ship the headers in inst/include, so you have to borrow that from them and do something like this in your code:
typedef void (*integrand) (unsigned ndim, const double *x, void *,
unsigned fdim, double *fval);
int adapt_integrate(
unsigned fdim, integrand f, void *fdata,
unsigned dim, const double *xmin, const double *xmax,
unsigned maxEval, double reqAbsError, double reqRelError,
double *val, double *err)
{
typedef int (*Fun)(unsigned,integrand,void*,unsigned,
const double*,const double*, unsigned, double, double, double*, double*) ;
Fun fun = (Fun) R_GetCCallable( "cubature", "adapt_integrate" ) ;
return fun(fdim,f,fdata,dim,xmin,xmax,maxEval,reqAbsError, reqRelError,val,err);
}
It might be a good idea to negociate with the maintainer of cubature that he ships declarations in inst/include so that you'd only have to use LinkingTo.
Didn't see this question earlier, and it looks like #Romain addressed it.
For completeness, a working example of how to do this when all parties play along is provided by the xts and RcppXts packages. In xts, we do this (for about ten functions) in the (source) file inst/include/xtsAPI.h:
SEXP attribute_hidden xtsLag(SEXP x, SEXP k, SEXP pad) {
static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;
if (fun == NULL)
fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","lagXts");
return fun(x, k, pad);
}
along with the usual business of R_registerRoutines and R_RegisterCCallable.
In RcppXts this is picked up (in an Rcpp Module) as
function("xtsLag",
&xtsLag,
List::create(Named("x"), Named("k"), Named("pad")),
"Extract the coredata from xts object");
which works pretty well. Someone reprimanded me to write the xts side more compactly (as the if NULL is spurious) which I will get to ... eventually.
This question is three years old now but I want to point out that multidimensional integration with Rcpp may be easier now that the RcppNumerical library is available:
https://github.com/yixuan/RcppNumerical
The routines for computing integrals are based on Thomas Hahn's Cuba package and are also available in the R2Cuba library on CRAN, so if you can accept using the Cuba routines over the function adaptIntegrate() from Cubature, this package may be of interest.
Related
Very simply, I’m using an optimization library in C++ that takes in a function of a single variable. I would like to be able to pass in multiple parameters though (which this library does not support). What I would like to do is create a lambda function of the sort (kind of like in Python) that lets me represent the cost function as a function of a single variable that passes in two parameters.
Here’s a simplified version of what I’m going for in pseudocode. Any help would be much appreciated. I can’t seem to get this to work with lambda in C++.
Optimize comes from a library (asa047). The version I wrote here isn’t at all realistic, but is just meant to demonstrate what this function takes in.
double cost(double x, double param1, double param2){
return x*param1 + param2;
}
double optimize(double fn( double x), double initial_value){
return optimal_x;
}
int main(){
double param1 = 2;
double param2 = 3;
function_object f; //What I would like to create
f(double x){
return cost(x,param1,param2);
}
optimize(f,2);
}
What I could see under the link to the asa47 library is that the function comes with source code. That means you can modify its parameters to pass any additional stuff as you need. I think that's the easiest and most correct way to achieve what you need. I.e. if fir example you want to additional int parameter, double fn ( double x[] ) can be replaces with something like double fn ( double x[], int p), then add int p to the "nelmin" function itself, and then modify call to fn() in the nelmin() to pass that additional p.
I want to use sba to do bundle adjustment task, and I would like to use sba-1.6(http://users.ics.forth.gr/~lourakis/sba/). But the user manual do not tell exactly how to use it. and I am kind of confused.
For example, I want to use this function sba_mot_levmar which has a parameter p I do not understand what it is. The problem here is that the provided examples make the rotation part in p to be 0. so that is p?
and after call this function, what is in p?
int sba_mot_levmar(
const int n, /* number of points */
const int m, /* number of images */
const int mcon,
char *vmask,
double *p, /* initial parameter vector p0: (a1, ..., am).
* aj are the image j parameters, size m*cnp */
const int cnp,/* number of parameters for ONE camera; e.g. 6 for Euclidean cameras */
double *x,
double *covx,
const int mnp,
void (*proj)(int j, int i, double *aj, double *xij, void *adata),
void (*projac)(int j, int i, double *aj, double *Aij, void *adata),
void *adata,
const int itmax,
const double opts[SBA_OPTSSZ]
double info[SBA_INFOSZ]
)
There's good tutorials for how to use sba with Ros, yet I am not sure if it is Lourakis implementation :
-http://wiki.ros.org/sba/Tutorials/IntroductionToSBA
it explain an example, and lately I found a wrapper for it in python (if you don't care about the language used):
-https://pypi.org/project/sba/
I believe these are easier to use and run than the straight-forward way you mention
Summary
What can I do if a function of an external library expect a non-const pointer (double *) but it is known that the values of it remains the same so according to const correctness I should pass a const pointer (const double *)?
The situation
I'd like to create a function that calculates the auto-correlation of a vector but unfortunately it seems that fftw3 (which is a C API) doesn't care about const correctness.
The function I'd like to call is:
fftw_plan fftw_plan_dft_r2c_1d(int n0,
double *in, fftw_complex *out,
unsigned flags);
And the code I'd like to create:
vector<double> autocorr(const vector<double>& data)
{
vector<double> ret(data.size(), 0);
// prepare other variables
fftw_plan a = fftw_plan_dft_r2c_1d(size, &data.front(), tmp, FFTW_ESTIMATE);
// do the rest of the work
return ret;
}
Of course, this will not work because the argument of my function is const vector<double>& data so I can't call &data.front(). What is the most appropriate solution to keep the const-correctness of my code?
If you're confronted with a C API that promises more than it shows with respect to const-correctness, it is time to const_cast:
vector<double> autocorr(const vector<double>& data)
{
vector<double> ret(data.size(), 0);
// prepare other variables
fftw_plan a = fftw_plan_dft_r2c_1d(size, const_cast<double*>(&data.front()), tmp, FFTW_ESTIMATE);
// do the rest of the work
return ret;
}
Also note this sentence in the documentation:
in and out point to the input and output arrays of the transform, which may be the same (yielding an in-place transform). These arrays are overwritten during planning, unless FFTW_ESTIMATE is used in the flags.
Since you're using the FFTW_ESTIMATE flag, you should be fine in this case.
The reason FFTW developers decided not to duplicate this function for the sake of const is that in C, const isn't at all a big deal, and FFTW is a C library.
First file a bug report against the library, then const_cast away the const-ness of &data.front(), for example const_cast<double*>(&data.front())
I'm trying to call a C routine from the cubature package in a c++ function to perform multidimensional integration.
The basic R example I'm trying to reproduce is
library(cubature)
integrand <- function(x) sin(x)
adaptIntegrate(integrand, 0, pi)
I could just call this R function from Rcpp following this recipe from the gallery, but there would be some performance penalty in switching back and forth from c/c++ to R. It seems more sensible to directly call the C function from C++.
The C routine adapt_integrate is exported from cubature with
// R_RegisterCCallable("cubature", "adapt_integrate", (DL_FUNC) adapt_integrate);
I don't understand how to call it from c++, however. Here's my lame attempt,
sourceCpp(code = '
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double integrand(double x){
return(sin(x));
}
// [[Rcpp::depends(cubature)]]
// [[Rcpp::export]]
Rcpp::List integratecpp(double llim, double ulim)
{
Rcpp::Function p_cubature = R_GetCCallable("cubature", "adapt_integrate");
Rcpp::List result = p_cubature(integrand, llim, ulim);
return(result);
}
'
)
integratecpp(0, pi)
This fails to compile; clearly I'm doing something very silly and missing some important steps to convert the output of R_GetCCallable into an Rcpp::Function (or call it directly?). I've read several related posts dealing with function pointers, but haven't seen an example using an external C function.
Unfortunately cubature does not ship the headers in inst/include, so you have to borrow that from them and do something like this in your code:
typedef void (*integrand) (unsigned ndim, const double *x, void *,
unsigned fdim, double *fval);
int adapt_integrate(
unsigned fdim, integrand f, void *fdata,
unsigned dim, const double *xmin, const double *xmax,
unsigned maxEval, double reqAbsError, double reqRelError,
double *val, double *err)
{
typedef int (*Fun)(unsigned,integrand,void*,unsigned,
const double*,const double*, unsigned, double, double, double*, double*) ;
Fun fun = (Fun) R_GetCCallable( "cubature", "adapt_integrate" ) ;
return fun(fdim,f,fdata,dim,xmin,xmax,maxEval,reqAbsError, reqRelError,val,err);
}
It might be a good idea to negociate with the maintainer of cubature that he ships declarations in inst/include so that you'd only have to use LinkingTo.
Didn't see this question earlier, and it looks like #Romain addressed it.
For completeness, a working example of how to do this when all parties play along is provided by the xts and RcppXts packages. In xts, we do this (for about ten functions) in the (source) file inst/include/xtsAPI.h:
SEXP attribute_hidden xtsLag(SEXP x, SEXP k, SEXP pad) {
static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;
if (fun == NULL)
fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","lagXts");
return fun(x, k, pad);
}
along with the usual business of R_registerRoutines and R_RegisterCCallable.
In RcppXts this is picked up (in an Rcpp Module) as
function("xtsLag",
&xtsLag,
List::create(Named("x"), Named("k"), Named("pad")),
"Extract the coredata from xts object");
which works pretty well. Someone reprimanded me to write the xts side more compactly (as the if NULL is spurious) which I will get to ... eventually.
This question is three years old now but I want to point out that multidimensional integration with Rcpp may be easier now that the RcppNumerical library is available:
https://github.com/yixuan/RcppNumerical
The routines for computing integrals are based on Thomas Hahn's Cuba package and are also available in the R2Cuba library on CRAN, so if you can accept using the Cuba routines over the function adaptIntegrate() from Cubature, this package may be of interest.
I have been exploring algorithms that require some work on matrices, and I have gotten some straightforward code working on my Linux machine. Here is an excerpt:
extern "C" {
// link w/ LAPACK
extern void dpptrf_(const char *uplo, const int *n, double *ap, int *info);
extern void dpptri_(const char *uplo, const int *n, double *ap, int *info);
// BLAS todo: get sse2 up in here (ATLAS?)
extern void dgemm_(const char *transa, const char *transb, const int *m,
const int *n, const int *k, const double *alpha, const double *a,
const int *lda, const double *b, const int *ldb, const double *beta,
double *c, const int *ldc);
}
// in-place: be sure that (N*(N+1)/2) doubles have been initialized
inline void invert_mat_sym_packed(double *vd, int n) {
int out = 0;
dpptrf_("U",&n,vd,&out);
ASSERT(!out);
dpptri_("U",&n,vd,&out);
ASSERT(!out);
}
// use with col-major ordering!!!
inline void mult_cm(double *a, double *b, double alpha, int m, int k, int n, double *c) {
int lda = m, ldb = k, ldc = m; double beta = 1.0;
dgemm_("N","N",&m,&n,&k,&alpha,a,&lda,b,&ldb,&beta,c,&ldc);
}
all I had to do was sudo apt-get install liblapack, and link against the library.
I am now trying to get this code working from MinGW using the 32-bit dll's from here but I am seeing segfaults and invalid output. I will proceed with gdb to determine the location of the error but I suspect there's a better, cleaner, more portable way to get this done.
What I did to get it to compile was install fortran for mingw (mingw-get install fortran) and link to the 32bit BLAS and LAPACK dll's from the earlier link.
I'm not sure how much I'm missing here... How does everybody else get their LAPACK going when coding with gcc for win32?
What I'm looking for is an easy-to-use C interface. I don't want wrapper classes all over the place.
I tried to find a download for Intel MKL... Ain't even free software!?
I solved the problem. It had nothing to do with the way I was calling the routines, I failed to memset my buffers to zero prior to accumulating values onto them.
Calling fortran routines is basically just as straightforward as it is to do from Linux.
However, another rather serious problem has appeared: Once I use the lapack routines my program no longer handles exceptions. See here.