#![allow( clippy::many_single_char_names, clippy::deref_addrof, clippy::unreadable_literal, clippy::many_single_char_names )] use ndarray::prelude::*; /// Reorder a's axes so that they are in "standard" axis order; /// make sure axes are in positive stride direction, and merge adjacent /// axes if possible. /// /// This changes the logical order of the elements in the /// array, so that if we read them in row-major order after regularization, /// it corresponds to their order in memory. /// /// Errors if array has a 0-stride axis fn regularize(a: &mut Array) -> Result<(), &'static str> where D: Dimension, A: ::std::fmt::Debug, { println!("Regularize:\n{:?}", a); // reverse all neg axes while let Some(ax) = a.axes().find(|ax| ax.stride <= 0) { if ax.stride == 0 { // no real reason to error on this case; other than // stride == 0 is incompatible with an owned array. return Err("Cannot regularize array with stride == 0 axis"); } // reverse ax println!("Reverse {:?}", ax.axis); a.invert_axis(ax.axis); } // sort by least stride let mut i = 0; let n = a.ndim(); while let Some(ax) = a.axes().rev().skip(i).min_by_key(|ax| ax.stride.abs()) { let cur_axis = Axis(n - 1 - i); if ax.axis != cur_axis { a.swap_axes(cur_axis.index(), ax.axis.index()); println!("Swap {:?} <=> {:?}", cur_axis, ax.axis); } i += 1; } // merge the lower axes if possible for j in (0..n).rev().skip(1) { if a.merge_axes(Axis(j), Axis(n - 1)) { println!("Merged {:?} into {:?}", Axis(j), Axis(n - 1)); } else { break; } } println!("Result:\n{:?}\n", a); Ok(()) } fn main() { let mut a = Array::::zeros((2, 3, 4)); for (i, elt) in (0..).zip(&mut a) { *elt = i; } a.swap_axes(0, 1); a.swap_axes(0, 2); a.slice_collapse(s![.., ..;-1, ..]); regularize(&mut a).unwrap(); let mut b = Array::::zeros((2, 3, 4)); for (i, elt) in (0..).zip(&mut b) { *elt = i; } regularize(&mut b).unwrap(); let mut b = b.into_shape_with_order(a.len()).unwrap(); regularize(&mut b).unwrap(); b.invert_axis(Axis(0)); regularize(&mut b).unwrap(); let mut a = Array::::zeros((2, 3, 4)); for (i, elt) in (0..).zip(&mut a) { *elt = i; } a.slice_collapse(s![..;-1, ..;2, ..]); regularize(&mut a).unwrap(); }