Skip to content

Instantly share code, notes, and snippets.

@stephenjbarr
Created August 30, 2012 06:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stephenjbarr/3523265 to your computer and use it in GitHub Desktop.
Save stephenjbarr/3523265 to your computer and use it in GitHub Desktop.
A few demonstrations of Rcpp::InternalFunction
## -*- mode: make; tab-width: 8; -*-
##
## Simple Makefile
##
## From RInside examples
## TODO:
## proper configure for non-Debian file locations, [ Done ]
## allow RHOME to be set for non-default R etc
## comment this out if you need a different version of R,
## and set set R_HOME accordingly as an environment variable
R_HOME := $(shell R RHOME)
sources := $(wildcard *.cpp)
programs := $(sources:.cpp=)
## include headers and libraries for R
RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)
## if you need to set an rpath to R itself, also uncomment
#RRPATH := -Wl,-rpath,$(R_HOME)/lib
## include headers and libraries for Rcpp interface classes
RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave)
## include headers and libraries for RInside embedding classes
RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave)
## compiler etc settings used in default make rules
CXX := $(shell $(R_HOME)/bin/R CMD config CXX)
CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS)
CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)
all: $(programs)
@test -x /usr/bin/strip && strip $^
run: $(programs)
@for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done
clean:
rm -vf $(programs)
rm -vrf *.dSYM
runAll:
for p in $(programs); do echo "Running $$p"; ./$$p; done
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*-
//
// A few more examples of exposing C++ functions to R
//
// Copyright (C) 2012 Stephen Jeffrey Barr
#include <RInside.h> // for the embedded R via RInside
// a c++ function we wish to expose to R
const char* hello( std::string who ){
std::string result( "hello " ) ;
result += who ;
return result.c_str() ;
}
const double doubler( double input ){
return 2.0 * input;
}
const double ary_sum( const Rcpp::NumericVector & input ){
double asum = 0.0;
int len = input.size();
for(int i = 0; i < len; i++) {
asum += input[i];
}
return asum;
}
// NOTE, this assumes that the input vector is length 2
const double my_objective_fn( const Rcpp::NumericVector & input ){
double asum = 0.0;
asum = ((input[0] - 3.0)*(input[0] - 3.0)) +
((input[1] - 5.5)*(input[1] - 5.5));
return asum;
}
int main(int argc, char *argv[]) {
// create an embedded R instance
RInside R(argc, argv);
// expose the "hello" function in the global environment
R["hello"] = Rcpp::InternalFunction( &hello ) ;
R["doubler"] = Rcpp::InternalFunction( &doubler );
R["ary_sum"] = Rcpp::InternalFunction( &ary_sum );
R["my_objective_fn"] = Rcpp::InternalFunction( &my_objective_fn );
// call it and display the result
std::string result = R.parseEval("hello('world')") ;
std::cout << "hello( 'world') = " << result << std::endl ;
// Use the doubler function
double ans = R.parseEval("doubler(3.0)");
std::cout << "doubler(3.0) = " << ans << std::endl ;
// Get the sum of an array in C++
ans = R.parseEval("ary_sum(c(3.0, 4.5, 2.1,1.5))");
std::cout << "ary_sum(c(3.0, 4.5, 2.1,1.5)) = " << ans << std::endl ;
// Evaluate my_objective_fn
ans = 0.0;
ans = R.parseEval("my_objective_fn(c(1.0, 2.0))");
std::cout << "my_objective_fn(c(1.0, 2.0)) = " << ans << std::endl ;
// Optimize my_objective_fn
Rcpp::List x = R.parseEval("optim(c(.2,.8), my_objective_fn)");
Rcpp::NumericVector optimum_point = Rcpp::as<Rcpp::NumericVector>(x[0]);
std::cout << "OPT.0: " << optimum_point(0) << std::endl;
std::cout << "OPT.1: " << optimum_point(1) << std::endl;
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment