1use crate::matrix::MatrixValue;
2use ndarray::Axis;
3use nu_engine::command_prelude::*;
4
5#[derive(Clone)]
6pub struct MatrixMax;
7
8impl Command for MatrixMax {
9 fn name(&self) -> &str {
10 "matrix max"
11 }
12
13 fn signature(&self) -> Signature {
14 Signature::build("matrix max")
15 .input_output_types(vec![
16 (Type::Custom("matrix".into()), Type::Float),
17 (Type::Custom("matrix".into()), Type::Custom("matrix".into())),
18 ])
19 .named(
20 "axis",
21 SyntaxShape::Int,
22 "The axis to find the max along (0-based).",
23 Some('a'),
24 )
25 .category(Category::Filters)
26 }
27
28 fn description(&self) -> &str {
29 "Find the maximum value in a matrix, or max along an axis."
30 }
31
32 fn search_terms(&self) -> Vec<&str> {
33 vec!["maximum"]
34 }
35
36 fn run(
37 &self,
38 engine_state: &EngineState,
39 stack: &mut Stack,
40 call: &Call,
41 input: PipelineData,
42 ) -> Result<PipelineData, ShellError> {
43 let head = call.head;
44 let axis: Option<i64> = call.get_flag(engine_state, stack, "axis")?;
45 let matrix = MatrixValue::from_value(&input.into_value(head)?)?;
46
47 match axis {
48 Some(axis) => {
49 let axis = axis as usize;
50 if axis >= matrix.array.ndim() {
51 return Err(ShellError::Generic(
52 nu_protocol::shell_error::generic::GenericError::new(
53 "Invalid axis",
54 format!(
55 "axis {} is out of bounds for a {}-dimensional array",
56 axis,
57 matrix.array.ndim()
58 ),
59 head,
60 ),
61 ));
62 }
63 let result = matrix.array.map_axis(Axis(axis), |view| {
64 view.iter().cloned().fold(f64::NEG_INFINITY, f64::max)
65 });
66 Ok(MatrixValue::new(result)
67 .into_value(head)
68 .into_pipeline_data())
69 }
70 None => {
71 let max_val: f64 = matrix
72 .array
73 .iter()
74 .cloned()
75 .fold(f64::NEG_INFINITY, f64::max);
76 Ok(Value::float(max_val, head).into_pipeline_data())
77 }
78 }
79 }
80
81 fn examples(&self) -> Vec<Example<'static>> {
82 vec![
83 Example {
84 description: "Find the maximum element in a matrix",
85 example: "[[1 2] [3 4]] | into matrix | matrix max",
86 result: Some(Value::test_float(4.0)),
87 },
88 Example {
89 description: "Find max along rows (axis 0)",
90 example: "[[1 2] [3 4]] | into matrix | matrix max --axis 0 | matrix into-nu | to nuon",
91 result: Some(Value::test_string("[[3.0, 4.0]]")),
92 },
93 Example {
94 description: "Find max along columns (axis 1)",
95 example: "[[1 2] [3 4]] | into matrix | matrix max --axis 1 | matrix into-nu | to nuon",
96 result: Some(Value::test_string("[[2.0, 4.0]]")),
97 },
98 ]
99 }
100}
101
102#[cfg(test)]
103mod test {
104 use super::*;
105
106 #[test]
107 fn test_examples() -> nu_test_support::Result {
108 nu_test_support::test().examples(MatrixMax)
109 }
110}