Created
August 30, 2012 06:25
-
-
Save stephenjbarr/3523265 to your computer and use it in GitHub Desktop.
A few demonstrations of Rcpp::InternalFunction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## -*- 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -*- 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