evalexpr_jit/backends/
vector.rs

1/// A trait for vector-like types that can be used with the JIT compiler.
2///
3/// This trait provides a common interface for different vector implementations,
4/// allowing them to be used interchangeably in JIT-compiled functions. It defines
5/// core vector operations needed for JIT compilation, including accessing raw data
6/// and creating zero-initialized vectors.
7///
8/// # Examples
9///
10/// ```rust
11/// use evalexpr_jit::prelude::Vector;
12///
13/// // Create a zero vector
14/// let vec: Vec<f64> = Vector::zeros(5);
15/// assert_eq!(vec.len(), 5);
16///
17/// // Access elements
18/// let mut vec = vec![1.0, 2.0, 3.0];
19/// let slice = vec.as_slice();
20/// assert_eq!(slice[0], 1.0);
21/// ```
22pub trait Vector {
23    /// Returns a reference to the vector's data as a slice.
24    fn as_slice(&self) -> &[f64];
25
26    /// Returns a mutable reference to the vector's data as a slice.
27    fn as_mut_slice(&mut self) -> &mut [f64];
28
29    /// Creates a new vector of the specified length filled with zeros.
30    ///
31    /// # Arguments
32    /// * `len` - The length of the vector to create
33    fn zeros(len: usize) -> Self;
34
35    /// Returns the length of the vector.
36    fn len(&self) -> usize;
37
38    /// Checks if the vector is empty.
39    fn is_empty(&self) -> bool {
40        self.len() == 0
41    }
42}
43
44/// Implementation of Vector trait for standard Vec<f64>.
45///
46/// This implementation provides an interface between the Vector trait and Rust's
47/// standard vector type. Vec<f64> already provides slice access, making this
48/// implementation straightforward.
49///
50/// # Examples
51///
52/// ```rust
53/// use evalexpr_jit::prelude::Vector;
54///
55/// let mut vec = Vec::<f64>::zeros(3);
56/// let slice = vec.as_mut_slice();
57/// slice[0] = 1.0;
58/// assert_eq!(vec[0], 1.0);
59/// ```
60impl Vector for Vec<f64> {
61    fn as_slice(&self) -> &[f64] {
62        self
63    }
64
65    fn as_mut_slice(&mut self) -> &mut [f64] {
66        self
67    }
68
69    fn zeros(len: usize) -> Self {
70        vec![0.0; len]
71    }
72
73    fn len(&self) -> usize {
74        self.len()
75    }
76}
77
78/// Implementation of Vector trait for ndarray's Array1<f64>.
79///
80/// This implementation provides an interface between the Vector trait and ndarray's
81/// 1-dimensional array type. It handles the conversion between ndarray's internal
82/// representation and the slice representation required by the JIT compiler.
83///
84/// # Examples
85///
86/// ```rust
87/// use evalexpr_jit::prelude::Vector;
88/// use ndarray::Array1;
89///
90/// let mut vec = Array1::<f64>::zeros(3);
91/// let slice = vec.as_mut_slice();
92/// slice[0] = 1.0;
93/// assert!(std::ptr::eq(slice, vec.as_slice().unwrap()));
94/// ```
95#[cfg(feature = "ndarray")]
96impl Vector for ndarray::Array1<f64> {
97    fn as_slice(&self) -> &[f64] {
98        self.as_slice().unwrap()
99    }
100
101    fn as_mut_slice(&mut self) -> &mut [f64] {
102        self.as_slice_mut().unwrap()
103    }
104
105    fn zeros(len: usize) -> Self {
106        ndarray::Array1::zeros(len)
107    }
108
109    fn len(&self) -> usize {
110        self.len()
111    }
112}
113
114/// Implementation of Vector trait for nalgebra's DVector<f64>.
115///
116/// This implementation provides an interface between the Vector trait and nalgebra's
117/// dynamic vector type. It handles the conversion between nalgebra's internal
118/// representation and the slice representation required by the JIT compiler.
119///
120/// # Examples
121///
122/// ```rust
123/// use evalexpr_jit::prelude::Vector;
124/// use nalgebra::DVector;
125///
126/// let mut vec = DVector::<f64>::zeros(3);
127/// let slice = vec.as_mut_slice();
128/// slice[0] = 1.0;
129/// assert!(std::ptr::eq(slice, vec.as_slice()));
130/// ```
131#[cfg(feature = "nalgebra")]
132impl Vector for nalgebra::DVector<f64> {
133    fn as_slice(&self) -> &[f64] {
134        self.as_slice()
135    }
136
137    fn as_mut_slice(&mut self) -> &mut [f64] {
138        self.as_mut_slice()
139    }
140
141    fn zeros(len: usize) -> Self {
142        nalgebra::DVector::zeros(len)
143    }
144
145    fn len(&self) -> usize {
146        self.len()
147    }
148}
149
150/// Implementation of Vector trait for fixed-size arrays.
151///
152/// This implementation allows fixed-size arrays to be used with the JIT compiler.
153/// The array size is specified through the const generic parameter N.
154///
155/// # Type Parameters
156/// * `N` - The fixed size of the array
157///
158/// # Examples
159///
160/// ```rust
161/// use evalexpr_jit::prelude::Vector;
162///
163/// let mut arr = <[f64; 3]>::zeros(3);
164/// let slice = arr.as_mut_slice();
165/// slice[0] = 1.0;
166/// assert_eq!(arr[0], 1.0);
167/// ```
168impl<const N: usize> Vector for [f64; N] {
169    fn as_slice(&self) -> &[f64] {
170        self
171    }
172
173    fn as_mut_slice(&mut self) -> &mut [f64] {
174        self
175    }
176
177    fn zeros(len: usize) -> Self {
178        assert_eq!(len, N, "Array length must match const generic size");
179        [0.0; N]
180    }
181
182    fn len(&self) -> usize {
183        N
184    }
185}