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())
Related
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 am having trouble executing an FFT plan with fftw library. I am declaring fftIn and fftOut vectors with size 2048, and defining a fftwf_plan_dft_1d with them.
But when I execute the plan, suddenly the fftOut vector gets all wrong. In my code, I can see while debugging that its size goes from 2048 to 0. When I wrote the small executable example below, I just get bad sizes such as 17293858104588369909.
Of course, when I try to access to the first item of the vector, a SIGSEGV happens.
My code:
#include <complex>
#include <iostream>
#include <fftw3.h>
#include <vector>
using namespace std;
typedef std::vector<std::complex<float>> fft_vector;
int main() {
const unsigned int VECTOR_SIZE = 2048;
fft_vector* fftIn = new fft_vector(VECTOR_SIZE);
fft_vector* fftOut = new fft_vector(VECTOR_SIZE);
fftwf_plan fftPlan = fftwf_plan_dft_1d(VECTOR_SIZE, reinterpret_cast<fftwf_complex*>(fftIn), reinterpret_cast<fftwf_complex*>(fftOut), FFTW_FORWARD, FFTW_ESTIMATE);
fftwf_execute(fftPlan);
std::cout << fftOut->size() << std::endl;
std::cout << fftOut->at(0).real() << fftOut->at(0).imag() << std::endl;
return 0;
}
Of course, I know fftIn vector is empty in this example, but output is broken when it is not anyway. In this case, the SIGSEGV happens in the second cout as described before.
My full code has threads (but FFT happens all within the same thread, so race conditions should not apply), and that was one of the reasons for trying to isolate the code in this small example, just in case, but it seems to have something wrong anyway.
Any idea?
The main issue is that you are passing a vector to it, which won't work; you need to pass the vector contents: &((*fftIn)[0]) and &((*fftOut)[0]) or something comparable. As it is, you are telling fftw to stomp on the vector object's metadata (including the length, which explains why it was sometimes 0 and sometimes gibberish). It was literally writing to the start of the vector structure because that's what the pointer points to. Also it was using fftIn's metadata as part of the input to the fft, which is also not what you want.
You might consider using fftw_complex and fftw_malloc instead, which will ensure that your data is stored aligned the way fftw needs: http://www.fftw.org/doc/SIMD-alignment-and-fftw_005fmalloc.html
You can put fftOut in a vector afterwards if you really need it. This will ensure that you get the advantages of SIMD, if available, and avoid any compiler- or platform-specific behavior with complex types and memory allocation. Using fftw's type and allocator means your code will always work optimally and as you expect, regardless of which platform you run it on and which compiler you use.
Here is an example of your transform from fftw's documentation (http://www.fftw.org/doc/Complex-One_002dDimensional-DFTs.html):
#include <fftw3.h>
...
{
fftw_complex *in, *out;
fftw_plan p;
...
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
...
fftw_execute(p); /* repeat as needed */
...
fftw_destroy_plan(p);
fftw_free(in); fftw_free(out);
}
Try to match this example and your code should do what you expect.
EDIT:
If you must use C++ complex and vector, this should work:
const unsigned int VECTOR_SIZE = 2048;
fft_vector* fftIn = new fft_vector(VECTOR_SIZE);
fft_vector* fftOut = new fft_vector(VECTOR_SIZE);
fftwf_plan fftPlan = fftwf_plan_dft_1d(VECTOR_SIZE,
reinterpret_cast<fftwf_complex*>(&(*fftIn)[0]),
reinterpret_cast<fftwf_complex*>(&(*fftOut)[0]),
FFTW_FORWARD, FFTW_ESTIMATE);
fftwf_execute(fftPlan);
std::cout << fftOut->size() << std::endl;
std::cout << fftOut->at(0).real() << fftOut->at(0).imag() << std::endl;
Notice that you have to dereference the vector pointer in order to get the [] operator to work; getting index 0 gives you the first element of the actual vector data and so the address of that element is the address (pointer) you need to give to fftw_plan.
you cannot reinterpret_cast a vector to a pointer on complex elements: you're accessing the vector inner variables (like the size), not necessarily the vector raw data, which probably explains why the object is trashed in output, and all the bad things that happen next.
On the other hand, casting the address of the vector data works.
Just do (no need to new the vectors too, use standard declaration):
fft_vector fftIn(VECTOR_SIZE);
fft_vector fftOut(VECTOR_SIZE);
// load your data in fftIn
fftwf_plan_dft_1d(VECTOR_SIZE, static_cast<const fftwf_complex*>(&fftIn[0]), static_cast<fftwf_complex*>(&fftOut[0]), FFTW_FORWARD, FFTW_ESTIMATE);
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
What is the best way to load from a const pointer using altivec?
According to the documentation (and my results) vec_ld doesn't take a const pointer as an argument:
http://www-01.ibm.com/support/knowledgecenter/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/compiler_ref/vec_ld.html
Hence something like this will fail:
void foo(const float* A){
vector4double a = vec_ld(0,A);
...
}
A nasty work-around would be:
void foo(const float* A){
vector4double a = vec_ld(0,const_cast<float*>A);
...
}
Is there a better way to do this?
Thank you.
Use const_cast.
It exists exactly for that purpose: handling const-incorrect APIs.
Function vec_ld loads a 128-bit vector (4 float values) to Altivec register. Loading is performed from 16-byte aligned address. It doesn't work properly if address doesn't have a 16-byte align. In that case you have to use next function:
typedef __vector uint8_t v128_u8;
typedef __vector float v128_f32;
inline v128_f32 Load(const float * p)
{
v128_u8 lo = vec_ld(0, p);
v128_u8 hi = vec_ld(A, p);
return (v128_f32)vec_perm(lo, hi, vec_lvsl(0, p));
}
or use function vec_vsx_ld if you have Power7 or Power8 CPU.
Your const float * means you point to something that is not modifiable, but you still can point to something else.
I don't know about your function vec_ld but I guess as it demands a pointer to a float, the function will change the value pointed.
Then, you have to provide a modifiable value.
I would not use your nasty workaround, because the user calling your method won't expect it's float value to be modified and it will surely because a nasty bug in the future.
If you could change your method foo to foo(float * A) or foo(float & A) it would be a relief.
For more information about const pointer, see : What is the difference between const int*, const int * const, and int const *?
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.