Eigenvalues calculations in C-within-R codes - c

I am writing R code which uses compiled C code.
From "Writing R Extensions" document, I learned there are many R executable/DLL that can be called from C code. The header file ‘Rmath.h’ lists many functions that are available and its source codes are listed on the this website: http://svn.r-project.org/R/trunk/src/nmath/
I need to calculate singular value decomposition of many matrices, however I do not find subroutines which does this on the above website. (So I am assuming that Rmath.h does not contain SVD subroutines) Is there simple way to do eigenvalue calculations in C-within-R code?
Thank you very much.

If you're open to using Rcpp and its related packages, the existing examples for the fastLm() show you how to do this with
Eigen via RcppEigen
Armadillo via RcppArmadillo
the GSL via RcppGSL
where the latter two will use the same BLAS as R, and Eigen has something internal that can often be faster. All the packages implement lm() using the decompositions offered by the language (often using solve or related, but switching to SVD is straightforward once you have the toolchain working for you).
Edit: Here is an explicit example. Use the following C++ code:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec getEigen(arma::mat M) {
return arma::eig_sym(M);
}
save in a file "eigenEx.cpp". Then all it takes is this R code:
library(Rcpp) ## recent version for sourceCpp()
sourceCpp("eigenEx.cpp") ## converts source file into getEigen() we can call
so that we can run this:
set.seed(42)
X <- matrix(rnorm(3*3), 3, 3)
Z <- X %*% t(X)
getEigen(Z) ## calls function created above
and I get the exact same eigen vector as from R. It really doesn't get much easier.
It also lets Armadillo chose what method to use for the Eigen decomposition, and as David hinted, this is something quicker than a full-blown SVD (see the Armadillo docs).

You can use one of many available Linear Algebra (lapack) libraries. Here is a link explaining how to get lapack libraries for windows. GOTOBLAS, and ACML are free. MKL is also free for non-commercial use. Once you have the libraries installed, the function you are looking for is sgesvd (for float) or dgesvd (for double).
Here are a couple of examples from Intel on how to use gesvd.
Row Major
Col Major
In case you are using Linux, Check out GNU SL and Eigen. These libraries can usually be installed from the package manager of the distribution.

Related

In what library is dgesvd_?

I'm trying to use the function dgesvd_() in a code and just can't find the library I have to include in order to the compiler to detect it!
I've only discovered some LAPACK or something like that but couldn't see includes or relevant information anywhere.
dgesvd computes the singular value decomposition (SVD) of a real matrix. It is a part of LAPACK. LAPACK is not really a library but an interface for numerical algebra functions. The standard implementation is the one provided by Netlib LAPACK. However, the Intel MKL also implement this (more efficiently than the one of Netlib). LAPACKE is a C interface of the FORTRAN one provided by the Netlib implementation. It provides a header than can be used for C project to call LAPACK functions (linked at runtime). You could use it in your C project as long as you link a LAPACK-compatible library.

Efficient calling of F95 in R: use .Fortran or .Call?

