mod array_methods;
mod core;
mod fancy;
mod index_utils;
mod take_put;
#[cfg(test)]
mod tests;
use crate::array::Array;
use crate::error::Result;
use std::ops::Range;
pub use self::array_methods::*;
pub use self::core::*;
pub use self::fancy::*;
pub use self::index_utils::*;
pub use self::take_put::*;
#[derive(Clone)]
pub enum IndexSpec {
Index(usize),
Slice(usize, Option<usize>, Option<usize>),
Indices(Vec<usize>),
Mask(Vec<bool>),
All,
Ellipsis,
NewAxis,
}
impl IndexSpec {
pub fn slice(start: usize, end: Option<usize>, step: Option<usize>) -> Self {
IndexSpec::Slice(start, end, step)
}
pub fn from_range(range: Range<usize>) -> Self {
IndexSpec::Slice(range.start, Some(range.end), None)
}
pub fn from_indices(indices: Vec<usize>) -> Self {
IndexSpec::Indices(indices)
}
pub fn from_mask(mask: Vec<bool>) -> Self {
IndexSpec::Mask(mask)
}
pub fn ellipsis() -> Self {
IndexSpec::Ellipsis
}
pub fn newaxis() -> Self {
IndexSpec::NewAxis
}
}
pub(crate) fn insert_newaxis<T: Clone + num_traits::Zero>(
arr: &Array<T>,
output_positions: &[usize],
) -> Result<Array<T>> {
if output_positions.is_empty() {
return Ok(arr.clone());
}
let newaxis_set: std::collections::HashSet<usize> = output_positions.iter().copied().collect();
let new_ndim = arr.ndim() + output_positions.len();
let mut new_shape = Vec::with_capacity(new_ndim);
let mut orig_dim_idx = 0;
for out_dim in 0..new_ndim {
if newaxis_set.contains(&out_dim) {
new_shape.push(1);
} else {
if orig_dim_idx < arr.ndim() {
new_shape.push(arr.shape()[orig_dim_idx]);
orig_dim_idx += 1;
} else {
new_shape.push(1);
}
}
}
Ok(arr.reshape(&new_shape))
}