---
title: "07 - Statistical Functions"
output:
  litedown::html_format:
    options:
      toc: true
      number_sections: true
vignette: >
  %\VignetteIndexEntry{07 - Statistical Functions}
  %\VignetteEngine{litedown::vignette}
  %\VignetteEncoding{UTF-8}
editor:
  markdown:
    wrap: sentence
bibliography: ["references.bib"]
---

## Notes

* These functions ignore `NA` values for now. Adjustments for handling `NA` values are covered in a separate vignette.
* R already provides efficient versions of the functions covered here. This is just to illustrate how to use C++ code.
* The explanations and equations used for the functions are taken from @diez15 and @hansen22. Some examples were adapted
  from @vaughan24.

## Sum

For a vector of $n$ elements $x_1, x_2, \ldots, x_n$, the sum is calculated as:

$$
\sum_{i=1}^{n} x_i = x_1 + x_2 + \ldots + x_n
$$

The following C++ function calculates the sum of a vector's elements:

```cpp
[[cpp4r::register]]
double sum_cpp(doubles x) {
  int n = x.size();
  double total = 0;
  for(int i = 0; i < n; ++i) {
    total += x[i];
  }
  return total;
}
```

Its R equivalent is:

```r
sum_r <- function(x) {
  total <- 0
  for (i in seq_along(x)) {
    total <- total + x[i]
  }
  total
}
```

Benchmark the functions as in the "Logical Functions" and "Rolling Functions" vignettes.

## Arithmetic mean

The arithmetic mean of a vector of $n$ elements $x_1, x_2, \ldots, x_n$ is calculated as:

$$
\bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i
$$

The following C++ function calculates the mean of a vector's elements:

```cpp
[[cpp4r::register]]
double mean_cpp(doubles x) {
  int n = x.size();
  double y = 0;

  for(int i = 0; i < n; ++i) {
    y += x[i];
  }
  return y / n;
}
```

Its R equivalent would be:

```r
mean_r <- function(x) {
  sum_r(x) / length(x)
}
```

Benchmark the functions as in the "Logical Functions" and "Rolling Functions" vignettes.

## Variance

The variance of a vector of $n$ elements $x_1, x_2, \ldots, x_n$ is calculated as:

$$
\text{Var}(x) = \frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x})^2
$$

The following C++ function calculates the variance of a vector's elements:

```cpp
[[cpp4r::register]]
double var_cpp(doubles x) {
  int n = x.size();
  double y1 = 0, y2 = 0;

  for(int i = 0; i < n; ++i) {
    y1 += x[i];
    y2 += pow(x[i], 2.0);
  }
  return (y2 - pow(y1, 2.0) / n) / (n - 1);
}
```

Its R equivalent would be:

```r
var_r <- function(x) {
  mean_r((x - mean_r(x))^2)
}
```

Benchmark the functions as in the "Logical Functions" and "Rolling Functions" vignettes.

## Root Mean Square Error (RMSE)

The RMSE function measures the differences between observed values and the true value.

For a vector of $n$ elements $x_1, x_2, \ldots, x_n$ and a value $x_0$, the RMSE is calculated as:

$$
\text{RMSE}(x, x_0) = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (x_i - x_0)^2}
$$

The following C++ function calculates the difference of a vector's elements to a value and returns the square root of the mean of the squared differences:

```cpp
[[cpp4r::register]]
double rmse_cpp(doubles x, double x0) {
  int n = x.size();
  double y = 0;
  for (int i = 0; i < n; ++i) {
    y += pow(x[i] - x0, 2.0);
  }
  return sqrt(y / n);
}
```

Its R equivalent would be:

```r
#' Return the root mean square error (R)
#' @param x numeric vector
#' @param x0 numeric value
#' @export
rmse_r <- function(x, x0) {
  sqrt(sum((x - x0)^2) / length(x))
}
```

Benchmark the functions as in the "Logical Functions" and "Rolling Functions" vignettes.

## References