I am writing some R simulation code, but want to leverage Fortran's swift Linear Algebra libraries to replace the core iteration loops. So far I was looking primarily at the obvious option of using .Fortran to call linked F95 subroutines; I figured I should optimize memory use (I am passing very large arrays) and set DUP=FALSE but then I read the warning in manual about the dangers of this approach and of its depreciation in R 3.1.0 and disablement in R 3.2.0. Now the manual recommends switching to .Call, but this function offers no Fortran support natively.
My googling has yielded a stackoverflow question which explores an approach of linking the Fortran subroutine through C code and the calling it using .Call. This seems to me the kind of thing that could either work like a charm or a curse. Hence, my questions:
Aiming for speed and robustness, what are the risks and benefits of calling Fortran via .Fortran and via .Call?
Is there a more elegant/efficient way of using .Call to call Fortran subroutines?
Is there another option altogether?
Here's my thoughts on the situation:
.Call is the generally preferred interface. It provides you a pointer to the underlying R data object (a SEXP) directly, and so all of the memory management is then your decision to make. You can respect the NAMED field and duplicate the data if you want, or ignore it (if you know that you won't be modifying the data in place, or feel comfortable doing that for some other reason)
.Fortran tries to automagically provide the appropriate data types from an R SEXP object to a Fortran subroutine; however, its use is generally discouraged (for reasons not entirely clear to me, to be honest)
You should have some luck calling compiled Fortran code from C / C++ routines. Given a Fortran subroutine called fortran_subroutine, you should be able to provide a forward declaration in your C / C++ code as e.g. (note: you'll need a leading extern "C" for C++ code):
void fortran_subroutine_(<args>);
Note the trailing underscore on the function name -- this is just how Fortran compilers (that I am familiar with, e.g. gfortran) 'mangle' symbol names by default, and so the symbol that's made available will have that trailing underscore.
In addition, you'll need to make sure the <args> you choose map to from the corresponding C types to the corresponding Fortran types. Fortunately, R-exts provides such a table.
In the end, R's R CMD build would automatically facilitate the compilation + linking process for an R package. Because I am evidently a glutton for punishment, I've produced an example package which should provide enough information for you to get a sense of how the bindings work there.
3. Is there another option altogether? YES
The R package dotCall64 could be an interesting alternative. It provides .C64() which is an enhanced version of the Foreign Function Interface, i.e., .C() and .Fortran().
The interface .C64() can be used to interface both Fortran and C/C++ code. It
has a similar usage as .C() and .Fortran()
provides a mechanism to avoid unnecessary copies of read-only and write-only arguments
supports long vectors (vectors with more then 2^31-1 elements)
supports 64-bit integer type arguments
Hence, one can avoid unnecessary copies of read-only arguments while avoiding the .Call() interface in combination with a C wrapper function.
Some links:
The R package dotCall64: https://CRAN.R-project.org/package=dotCall64
Description of dotCall64 with examples: https://doi.org/10.1016/j.softx.2018.06.002
An illustration where dotCall64 is used to make the sparse matrix algebra R package spam compatible with huge sparse matrices (more than 2^31-1 non-zero elements): https://doi.org/10.1016/j.cageo.2016.11.015
I am one of the authors of dotCall64 and spam.

Uniroot function in C

In a C program that gets called from within R, I need to use the 'uniroot' function of R. One way to do this is to invoke R again from C with the 'call_R' function. I am wondering if there is a better way ? Is there a function in 'Rmath.h'to do this ?
As per ?uniroot, the R function is basically a wrapper around some freely available C source code for implementing Richard Brent's root finding algorithm -- it even gives the link. So if you're already programming in C, you don't need to touch R at all for this.
The Rmath library provides a number statistical distribution functions, but no access to R itself.
What you want amounts to embedding R in your C program, which is doable but a little tedious. If you are to C++, you could look at my RInside which makes this pretty painless via C++. It comes with a fairly decent number of examples.

Quaternions in CLAPACK or an Alternate C Style Quaternion Library

I am porting a set of spatial computations to an embedded environment that essentially compiles and runs C code.
I have replaced a number of the linear algebra functions that previously used VNL (a templated C++ library that will not work on the new platform) with CBLAS and CLAPACK. Their API (all parameters are pointers, no templates) is perfect for what I am doing.
The catch, however, is I do not see quaternion based functions anywhere in the CLAPACK Users Guide. Am I missing a section and there is quaternion support somewhere? If so, please point me to the functions. Specifically, I'm looking for inverse, multiplication, and conversion to and from euler angles and 3x3 matrices.
If there is not this kind of support in CLAPACK, is there another library with similar design characteristics that does quaternion math?
This PDF seems to indicate that quaternion support was not planned in LAPACK. I suppose it is safe to assume CLAPACK would be the same.
http://www.netlib.org/lapack/lawnspdf/lawn106.pdf
I still have not found a replacement or supplementary library that does support quaternions.
EDIT:
Found CQRLib, an ANSI C quaternion library. It allocates variables to the stack (a problem on my architecture), so I'll have to refactor that. But otherwise it looks like it should work.
http://cqrlib.sourceforge.net/

Singular Value Decomposition simple code in c

I am looking for Singular Value Decomposition (SVD) code in C, would you please help me?
I found many sources but I cannot run them, I am looking for a version of SVD code that provide all 3 matrix of S, V and U for me.
You can use the Numerical recipies code for that
svdcmp.c reference. Actually in my case I found more accurate the openCV one, but both work fine.
Use one of the libraries listed at the Wiki page: comparison of linear algebra libraries. Look under the "SVD" column to make sure algorithm is supported (even vast majority of the libraries do support SVD).
Don't write it yourself, don't deal with trying to build someone else's source. Use a library that provides this function for you. There's probably already one available on your target platform.
Specifically, use the industry-standard LAPACK library or use the GSL or whatever other linear algebra library you want. They all have an SVD implementation.

Resources