tenferro_ops/
reduction.rs1use thiserror::Error;
2
3#[derive(Debug, Clone, PartialEq, Eq, Error)]
5pub enum ReductionShapeError {
6 #[error("axis {axis} is out of bounds for rank {rank}")]
8 AxisOutOfBounds { axis: usize, rank: usize },
9 #[error("duplicate axis {axis}")]
11 DuplicateAxis { axis: usize },
12}
13
14pub fn reduced_shape(
30 input_shape: &[usize],
31 axes: &[usize],
32 keepdims: bool,
33) -> Result<Vec<usize>, ReductionShapeError> {
34 let mut reduced = vec![false; input_shape.len()];
35 for &axis in axes {
36 if axis >= input_shape.len() {
37 return Err(ReductionShapeError::AxisOutOfBounds {
38 axis,
39 rank: input_shape.len(),
40 });
41 }
42 if reduced[axis] {
43 return Err(ReductionShapeError::DuplicateAxis { axis });
44 }
45 reduced[axis] = true;
46 }
47 let mut out = Vec::with_capacity(input_shape.len());
48 for (axis, &dim) in input_shape.iter().enumerate() {
49 if reduced[axis] {
50 if keepdims {
51 out.push(1);
52 }
53 } else {
54 out.push(dim);
55 }
56 }
57 Ok(out)
58}