Skip to content

Commit 96f36a1

Browse files
authored
Merge pull request #509 from coatless/doc_updates
Rcpp-quickref Vignette Updates (Closes #484)
2 parents fd509c6 + f62d4a7 commit 96f36a1

File tree

3 files changed

+202
-88
lines changed

3 files changed

+202
-88
lines changed

ChangeLog

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2016-07-17 James J Balamuta <[email protected]>
2+
3+
* vignettes/Rcpp-quickref.Rnw: Added sections on Rcpp attributes and
4+
plugins. Facelifts on important notes, inline, environments, and
5+
calling R functions.
6+
17
2016-07-15 James J Balamuta <[email protected]>
28

39
* vignettes/Rcpp-FAQ.Rnw: Added section on default function parameters

inst/NEWS.Rd

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
}
4242
\item Changes in Rcpp Documentation:
4343
\itemize{
44+
\item The Rcpp Quick Reference vignette received a facelift with
45+
new sections on Rcpp attributes and plugins begin added.
46+
Furthermore, content was improved in the following
47+
sections: important notes, inline compiling, environments,
48+
and calling R functions.
49+
(James Balamuta in \ghpr{509} fixing \ghit{484}).
4450
\item A section on default parameters was added to the Rcpp FAQ vignette
4551
(James Balamuta in \ghpr{505} fixing \ghit{418}).
4652
\item The Rcpp-attributes vignette is now mentioned more prominently in

vignettes/Rcpp-quickref.Rnw

+190-88
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ prettyDate <- format(Sys.Date(), "%B %e, %Y")
6464
// If you experience compiler errors, please check that you have an appropriate version of g++. See `Rcpp-FAQ' for more information.
6565
6666
// Many of the examples here imply the following:
67+
#include <Rcpp.h>
6768
using namespace Rcpp;
68-
// The inline package adds this for you. Alternately, use e.g.:
69+
// The cppFunction will automatically add this.
70+
71+
// Or, prefix Rcpp objects with the Rcpp namespace e.g.:
6972
Rcpp::NumericVector xx(10);
7073
@
7174
@@ -90,7 +93,7 @@ NumericVector xx = NumericVector::create(
9093
1.0, 2.0, 3.0, 4.0 );
9194
NumericVector yy = NumericVector::create(
9295
Named["foo"] = 1.0,
93-
_["bar"] = 2.0 ); // short for Named
96+
_["bar"] = 2.0 ); // _ short for Named
9497
@
9598
9699
\paragraph{Extract and set single elements}~
@@ -147,20 +150,23 @@ NumericVector zz1 = xx( _, 1);
147150
NumericMatrix zz2 = xx( Range(0,2), Range(0,2));
148151
@
149152
150-
\paragraph{Inline}~
153+
\paragraph{Inline C++ Compile in R}~
151154
\newline
152155
<<lang=cpp>>=
153-
## Note - this is R code. inline allows rapid testing.
154-
require(inline)
155-
testfun = cxxfunction(
156-
signature(x="numeric", i="integer"),
157-
body = '
158-
NumericVector xx(x);
159-
int ii = as<int>(i);
160-
xx = xx * ii;
161-
return( xx );
162-
', plugin="Rcpp")
163-
testfun(1:5, 3)
156+
## Note - this is R code.
157+
## cppFunction in Rcpp allows rapid testing.
158+
require(Rcpp)
159+
160+
cppFunction("
161+
NumericVector exfun(NumericVector x, int i){
162+
x = x*i;
163+
return x;
164+
}")
165+
166+
exfun(1:5, 3)
167+
168+
## Use evalCpp to evaluate C++ expressions
169+
evalCpp("std::numeric_limits<double>::max()")
164170
@
165171
166172
\paragraph{Interface with R}~
@@ -222,95 +228,74 @@ double s2 = std::inner_product(res.begin(),
222228
res.end(), res.begin(), 0.0);
223229
@
224230

225-
\paragraph{Function}~
231+
\paragraph{Rcpp Attributes}~
226232
\newline
227233
<<lang=cpp>>=
228-
Function rnorm("rnorm");
229-
rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 );
230-
@
234+
// Add code below into C++ file Rcpp_example.cpp
231235
232-
\paragraph{Environment}~
233-
\newline
234-
<<lang=cpp>>=
235-
Environment stats("package:stats");
236-
Environment env( 2 ); // by position
236+
#include <Rcpp.h>
237+
using namespace Rcpp;
237238
238-
// special environments
239-
Environment::Rcpp_namespace();
240-
Environment::base_env();
241-
Environment::base_namespace();
242-
Environment::global_env();
243-
Environment::empty_env();
239+
// Place the export tag right above function declaration.
240+
241+
// [[Rcpp::export]]
242+
double muRcpp(NumericVector x){
243+
int n = x.size(); // Size of vector
244+
double sum = 0; // Sum value
245+
246+
// For loop, note cpp index shift to 0
247+
for(int i = 0; i < n; i++){
248+
// Shorthand for sum = sum + x[i]
249+
sum += x[i];
250+
}
251+
252+
return sum/n; // Obtain and return the Mean
253+
}
244254
245-
Function rnorm = stats["rnorm"];
246-
glob["x"] = "foo";
247-
glob["y"] = 3;
248-
std::string x = glob["x"];
255+
// Place dependent functions above call or
256+
// declare the function definition with:
257+
double muRcpp(NumericVector x);
258+
259+
// [[Rcpp::export]]
260+
double varRcpp(NumericVector x, bool bias = true){
261+
// Calculate the mean using C++ function
262+
double mean = muRcpp(x);
263+
double sum = 0;
264+
int n = x.size();
265+
266+
for(int i = 0; i < n; i++){
267+
sum += pow(x[i] - mean, 2.0); // Square
268+
}
269+
270+
return sum/(n-bias); // Return variance
271+
}
249272
250-
glob.assign( "foo" , 3 );
251-
int foo = glob.get( "foo" );
252-
int foo = glob.find( "foo" );
253-
CharacterVector names = glob.ls()
254-
bool b = glob.exists( "foo" );
255-
glob.remove( "foo" );
273+
## In R:
274+
require(Rcpp)
275+
sourceCpp("path/to/file/Rcpp_example.cpp")
276+
x = 1:5;
277+
all.equal(muRcpp(x), mean(x)); all.equal(var(x),varRcpp(x))
278+
## TRUE
279+
@
256280

257-
glob.lockBinding("foo");
258-
glob.unlockBinding("foo");
259-
bool b = glob.bindingIsLocked("foo");
260-
bool b = glob.bindingIsActive("foo");
261281

262-
Environment e = stats.parent();
263-
Environment e = glob.new_child();
264-
@
265282

266-
\paragraph{Modules}~
283+
\paragraph{Rcpp Extensions}~
267284
\newline
268285
<<lang=cpp>>=
269-
// Warning -- At present, module-based objects do not persist across quit(save="yes")/reload cycles. To be safe, save results to R objects and remove module objects before exiting R.
286+
// Enable C++11
287+
// [[Rcpp::plugins(cpp11)]]
270288
271-
// To create a module-containing package from R, use:
272-
Rcpp.package.skeleton("mypackage",module=TRUE)
273-
// You will need to edit the RcppModules: line of the DESCRIPTION file to match your module name (in this example, from yada to mod_bar).
289+
// Enable OpenMP (excludes macOS)
290+
// [[Rcpp::plugins(openmp)]]
274291
275-
class Bar {
276-
public:
277-
Bar(double x_) :
278-
x(x_), nread(0), nwrite(0) {}
279-
280-
double get_x( ) {
281-
nread++; return x;
282-
}
283-
284-
void set_x( double x_) {
285-
nwrite++; x = x_;
286-
}
287-
288-
IntegerVector stats() const {
289-
return IntegerVector::create(
290-
_["read"] = nread,
291-
_["write"] = nwrite);
292-
}
293-
private:
294-
double x; int nread, nwrite;
295-
};
296-
297-
RCPP_MODULE(mod_bar) {
298-
class_<Bar>( "Bar" )
299-
.constructor<double>()
300-
.property( "x", &Bar::get_x, &Bar::set_x,
301-
"Docstring for x" )
302-
.method( "stats", &Bar::stats,
303-
"Docstring for stats")
304-
;}
305-
306-
## The following is R code.
307-
require(mypackage); show(Bar)
308-
b <- new(Bar, 10); b$x <- 10
309-
b_persist <- list(stats=b$stats(), x=b$x)
310-
rm(b)
292+
// Use the RcppArmadillo package
293+
// Requires different header file from Rcpp.h
294+
#include <RcppArmadillo.h>
295+
// [[Rcpp::depends(RcppArmadillo)]]
311296
@
312297

313-
\newpage
298+
314299

315300
\paragraph{Rcpp sugar}~
316301
\newline
@@ -386,4 +371,121 @@ double zz = Rf_rnorm(0, 2);
386371
387372
388373
374+
\newpage
375+
376+
\paragraph{Environment}~
377+
\newline
378+
<<lang=cpp>>=
379+
// Obtain an R environment
380+
Environment stats("package:stats");
381+
Environment env( 2 ); // by position
382+
383+
// Special environments
384+
Environment::Rcpp_namespace();
385+
Environment::base_env();
386+
Environment::base_namespace();
387+
Environment::global_env();
388+
Environment::empty_env();
389+
390+
// Extract function from specific
391+
// environment
392+
Function rnorm = stats["rnorm"];
393+
394+
// Assign into the environment
395+
glob["x"] = "foo";
396+
glob["y"] = 3;
397+
398+
// Retrieve information from environment
399+
std::string x = glob["x"];
400+
glob.assign( "foo" , 3 );
401+
int foo = glob.get( "foo" );
402+
int foo = glob.find( "foo" );
403+
CharacterVector names = glob.ls()
404+
bool b = glob.exists( "foo" );
405+
glob.remove( "foo" );
406+
407+
// Administration
408+
glob.lockBinding("foo");
409+
glob.unlockBinding("foo");
410+
bool b = glob.bindingIsLocked("foo");
411+
bool b = glob.bindingIsActive("foo");
412+
413+
// Retrieve related environments
414+
Environment e = stats.parent();
415+
Environment e = glob.new_child();
416+
@
417+
418+
\paragraph{Calling Functions in R}~
419+
\newline
420+
<<lang=cpp>>=
421+
// Do NOT expect to have a performance gain
422+
// when calling R functions from R!
423+
424+
// Retrieve functions from default loaded environment
425+
Function rnorm("rnorm");
426+
rnorm(100, _["mean"] = 10.2, _["sd"] = 3.2 );
427+
428+
// Passing in an R function and obtaining results
429+
// Make sure the function conforms with return type!
430+
NumericVector callFunction(NumericVector x,
431+
Function f) {
432+
NumericVector res = f(x);
433+
return res;
434+
}
435+
436+
## In R:
437+
x = 1:5
438+
callFunction(x, sum)
439+
@
440+
441+
\newpage
442+
443+
\paragraph{Modules}~
444+
\newline
445+
<<lang=cpp>>=
446+
// Warning -- At present, module-based objects do not persist across quit(save="yes")/reload cycles. To be safe, save results to R objects and remove module objects before exiting R.
447+
448+
// To create a module-containing package from R, use:
449+
Rcpp.package.skeleton("mypackage",module=TRUE)
450+
// You will need to edit the RcppModules: line of the DESCRIPTION file to match your module name (in this example, from yada to mod_bar).
451+
452+
class Bar {
453+
public:
454+
Bar(double x_) :
455+
x(x_), nread(0), nwrite(0) {}
456+
457+
double get_x( ) {
458+
nread++; return x;
459+
}
460+
461+
void set_x( double x_) {
462+
nwrite++; x = x_;
463+
}
464+
465+
IntegerVector stats() const {
466+
return IntegerVector::create(
467+
_["read"] = nread,
468+
_["write"] = nwrite);
469+
}
470+
private:
471+
double x; int nread, nwrite;
472+
};
473+
474+
RCPP_MODULE(mod_bar) {
475+
class_<Bar>( "Bar" )
476+
.constructor<double>()
477+
.property( "x", &Bar::get_x, &Bar::set_x,
478+
"Docstring for x" )
479+
.method( "stats", &Bar::stats,
480+
"Docstring for stats")
481+
;}
482+
483+
## The following is R code.
484+
require(mypackage); show(Bar)
485+
b <- new(Bar, 10); b$x <- 10
486+
b_persist <- list(stats=b$stats(), x=b$x)
487+
rm(b)
488+
@
489+
490+
389491
\end{document}

0 commit comments

Comments
 (0)