Is there a way to raise a matrix to a power of 0.5 in Rcpp or RcppArmadillo? I don't want the element-wise power because I know that can be done by using pow function.
If you are asking about a function expm(), I am using one by wrapping around the code from the namesake CRAN package expm in my (incomplete) RcppKalman package on GitHub:
#include <RcppArmadillo.h>
/* Interface to expm package. */
typedef enum { Ward_2, Ward_1, Ward_buggy_octave } precond_type;
/* Matrix exponential exp(x), where x is an (n x n) matrix. Result z
* is an (n x n) matrix. Mostly lifted from the core of function
* expm() of package Matrix, which is itself based on the function of
* the same name in Octave. */
void (*expmat)(double *x, int n, double *z, precond_type precond_kind);
extern "C" void R_init_RcppKalman(DllInfo *dll) {
expmat = (void (*) (double*, int,
double*, precond_type)) R_GetCCallable("expm", "expm");
}
//' This function computes the exponential of a matrix.
//'
//' This functions calls the \code{expm} function from the eponymous package
//' \pkg{expm}. This is implemented via a registered function call, and does
//' not required explicit linking at the C level. However, the \pkg{expm} package
//' is imported in order to access its registered function at the C level.
//' [...]
// [[Rcpp::export]]
arma::mat expm(arma::mat x) {
arma::mat z(x.n_rows, x.n_cols);
(*expmat)(x.begin(), x.n_rows, z.begin(), Ward_2);
return z;
}
Some of the strange-looking stuff in the file is just the mechanics of getting expm from that package. The arma::mat expm(arma::mat x) function is pretty regular (and I guess I should make it const & as well).
Edit: Re-reading your question, I think I misunderstood. You were not asking for the matrix exponential. But then .... what exactly is it your are asking for if it is not element-wise?
Related
Here's an illustration of what I am currently doing with two functions.
In both cases I am creating a local copies: either an instance of std::vector<GLfloat> or of std::vector<GLdouble>.
Isn't there a shortcut not involving copies, where I could go from Rcpp::NumericMatrix to GLfloat */GLdouble * in a more direct way?
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
//' #export
// [[Rcpp::export("glLoadMatrixf")]]
void gl_load_matrixf(Rcpp::NumericMatrix m) {
std::vector<GLfloat> float_v = Rcpp::as<std::vector<GLfloat> >(m);
const GLfloat * _float_v = &float_v[0];
glLoadMatrixf(_float_v);
}
//' #export
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
std::vector<GLdouble> double_v = Rcpp::as<std::vector<GLdouble> >(m);
const GLdouble * _double_v = &double_v[0];
glLoadMatrixd(_double_v);
}
On my system GLfloat and GLdouble are defined as:
typedef float GLfloat;
typedef double GLdouble;
And R's numeric data type is always a double. So you can use &m[0] or m.begin() directly to get something convertible to a GLdouble * without the need to copy the data. For GLfloat this is not possible, since it requires a (lossy) cast to go from the (64 bit) double used by R to a (32 bit) float.
Some code as illustration:
Sys.setenv(PKG_LIBS="-lGL -lglfw")
Rcpp::sourceCpp(code = '
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
const GLdouble * _double_v = &m[0];
glLoadMatrixd(_double_v);
}
')
glLoadMatrixd(matrix(runif(10), 2, 5))
BTW, I have no idea what dimensions such a matrix should have. 2x5 is probably incorrect ...
I am writing an R package in which one of the functions takes Rcpp::XPtr as an input (as a SEXP). However, the creation of XPtr from Rcpp::Function is something I want to do inside the package (i.e., the user should be able to input Function).
e.g, my package takes input generated as follows, which requires the user to write an additional function (here putFunPtrInXPtr()) and run the function in R to generate the XPtr (here my_ptr).
#include <Rcpp.h>
using namespace Rcpp;
typedef NumericVector (*funcPtr) (NumericVector y);
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
return x * 2;
}
// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
XPtr<funcPtr> testptr(new funcPtr(×Two), false);
return testptr;
}
/*** R
my_xptr <- putFunPtrInXPtr()
*/
How can I write something in which the user provides Function user_fun and I create the XPtr?
I tried
XPtr<funcPtr> package_fun(Function user_fun_input){
XPtr<funcPtr> testptr(new funcPtr(&user_fun_input), false);
}
user_fun_input is the parameter name inside the package function, but I am getting the following error
cannot initialize a new value of type 'funcPtr' (aka 'Vector<14> (*) (Vector<14>') with an rvalue of type 'Rcpp::Function *' (aka 'Function_Impl<PreserveStorage> *')
Also, there is an R step involved in creating the pointer, I am not sure how to implement that in the package (my .cpp file).
I think the creation of XPtr from Function could be confusing to the user, so better to just take Function as input and create the pointer to it, inside the package. I do use the XPtr in my package to gain speed.
Suggestions are most appreciated!
I am trying to use the Rcpp sample function, but I want to sample without replacement and with unequal probability. However I am struggling to understand what form the argument sugar::probs_t probs should take, because I cannot find the definition.
sugar::probs_t is a typedef of Nullable< Vector<REALSXP> > (see the inst/include/Rcpp/sugar/functions/sample.h code file). So, if you pass it a Rcpp::NumericVector, then everything should be fine.
As you didn't provide any example code, lets look at an implementation in the unit test file for sugar:
// [[Rcpp::export]]
NumericVector sample_dbl(NumericVector x, int sz, bool rep = false, sugar::probs_t p = R_NilValue)
{
return sample(x, sz, rep, p);
}
I'm looking for a way to use a function as an argument to another function in GLSL. In regular C, it can be simulated by passing a function pointer as a function argument. It also seems that other languages (like HLSL) now provide ways to deal with high-level constructs like higher-order functions, or can simulate them with clever use of HLSL structures. unfortunately I'm stuck with GLSL for now, and I can't find any way to simulate higher-order functions. Is it really impossible in current (4.2) GLSL ? Or am I missing some clever trick ?
common example of what I'm trying to achieve :
int f(someType f2, int i) {
return f2(i);
}
I'm looking for a way to use a function as an argument to another function in GLSL.
Short answer: you can't.
The closest thing to this kind of functionality you'll get in GLSL is shader subroutines. And that only allows the external OpenGL API to select which subroutine to use, not the shader itself.
So just do the switch/case statement and get it over with.
There are no higher-order functions in GLSL, but it's possible to simulate them:
#define second_order 1
#define second_order1 2
#define another_function 3
//there are no function pointers in GLSL, so I use integers instead
int call(int f2,int param1){
//instead of a function, an integer is passed as a parameter
switch(f2){
case second_order:
return param1*2;
case second_order1:
return param1*3;
}
}
int call(int f2,int param1,int param2){
//this function can be overloaded to accept more parameters
switch(f2){
case another_function:
return param1 + param2;
}
}
int f(int f2, int i) {
return call(f2,i);
}
Alternatively, this can be done using structs:
struct function{
int x;
};
function Sin(){
return function(1);
}
function Cos(){
return function(2);
}
float call(function func,float x){
if(func == Sin()){
return sin(x);
}
else if(func == Cos()){
return cos(x);
}
}
vec4 map(function func,vec4 a1){
//this function can be overloaded for different array sizes
vec4 a2;
for(int i = 0; i < 4; i++){
a2[i] = call(func,a1[i]);
}
return a2;
}
It's also possible to simulate generic second-order functions using macros:
#define map(function,input1,output1) \
for(int i = 0; i < input1.length(); i++){ \
output1[i] = function(input1[i]); \
}
This macro can be used with any type of array:
float[] arr1 = float[](1.,3.,4.);
float[arr1.length()] output1;
map(sin,arr1,output1)
In my data.h file I have:
typedef struct {
double ***grid;
} Solver;
In my .c file I have
static Solver _solver;
which first makes a call to a function to do some allocation on grid such as
_solver.grid = malloc(....);
//then makes a call to
GS_init(_solver.grid);
The GS_init function is declared in GS.h as:
void GS_init(double ***grid);
When I try to compile, I get two errors:
the struct "<unnamed>" has no field "grid"
GS_init(_solver.grid)
^
and
too many arguments in function call
GS_init(_solver.grid)
^
Any ideas what is going wrong here?
This code compiles with 'gcc -Wall -Werror -c':
data.h
typedef struct
{
double ***grid;
} Solver;
gs.h
extern void GS_init(double ***grid);
gs.c
#include "data.h"
#include "gs.h"
#include <stdlib.h>
static Solver _solver;
void anonymous(void)
{
_solver.grid = malloc(32 * sizeof(double));
GS_init(_solver.grid);
}
Derek asked:
Why does this work? Is it because of the extern keyword?
The 'extern' is not material to making it work, though I always use it.
When I have to flesh out GS_init() in, say compute.c, would I write void GS_init(double ***grid){ //loop over grid[i][j][k] setting to zero }
Sort of...yes, the GS_init() code could do that if the data structure is set up properly, which is going to need more information than there is currently visible in the structure.
For the compiler to process:
grid[i][j][k] = 0.0;
the code has to know the valid ranges for each of i, j, and k; assume the number of rows in each dimension are Ni, Nj, Nk. The data 'structure' pointed to by grid must be an array of Ni 'double **' values - which must be allocated. Each of those entries must point to Nj 'double *' values. So, you have to do more allocation than a single malloc(), and you have to do more initialization than just setting everything to zero.
If you want to use a single array of doubles only, you will have to write a different expression to access the data:
grid[(i * Ni + j) * Nj + k] = 0.0;
And under this scenario, grid would be a simple double * and not a triple pointer.