Reputation: 5566
In numpy, one can do
>>> np.linspace([1,2,3], [4,5,6], 4)
array([[1., 2., 3.],
[2., 3., 4.],
[3., 4., 5.],
[4., 5., 6.]])
However, it seems this isn't available from rust ndarray's linspace
which only accepts Float
.
How do I generalize rust-ndarray's linspace
to accept 1D arrays (Array1<T>
) of arbitrary size?
Upvotes: 0
Views: 109
Reputation: 5566
May not be optimized, but one way is the following
fn linspace<A:Float>(start: Array1<A>, end: Array1<A>, n: usize) -> Array<A, Dim<[usize; 2]>>{
assert!(start.len() == end.len());
Array::from_shape_vec((start.len(), n), (0..start.len()).map(|idx| Array::linspace(start[idx], end[idx], n)).flatten().collect()).unwrap().reversed_axes()
}
Basically,
assert!(start.len() == end.len());
asserts same length(start.len(), n), (0..start.len()).map(|idx| Array::linspace(start[idx], end[idx], n))
repeatedly calls Array::linspace
on each index which results in a nested Vec<Array<...>>
.flatten().collect()
flattens the Vec<Array<...>>
into a 1D Vec<...>
Array::from_shape_vec().unwrap()
converts the Vec<...>
into a (start.len(), n)
sized Array
(this is required since flatten arranges the elements as such).reversed_axes()
transposes the array into shape (n, start.len())
as is the case in numpy's linspaceThis passes the following test
mod tests {
use ndarray::array;
use super::*;
#[test]
fn test_linspace() {
assert_eq!(linspace(array![1.,2.,3.], array![4.,5.,6.], 4), array![[1.,2.,3.],[2., 3., 4.], [3.,4.,5.], [4.,5.,6.]])
}
}
Upvotes: 0