@@ -67,7 +67,9 @@ footer_contents: "Rcpp Vignette"
67
67
skip_final_break : true
68
68
69
69
# Produce a pinp document
70
- output : pinp::pinp
70
+ output :
71
+ pinp::pinp :
72
+ collapse : true
71
73
72
74
header-includes : >
73
75
\newcommand{\proglang}[1]{\textsf{#1}}
@@ -85,6 +87,13 @@ vignette: >
85
87
86
88
\tableofcontents
87
89
90
+ ``` {r setup, include=FALSE}
91
+ knitr::opts_chunk$set(cache=TRUE)
92
+ library(Rcpp)
93
+ library(inline)
94
+ options("width"=50, digits=5)
95
+ ```
96
+
88
97
# Getting started
89
98
90
99
## How do I get started
@@ -246,7 +255,7 @@ The \pkg{inline} package \citep{CRAN:inline} provides the functions
246
255
function that uses ` accumulate ` from the (\proglang{C++}) Standard
247
256
Template Library to sum the elements of a numeric vector.
248
257
249
- ``` {r, eval = FALSE }
258
+ ``` {r}
250
259
fx <- cxxfunction(signature(x = "numeric"),
251
260
'NumericVector xx(x);
252
261
return wrap(
@@ -259,18 +268,6 @@ res <- fx(seq(1, 10, by=0.5))
259
268
res
260
269
```
261
270
262
- ``` {r, eval = FALSE, echo=FALSE}
263
- stopifnot(identical(res, sum(seq(1, 10, by=0.5))))
264
- ```
265
-
266
- <!--
267
- \pkg{Rcpp} uses \pkg{inline} to power its entire unit test suite. Consult the
268
- `unitTests` directory of \pkg{Rcpp} for several hundred further examples.
269
- ```{r, eval = FALSE}
270
- list.files( system.file( "unitTests", package = "Rcpp" ), pattern = "^runit[.]" )
271
- ```
272
- -->
273
-
274
271
One might want to use code that lives in a \proglang{C++} file instead of writing
275
272
the code in a character string in R. This is easily achieved by using
276
273
\rdoc{base}{readLines}:
@@ -289,16 +286,17 @@ useful as it shows how \pkg{inline} runs the show.
289
286
290
287
Rcpp Attributes \citep{CRAN:Rcpp: Attributes }, and also discussed in
291
288
\faq{prototype-using-attributes} below, permits an even easier
292
- route to integrating R and C++. It provides three key functions. First, \rdoc{Rcpp}{evalCpp}
293
- provide a means to evaluate simple C++ expression which is often useful for
294
- small tests, or to simply check if the toolchain is set up
295
- correctly. Second, \rdoc{Rcpp}{cppFunction} can be used to create C++ functions
296
- for R use on the fly. Third, ` Rcpp::sourceCpp ` can integrate entire files in
297
- order to define multiple functions.
289
+ route to integrating R and C++. It provides three key functions.
290
+ First, \rdoc{Rcpp}{evalCpp} provide a means to evaluate simple C++
291
+ expression which is often useful for small tests, or to simply check
292
+ if the toolchain is set up correctly. Second, \rdoc{Rcpp}{cppFunction}
293
+ can be used to create C++ functions for R use on the fly. Third,
294
+ ` Rcpp::sourceCpp ` can integrate entire files in order to define
295
+ multiple functions.
298
296
299
297
The example above can now be rewritten as:
300
298
301
- ``` {r, eval = FALSE }
299
+ ``` {r}
302
300
cppFunction('double accu(NumericVector x) {
303
301
return(
304
302
std::accumulate(x.begin(), x.end(), 0.0)
@@ -647,7 +645,7 @@ what we show below.
647
645
Most certainly, consider this simple example of a templated class
648
646
which squares its argument:
649
647
650
- ``` {r, eval = FALSE }
648
+ ``` {r}
651
649
inc <- 'template <typename T>
652
650
class square :
653
651
public std::unary_function<T,T> {
@@ -821,7 +819,7 @@ two calls result in the same random draws. If we wanted to control the draws,
821
819
we could explicitly set the seed after the `RNGScope` object has been
822
820
instantiated.
823
821
824
- ```{r, eval = FALSE }
822
+ ```{r}
825
823
fx <- cxxfunction(signature(),
826
824
'RNGScope();
827
825
return rnorm(5, 0, 100);',
@@ -837,7 +835,7 @@ random variable distributed as $N(m,s)$.
837
835
838
836
Using Rcpp Attributes, this can be as simple as
839
837
840
- ``` {r, eval = FALSE }
838
+ ``` {r}
841
839
cppFunction('Rcpp::NumericVector ff(int n) {
842
840
return rnorm(n, 0, 100); }')
843
841
set.seed(42)
@@ -858,7 +856,7 @@ as well as R, and that identical random number draws are obtained.
858
856
859
857
\noindent Yes, see the following example:
860
858
861
- ``` {r, eval = FALSE }
859
+ ``` {r}
862
860
src <- 'Rcpp::NumericVector v(4);
863
861
v[0] = R_NegInf; // -Inf
864
862
v[1] = NA_REAL; // NA
@@ -892,7 +890,7 @@ Rcpp::NumericVector fun(void) {
892
890
\noindent Yes, via the \pkg{RcppArmadillo} package which builds upon \pkg{Rcpp} and the
893
891
wonderful Armadillo library described above in \faq{matrix-algebra}:
894
892
895
- ```{r, eval = FALSE }
893
+ ```{r}
896
894
txt <- 'arma::mat Am = Rcpp::as< arma::mat >(A);
897
895
arma::mat Bm = Rcpp::as< arma::mat >(B);
898
896
return Rcpp::wrap( Am * Bm );'
@@ -903,16 +901,9 @@ mmult <- cxxfunction(signature(A="numeric",
903
901
A <- matrix(1:9, 3, 3)
904
902
B <- matrix(9:1, 3, 3)
905
903
C <- mmult(A, B)
904
+ C
906
905
```
907
906
908
- <!--
909
- ```{r eval=FALSE}
910
- A <- matrix(1:9, 3, 3)
911
- B <- matrix(9:1, 3, 3)
912
- A %*% B
913
- ```
914
- -->
915
-
916
907
Armadillo supports a full range of common linear algebra operations.
917
908
918
909
The \pkg{RcppEigen} package provides an alternative using the
@@ -1334,7 +1325,7 @@ As a result, the \pkg{Rcpp} object is ``linked'' to the original \proglang{R} ob
1334
1325
Thus, if an operation is performed on the \pkg{Rcpp} object, such as adding 1
1335
1326
to each element, the operation also updates the \proglang{R} object causing the change to be propagated to \proglang{R}'s interactive environment.
1336
1327
1337
- ```cpp
1328
+ ```{Rcpp}
1338
1329
#include<Rcpp.h>
1339
1330
1340
1331
// [[Rcpp::export]]
@@ -1348,9 +1339,9 @@ void explicit_ref(Rcpp::NumericVector& X) {
1348
1339
}
1349
1340
```
1350
1341
1351
- R use:
1342
+ R use
1352
1343
1353
- ``` {r, eval = FALSE }
1344
+ ``` {r}
1354
1345
a <- 1.5:4.5
1355
1346
b <- 1.5:4.5
1356
1347
implicit_ref(a)
@@ -1374,7 +1365,7 @@ and, thus, there would _not_ be a link between the \pkg{Rcpp} object
1374
1365
and \proglang{R} object. So, any changes in \proglang{C++} would not be propagated to
1375
1366
\proglang{R} unless otherwise specified.
1376
1367
1377
- ``` cpp
1368
+ ``` {Rcpp}
1378
1369
#include<Rcpp.h>
1379
1370
1380
1371
// [[Rcpp::export]]
@@ -1390,14 +1381,14 @@ void num_vec_type(Rcpp::NumericVector X) {
1390
1381
1391
1382
R use:
1392
1383
1393
- ```{r, eval=FALSE }
1384
+ ``` {r}
1394
1385
a <- 1:5
1395
1386
b <- 1:5
1396
1387
class(a)
1397
1388
int_vec_type(a)
1398
- a
1389
+ a # variable a changed as a side effect
1399
1390
num_vec_type(b)
1400
- b
1391
+ b # b unchanged as copy was made for numeric
1401
1392
```
1402
1393
1403
1394
With this being said, there is one last area of contention with the proxy model:
@@ -1410,36 +1401,43 @@ would be allowed to be modified by the compiler and, thus, modifying the initial
1410
1401
` SEXP ` object. Therefore, the initially secure \proglang{R} object would be altered.
1411
1402
To illustrate this phenomenon, consider the following scenario:
1412
1403
1413
- ``` cpp
1404
+ ``` {Rcpp}
1414
1405
#include <Rcpp.h>
1415
1406
1416
1407
// [[Rcpp::export]]
1417
- Rcpp::NumericVector const_override_ex (
1418
- const Rcpp::NumericVector & X) {
1408
+ Rcpp::IntegerVector const_override_ex(
1409
+ const Rcpp::IntegerVector & X) {
1419
1410
1420
- Rcpp::NumericVector Y(X); // Create object
1411
+ Rcpp::IntegerVector Y(X); // Create object
1421
1412
// from SEXP
1422
1413
1423
1414
Y = Y * 2; // Modify new object
1424
1415
1425
- return X ; // Return old object
1416
+ return Y ; // Return new object
1426
1417
}
1427
1418
```
1428
1419
1429
1420
R use:
1430
1421
1431
- ```{r, eval=FALSE}
1432
- x <- 1:10
1422
+ ``` {r}
1423
+ x <- 1:10 # an integer sequence
1424
+ # returning an altered value
1433
1425
const_override_ex(x)
1426
+ # but the original value is altered too!
1434
1427
x
1435
1428
```
1436
1429
1430
+ So we see that with ` SEXP ` objects, the ` const ` declaration can be
1431
+ circumvented as it is really a pointer to the underlying R object.
1432
+
1433
+
1437
1434
## Issues with implicit conversion from an \pkg{Rcpp} object to a scalar or other \pkg{Rcpp} object
1438
1435
1439
- Not all \pkg{Rcpp} expressions are directly compatible with ` operator= ` .
1440
- Compability issues stem from many \pkg{Rcpp} objects and functions returning an
1441
- intermediary result which requires an explicit conversion. In such cases, the
1442
- user may need to assist the compiler with the conversion.
1436
+ Not all \pkg{Rcpp} expressions are directly compatible with
1437
+ ` operator= ` . Compability issues stem from many \pkg{Rcpp} objects and
1438
+ functions returning an intermediary result which requires an explicit
1439
+ conversion. In such cases, the user may need to assist the compiler
1440
+ with the conversion.
1443
1441
1444
1442
There are two ways to assist with the conversion. The first is to construct
1445
1443
storage variable for a result, calculate the result, and then store a value
@@ -1495,7 +1493,7 @@ is cast into the appropriate \pkg{Rcpp} object type. Therefore, if a
1495
1493
via ` operator= ` , then the resulting ` Vector ` would have a length of
1496
1494
1 . See the following code snippet for the aforementioned behavior.
1497
1495
1498
- ``` cpp
1496
+ ``` {Rcpp}
1499
1497
#include<Rcpp.h>
1500
1498
1501
1499
// [[Rcpp::export]]
@@ -1515,7 +1513,7 @@ void vec_scalar_assign(int n, double fill_val) {
1515
1513
1516
1514
R use:
1517
1515
1518
- ```{r, eval=FALSE }
1516
+ ``` {r}
1519
1517
vec_scalar_assign(5L, 3.14)
1520
1518
```
1521
1519
@@ -1526,7 +1524,7 @@ results while attempting to use the assignment operator with a scalar. In
1526
1524
particular, the scalar will be coerced into a square ` Matrix ` and then
1527
1525
assigned. For an example of this behavior, consider the following code:
1528
1526
1529
- ``` cpp
1527
+ ``` {Rcpp}
1530
1528
#include<Rcpp.h>
1531
1529
1532
1530
// [[Rcpp::export]]
@@ -1546,7 +1544,7 @@ void mat_scalar_assign(int n, double fill_val) {
1546
1544
1547
1545
R use:
1548
1546
1549
- ```{r, eval=FALSE }
1547
+ ``` {r}
1550
1548
mat_scalar_assign(2L, 3.0)
1551
1549
```
1552
1550
@@ -1574,7 +1572,7 @@ by \pkg{Rcpp} attributes. This is engaged by adding
1574
1572
For diagnostic and illustrativative purposes, consider the following code
1575
1573
which checks to see if ` R_xlen_t ` is available on your platform:
1576
1574
1577
- ``` cpp
1575
+ ``` {Rcpp}
1578
1576
#include <Rcpp.h>
1579
1577
// Force compilation mode to C++11
1580
1578
// [[Rcpp::plugins(cpp11)]]
@@ -1591,7 +1589,7 @@ bool test_long_vector_support() {
1591
1589
1592
1590
R use:
1593
1591
1594
- ``` {r, eval = FALSE }
1592
+ ``` {r}
1595
1593
test_long_vector_support()
1596
1594
```
1597
1595
@@ -1627,7 +1625,7 @@ type. Though, sorting is slightly problematic due to locale as explained in the
1627
1625
next entry. In the interim, the following code example illustrates the preferred
1628
1626
approach alongside the problematic STL approach:
1629
1627
1630
- ``` cpp
1628
+ ``` {Rcpp}
1631
1629
#include <Rcpp.h>
1632
1630
1633
1631
// [[Rcpp::export]]
@@ -1653,7 +1651,7 @@ Rcpp::CharacterVector stl_sort(
1653
1651
1654
1652
R use:
1655
1653
1656
- ```{r, eval=FALSE }
1654
+ ``` {r}
1657
1655
set.seed(123)
1658
1656
(X <- sample(c(LETTERS[1:5], letters[1:6]), 11))
1659
1657
preferred_sort(X)
@@ -1680,7 +1678,7 @@ capitalized words are sorted together followed by the sorting of lowercase
1680
1678
words instead of a mixture of capitalized and lowercase words. The issue is
1681
1679
illustrated by the following code example:
1682
1680
1683
- ``` cpp
1681
+ ``` {Rcpp}
1684
1682
#include <Rcpp.h>
1685
1683
1686
1684
// [[Rcpp::export]]
@@ -1693,7 +1691,7 @@ Rcpp::CharacterVector rcpp_sort(
1693
1691
1694
1692
R use:
1695
1693
1696
- ```{r, eval=FALSE }
1694
+ ``` {r}
1697
1695
x <- c("B", "b", "c", "A", "a")
1698
1696
sort(x)
1699
1697
rcpp_sort(x)
0 commit comments