Module extendr_api::optional::ndarray

source ·
Expand description

Defines conversions between R objects and the ndarray crate, which offers native Rust array types and numerical computation routines.

To enable these conversions, you must first enable the ndarray feature for extendr:

[dependencies]
extendr-api = { version = "0.4", features = ["ndarray"] }

Specifically, extendr supports the following conversions:

  • RobjArrayView1, for when you have an R vector that you want to analyse in Rust:
    use extendr_api::prelude::*;
    
    #[extendr]
    fn describe_vector(vector: ArrayView1<f64>){
        println!("This R vector has length {:?}", vector.len())
    }
  • RobjArrayView2, for when you have an R matrix that you want to analyse in Rust.
    use extendr_api::prelude::*;
    
    #[extendr]
    fn describe_matrix(matrix: ArrayView2<f64>){
        println!("This R matrix has shape {:?}", matrix.dim())
    }
  • ArrayBaseRobj, for when you want to return a reference to an ndarray Array from Rust back to R.
    use extendr_api::prelude::*;
    
    #[extendr]
    fn return_matrix() -> Robj {
        Array2::<f64>::zeros((4, 4)).try_into().unwrap()
    }

The item type (ie the T in Array2<T>) can be a variety of Rust types that can represent scalars: u32, i32, f64 and, if you have the num_complex compiled feature enabled, Complex<f64>. Items can also be extendr’s wrapper types: Rbool, Rint, Rfloat and Rcplx.

Note that the extendr-ndarray integration only supports accessing R arrays as ArrayView, which are immutable. Therefore, instead of directly editing the input array, it is recommended that you instead return a new array from your #[extendr]-annotated function, which you allocate in Rust. It will then be copied into a new block of memory managed by R. This is made easier by the fact that ndarray allocates a new array automatically when performing operations on array references:

use extendr_api::prelude::*;

#[extendr]
fn scalar_multiplication(matrix: ArrayView2<f64>, scalar: f64) -> Robj {
    (&matrix * scalar).try_into().unwrap()
}

For all array uses in Rust, refer to the ndarray::ArrayBase documentation, which explains the usage for all of the above types.

Macros§