Skip to content

Instantly share code, notes, and snippets.

@bschneidr
Last active May 9, 2025 00:14
Show Gist options
  • Select an option

  • Save bschneidr/95385aab9db3dbda0cbf116e63773775 to your computer and use it in GitHub Desktop.

Select an option

Save bschneidr/95385aab9db3dbda0cbf116e63773775 to your computer and use it in GitHub Desktop.
Eigendecomposition using 'faer' with R (via 'rextendr')
library(rextendr)
rust_source(
code = readLines("r-faer-eigendecomposition.rs"),
dependencies = list("faer" = "0.22.6"),
features = "faer",
profile = "release"
)
X <- matrix(rnorm(n = 25), 5, 5)
eigen_faer(X)
use extendr_api::prelude::*;
use ::faer::{Mat, MatRef, Side};
use ::faer::diag::DiagRef;
use ::faer::{Par, set_global_parallelism};
use core::num::NonZeroUsize;
#[extendr]
fn eigen_faer(x: RMatrix<f64>) -> List {
set_global_parallelism(Par::Rayon(NonZeroUsize::new(12).expect("Value must be nonzero")));
// Convert to a faer matrix
let A: Mat<f64> = Mat::from_fn(x.nrows(), x.ncols(), |row, col| x[[row, col]]);;
// Eigendecomposition
let evd = A.self_adjoint_eigen(Side::Lower).expect("Eigen problem!");
// Extract matrix of eigenvectors and column matrix of eigenvalues
let eigenvectors: &MatRef<f64> = &evd.U();
let eigenvalues: &DiagRef<f64> = &evd.S();
let dimension: usize = eigenvectors.nrows();
// Convert to types that can be passed to R
let eigenvectors: RMatrix<f64> = RMatrix::new_matrix(
dimension, dimension,
|row, col| eigenvectors[(row, col)]
);
let eigenvalues: Vec<f64> = (0..dimension)
.map(|i| eigenvalues[i])
.collect();
// Combine into an R list object
list!(vectors = eigenvectors, values = eigenvalues)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment