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
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'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 got stuck with calling the MKL Blas function cblas_zgemv
There are two coeffitiens alpha and beta which are complex numbers:
alpha
REAL for sgemv
DOUBLE PRECISION for dgemv
COMPLEX for cgemv, scgemv
DOUBLE COMPLEX for zgemv, dzgemv
. But in the definition of the function:
void cblas_zgemv (const CBLAS_ORDER order, const CBLAS_TRANSPOSE TransA,
const MKL_INT M, const MKL_INT N, const void *alpha, const void *A,
const MKL_INT lda, const void *X, const MKL_INT incX, const void *beta,
void *Y, const MKL_INT incY);
I have tried to set the alpha = complex(1.0,0) but this return me an error:
error: no suitable conversion function from "complex<double>" to "const void *" exists
What can I do? I don't understand what this const void* is...
The function expects a pointer to the complex value, not the value itself. You'll need a variable to store the value in, and then pass the address of that:
std::complex<double> alpha(1,0);
cblas_zgemv(..., &alpha, ...);
I believe this is safe since lapack_complex_double is layout-compatible with (and, in C++, is an alias for) std::complex<double>. To be on the safe side, you might prefer to use lapack_complex_double when calling that library.
I have a regular C++ class like PardisoSolver.h:
#ifndef PARDISOSOLVER_H_
#define PARDISOSOLVER_H_
class PardisoSolver {
public:
/* Initializes a new Solver with the given matrix in CSR */
PardisoSolver(
int* ia,
int* ja,
double* a,
int n,
int nja);
virtual ~PardisoSolver();
void setMatrixType(int mtype);
void pardisoSymFactorize();
private:
static int get_nproc(void);
void handle_error(int ierror, int line);
int* ia; // row indices
int* ja; // column pointer
double* a; // non zero values
int n_eq; // size of matrix
int nja; // number of non zero elements
bool factorized;
/* PARDISO SETTINGS */
void *pt[64];
int maxfct;
int mnum;
int mtype;
int perm;
int nrhs;
int iparm[64];
int msglvl;
int error;
double dparm[64];
double dzero;
int izero;
};
#endif /* PARDISOSOLVER_H_ */
And on the other hand I have the implementations in PardisoSolver.cpp. Here I have an additional declaration of a C function just along with the implementations of the class:
extern "C" void pardiso (void *, int *, int *, int *, int *, int *,
double *, int *, int *, int *, int *, int *,
int *, double *, double *, int *, double *);
Now when I try to call that function like
pardiso (pt, &maxfct, &mnum, &mtype, &phase,
&n_eq, a, ia, ja, &izero, &nrhs,
iparm, &msglvl, &dzero, &dzero, &error, dparm);
I get the compile error
PardisoSolver.cpp:94: undefined reference to `pardiso'
where the call is in line 94. Did I declare the C function in the wrong place? As I got it, it cannot be a member of a class so this should be the way to call it. Thanks for the help.
All of this suggest that your program design needs improvment. First of all, there should only be one interface to your "module" (class + other stuff). You should not have "a class, and then some", that doesn't make any sense. All functions related to the functionality of the class should be included in that class. All that aren't related, should be moved to another part of the program.
Once you have straightened that out, you need to clarify the programming language. Is this C or C++? Is it C++ with a caller in C? It seems to be the latter. If so, you need to separate the two languages somehow. As one example: in Windows you could place the C++ class in a DLL, with an interface that can be called from C.
And finally, you should consider whether it makes sense to have a function taking 17 pointers as parameters. Are these parameters not related at all? Could they be grouped in structs/classes? Or perhaps this is simply a needlessly complex monster function, that could be split in several different ones.
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.