--- title: "15 - Using SEXP with Armadillo data types" output: litedown::html_format: options: toc: true number_sections: true vignette: > %\VignetteIndexEntry{15 - Using SEXP with Armadillo data types} %\VignetteEngine{litedown::vignette} %\VignetteEncoding{UTF-8} editor: markdown: wrap: sentence bibliography: ["references.bib"] --- `as_sexp()` allows to pass objects from Armadillo to R while `as_cpp<>` allows to pass objects from R to Armadillo. I prefer to use `as_mat()`, `as_doubles_matrix()`, etc. to be clear about the return types being used and avoid ambiguity (e.g., as in example 5 below). To pass data to Armadillo we use: - `as_Mat(doubles_matrix<>)` -> `Mat` - `as_Mat(integers_matrix<>) / - as_mat()` -> `Mat` - `as_imat(integers_matrix<>)` -> `imat` - `as_umat(integers_matrix<>)` -> `umat` - `as_fmat(doubles_matrix<>)` -> `fmat` - `as_Col(doubles)` -> `Col / vec` - `as_Col(integers) / as_col()` -> `Col` - `as_uvec(integers)` -> `uvec` To pass data back to R we use: - `as_doubles_matrix(mat/fmat)` -> `doubles_matrix<>` - `as_integers_matrix(imat/umat)` -> `integers_matrix<>` - `as_complexes_matrix(cx_mat)` -> `complexes_matrix<>` - `as_doubles(vec)` -> `doubles` - `as_integers(ivec/uvec)` -> `integers` Or we can use the generic conversion `cpp4r::as_sexp()`: - `vec/ivec/uvec/fvec` -> `doubles/integers` - `mat/imat/umat/fmat` -> `doubles_matrix<> / integers_matrix<>` - `rowvec/irowvec/urowvec/frowvec` -> `doubles_matrix<> / integers_matrix<>` Let's use the following function in different ways: ```cpp vec ols_fit(const Mat& X, const Col& Y) { // QR decomposition mat Q, R; qr_econ(Q, R, X); // Least Squares Problem vec betas = solve(trimatu(R), Q.t() * Y); return betas; } ``` There are at least five ways to use this function and return the results to R: ```cpp // Example 1: vec to doubles() [[cpp4r::register]] doubles ols_traditional_(const doubles_matrix<>& x, const doubles& y) { mat X = as_Mat(x); vec Y = as_Col(y); return as_doubles(ols_fit(X, Y)); } // Example 2: vec to doubles using as_sexp() [[cpp4r::register]] doubles ols_simplified_(const doubles_matrix<>& x, const doubles& y) { mat X = as_mat(x); vec Y = as_Col(y); return cpp4r::as_sexp(ols_fit(X, Y)); } // Example 3: mat to doubles_matrix<> using as_sexp() [[cpp4r::register]] doubles_matrix<> ols_simplified2_(const doubles_matrix<>& x, const doubles& y) { mat X = as_mat(x); vec Y = as_Col(y); return cpp4r::as_sexp(ols_fit(X, Y)); } // Example 4: vec to doubles using as_sexp() [[cpp4r::register]] doubles ols_simplified3_(const doubles_matrix<>& x, const doubles& y) { mat X = as_mat(x); vec Y = as_Col(y); return cpp4r::as_sexp(ols_fit(X, Y)); } // Example 4: vec to doubles using as_sexp() [[cpp4r::register]] doubles ols_simplified4_(const doubles_matrix<>& x, const doubles& y) { return cpp4r::as_sexp(ols_fit(as_mat(x), as_col(y))); } // Example 5: vec to doubles using as_sexp() // returns doubles ignoring the doubles_matrix<> output [[cpp4r::register]] doubles_matrix<> ols_simplified5_(const doubles_matrix<>& x, const doubles& y) { return cpp4r::as_sexp(ols_fit(as_mat(x), as_col(y))); } ```