# 01 - Basic ‘armadillo4r’ usage

# 1 Ordinary Least Squares

The Ordinary Least Squares (OLS) estimator is \(\hat{\beta} = (X^tX)^{-1}(X^tY)\) for a design matrix \(X\) and an outcome vector \(Y\) Hansen 2022.

The following code shows how to compute the OLS estimator using Armadillo and sending data from R to C++ and viceversa using `cpp4r` and `armadillo4r` SandersonCurtin 2016:

    #include <cpp4r.hpp>
    #include <armadillo4r.hpp>

    using namespace arma;
    using namespace cpp4r;

    [[cpp4r::register]] doubles_matrix<> ols_mat_(const doubles_matrix<>& x) {
      // Convert from R to C++
      Mat<double> Y = as_Mat(y);  // Col<double> Y = as_Col(y); also works
      Mat<double> X = as_Mat(x);

      // Armadillo operations
      Mat<double> XtX = X.t() * X;             // X'X
      Mat<double> XtX_inv = inv(XtX);          // (X'X)^(-1)
      Mat<double> beta = XtX_inv * X.t() * Y;  // (X'X)^(-1)(X'Y)

      // Convert from C++ to R
      return as_doubles_matrix(beta);
    }

The previous code includes the `cpp4r` and `armadillo4r` libraries (armadillo4r calls Armadillo) to allow interfacing C++ with R. It also loads the corresponding namespaces in order to simplify the notation (i.e., using `Mat` instead of `arma::Mat`), and the function `as_Mat()` and `as_doubles_mat()` are provided by `armadillo4r` to pass a `matrix` object from R to C++ and that Armadillo can read and then pass it back to R.

The use of `const` and `&` are specific to the C++ language and allow to pass data from R to C++ without copying the data, and therefore saving time and memory.

`armadillo4r` provides flexibility and in the case of the resulting vector of OLS coefficients, it can be returned as a matrix or a vector. The following code shows how to create three functions to compute the OLS estimator and return the result as a matrix or a vector avoiding repeated code:

    Mat<double> ols_(const doubles_matrix<>& y, const doubles_matrix<>& x) {
      Mat<double> Y = as_Mat(y);  // Col<double> Y = as_Col(y); also works
      Mat<double> X = as_Mat(x);

      Mat<double> XtX = X.t() * X;             // X'X
      Mat<double> XtX_inv = inv(XtX);          // (X'X)^(-1)
      Mat<double> beta = XtX_inv * X.t() * Y;  // (X'X)^(-1)(X'Y)

      return beta;
    }

    [[cpp4r::register]] doubles_matrix<> ols_mat_(const doubles_matrix<>& y,
                                                  const doubles_matrix<>& x) {
      Mat<double> beta = ols_(y, x);
      return as_doubles_matrix(beta);
    }

    [[cpp4r::register]] doubles ols_dbl_(const doubles_matrix<>& y,
                                         const doubles_matrix<>& x) {
      Mat<double> beta = ols_(y, x);
      return as_doubles(beta);
    }

In the previous code, the `ols_mat_()` function receives inputs from R and calls `ols_()` to do the computation on C++ side, and `ols_dbl_()` does the same but it returns a vector instead of a matrix.

# 2 Additional Examples

The package repository includes the directory `armadillo4rtest`, which contains an R package that uses Armadillo, and that provides additional examples for eigenvalues, Cholesky and QR decomposition, and linear models.

# 3 References

Hansen B (2022). Econometrics. Princeton University Press.

Sanderson C, Curtin R (2016). “Armadillo: a template-based C++ library for linear algebra.” Journal of Open Source Software, 1(2), 26. doi:10.21105/joss.00026. https://doi.org/10.21105/joss.00026.