Packages

library(Rcpp)
library(tidyverse)
library(bench)

Exercise 1

Problem

Write a C++ function that computes the sum of the squared deviations about a specific value. An R function to do this can be defined as follows.

ssd <- function(x, x0) {
  sum((x - x0) ^ 2)
}

Assume x is a vector and x0 is a “scalar”. Compare the performance between ssd() and your C++ function.


Hint: pow() in C++ is used for exponentiation.

Solution

cppFunction(
  'double ssd_c(NumericVector x, double x0) {
    int n = x.size();
    double result = 0;
    for (int i = 0; i < n; ++i) {
      result += pow(x[i] - x0, 2);
    }
    return result;
  }'
)
x <- rnorm(100)
ssd(x, x0 = 0)
ssd_c(x, x0 = 0)
x <- rnorm(n = 1e6)
bench::mark(
  ssd(x, 0),
  ssd_c(x, 0),
  relative = TRUE
)[, 1:6]

Exercise 2

Problem

Convert the R diff() function into C++. Only consider a numeric vector as an input and the lag argument. Write this function in a .cpp file and source it into R.

Some examples of R’s diff() function:

set.seed(24581)
(x <- sample(1:10))
#>  [1]  7  4  9 10  1  2  8  5  3  6
diff(x, lag = 1)
#> [1] -3  5  1 -9  1  6 -3 -2  3
diff(x, lag = 3)
#> [1]  3 -3 -7 -2  4  1 -2
diff(x, lag = 4)
#> [1] -6 -2 -1 -5  2  4

Solution

# include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector diff_c(NumericVector x, int lag) {
  int n = x.size() - lag;
  NumericVector result(n);
  for (int i = 0; i < n; ++i) {
    result[i] = x[i + lag] - x[i];
  }
  return result;
}
sourceCpp("diff_c.cpp")