1use crate::*;
2use mech_core::*;
3use num_traits::*;
4#[cfg(feature = "matrix")]
5use mech_core::matrix::Matrix;
6
7macro_rules! sum_column_op {
10 ($arg:expr, $out:expr) => {
11 unsafe {
12 *$out = (*$arg).column_sum();
13 }
14 };}
15
16#[cfg(all(feature = "matrix1", feature = "matrix1"))]
17impls_stas!(StatsSumColumnM1, Matrix1<T>, Matrix1<T>, sum_column_op);
18#[cfg(all(feature = "matrix2", feature = "vector2"))]
19impls_stas!(StatsSumColumnM2, Matrix2<T>, Vector2<T>, sum_column_op);
20#[cfg(all(feature = "matrix3", feature = "vector3"))]
21impls_stas!(StatsSumColumnM3, Matrix3<T>, Vector3<T>, sum_column_op);
22#[cfg(all(feature = "matrix4", feature = "vector4"))]
23impls_stas!(StatsSumColumnM4, Matrix4<T>, Vector4<T>, sum_column_op);
24#[cfg(all(feature = "matrix2x3", feature = "vector2"))]
25impls_stas!(StatsSumColumnM2x3, Matrix2x3<T>, Vector2<T>, sum_column_op);
26#[cfg(all(feature = "matrix3x2", feature = "vector3"))]
27impls_stas!(StatsSumColumnM3x2, Matrix3x2<T>, Vector3<T>, sum_column_op);
28#[cfg(all(feature = "matrixd", feature = "vectord"))]
29impls_stas!(StatsSumColumnMD, DMatrix<T>, DVector<T>, sum_column_op);
30#[cfg(all(feature = "vector2", feature = "vector2"))]
31impls_stas!(StatsSumColumnV2, Vector2<T>, Vector2<T>, sum_column_op);
32#[cfg(all(feature = "vector3", feature = "vector3"))]
33impls_stas!(StatsSumColumnV3, Vector3<T>, Vector3<T>, sum_column_op);
34#[cfg(all(feature = "vector4", feature = "vector4"))]
35impls_stas!(StatsSumColumnV4, Vector4<T>, Vector4<T>, sum_column_op);
36#[cfg(all(feature = "vectord", feature = "vectord"))]
37impls_stas!(StatsSumColumnVD, DVector<T>, DVector<T>, sum_column_op);
38#[cfg(all(feature = "row_vector2", feature = "matrix1"))]
39impls_stas!(StatsSumColumnR2, RowVector2<T>, Matrix1<T>, sum_column_op);
40#[cfg(all(feature = "row_vector3", feature = "matrix1"))]
41impls_stas!(StatsSumColumnR3, RowVector3<T>, Matrix1<T>, sum_column_op);
42#[cfg(all(feature = "row_vector4", feature = "matrix1"))]
43impls_stas!(StatsSumColumnR4, RowVector4<T>, Matrix1<T>, sum_column_op);
44#[cfg(all(feature = "row_vectord", feature = "matrix1"))]
45impls_stas!(StatsSumColumnRD, RowDVector<T>, Matrix1<T>, sum_column_op);
46
47#[cfg(all(feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
48#[derive(Debug)]
49struct StatsSumColumnRD2<T> {
50 arg: Ref<RowDVector<T>>,
51 out: Ref<DMatrix<T>>,
52}
53
54#[cfg(all(feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
55impl<T> MechFunctionFactory for StatsSumColumnRD2<T>
56where
57 T: Copy + Debug + Clone + Sync + Send + 'static +
58 Add<Output = T> + AddAssign +
59 CompileConst + ConstElem + AsValueKind +
60 Zero + One +
61 PartialEq + PartialOrd,
62 Ref<DMatrix<T>>: ToValue,
63{
64 fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
65 match args {
66 FunctionArgs::Unary(out, arg) => {
67 let arg = unsafe { arg.as_unchecked().clone() };
68 let out = unsafe { out.as_unchecked().clone() };
69 Ok(Box::new(StatsSumColumnRD2 { arg, out }))
70 }
71 _ => Err(MechError2::new(
72 IncorrectNumberOfArguments { expected: 2, found: args.len() },
73 None
74 ).with_compiler_loc()
75 ),
76 }
77 }
78}
79#[cfg(all(feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
80impl<T> MechFunctionImpl for StatsSumColumnRD2<T>
81where
82 T: Copy + Debug + Clone + Sync + Send + 'static +
83 Add<Output = T> + AddAssign +
84 Zero + One +
85 PartialEq + PartialOrd,
86 Ref<DMatrix<T>>: ToValue,
87{
88 fn solve(&self) {
89 let arg_ptr = self.arg.as_ptr();
90 let mut out_ptr = self.out.as_mut_ptr();
91 unsafe {
92 (&mut (*out_ptr))[(0,0)] = (*arg_ptr).column_sum()[0];
93 }
94 }
95 fn out(&self) -> Value { self.out.to_value() }
96 fn to_string(&self) -> String { format!("{:#?}", self) }
97}
98
99#[cfg(all(feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
100#[cfg(feature = "compiler")]
101impl<T> MechFunctionCompiler for StatsSumColumnRD2<T>
102where
103 T: CompileConst + ConstElem + AsValueKind,
104{
105 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
106 let name = format!("{}<{}>", stringify!(StatsSumColumnRD2), T::as_value_kind());
107 compile_unop!(name,self.out,self.arg,ctx,FeatureFlag::Custom(hash_str("stats/sum")));
108 }
109}
110#[cfg(all(feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
111register_fxn_descriptor!(StatsSumColumnRD2, u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128", f32, "f32", f64, "f64", C64, "complex", R64, "rational");
112
113macro_rules! impl_stats_sum_column_match_arms {
114 ($arg:expr, $($input_type:ident, $($target_type:ident, $value_string:tt),+);+ $(;)?) => {
115 paste!{
116 match $arg {
117 $(
118 $(
119 #[cfg(all(feature = $value_string, feature = "row_vector4", feature = "matrix1"))]
120 Value::[<Matrix $input_type>](Matrix::<$target_type>::RowVector4(arg)) => Ok(Box::new(StatsSumColumnR4{arg: arg.clone(), out: Ref::new(Matrix1::from_element($target_type::default())) })),
121 #[cfg(all(feature = $value_string, feature = "row_vector3", feature = "matrix1"))]
122 Value::[<Matrix $input_type>](Matrix::<$target_type>::RowVector3(arg)) => Ok(Box::new(StatsSumColumnR3{arg: arg.clone(), out: Ref::new(Matrix1::from_element($target_type::default())) })),
123 #[cfg(all(feature = $value_string, feature = "row_vector2", feature = "matrix1"))]
124 Value::[<Matrix $input_type>](Matrix::<$target_type>::RowVector2(arg)) => Ok(Box::new(StatsSumColumnR2{arg: arg.clone(), out: Ref::new(Matrix1::from_element($target_type::default())) })),
125 #[cfg(all(feature = $value_string, feature = "vector4", feature = "vector4"))]
126 Value::[<Matrix $input_type>](Matrix::<$target_type>::Vector4(arg)) => Ok(Box::new(StatsSumColumnV4{arg: arg.clone(), out: Ref::new(Vector4::from_element($target_type::default())) })),
127 #[cfg(all(feature = $value_string, feature = "vector3", feature = "vector3"))]
128 Value::[<Matrix $input_type>](Matrix::<$target_type>::Vector3(arg)) => Ok(Box::new(StatsSumColumnV3{arg: arg.clone(), out: Ref::new(Vector3::from_element($target_type::default())) })),
129 #[cfg(all(feature = $value_string, feature = "vector2", feature = "vector2"))]
130 Value::[<Matrix $input_type>](Matrix::<$target_type>::Vector2(arg)) => Ok(Box::new(StatsSumColumnV2{arg: arg.clone(), out: Ref::new(Vector2::from_element($target_type::default())) })),
131 #[cfg(all(feature = $value_string, feature = "matrix4", feature = "vector4"))]
132 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix4(arg)) => Ok(Box::new(StatsSumColumnM4{arg: arg.clone(), out: Ref::new(Vector4::from_element($target_type::default()))})),
133 #[cfg(all(feature = $value_string, feature = "matrix3", feature = "vector3"))]
134 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix3(arg)) => Ok(Box::new(StatsSumColumnM3{arg: arg.clone(), out: Ref::new(Vector3::from_element($target_type::default()))})),
135 #[cfg(all(feature = $value_string, feature = "matrix2", feature = "vector2"))]
136 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix2(arg)) => Ok(Box::new(StatsSumColumnM2{arg: arg.clone(), out: Ref::new(Vector2::from_element($target_type::default()))})),
137 #[cfg(all(feature = $value_string, feature = "matrix1", feature = "matrix1"))]
138 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix1(arg)) => Ok(Box::new(StatsSumColumnM1{arg: arg.clone(), out: Ref::new(Matrix1::from_element($target_type::default())) })),
139 #[cfg(all(feature = $value_string, feature = "matrix2x3", feature = "vector2"))]
140 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix2x3(arg)) => Ok(Box::new(StatsSumColumnM2x3{arg: arg.clone(), out: Ref::new(Vector2::from_element($target_type::default()))})),
141 #[cfg(all(feature = $value_string, feature = "matrix3x2", feature = "vector3"))]
142 Value::[<Matrix $input_type>](Matrix::<$target_type>::Matrix3x2(arg)) => Ok(Box::new(StatsSumColumnM3x2{arg: arg.clone(), out: Ref::new(Vector3::from_element($target_type::default()))})),
143 #[cfg(all(feature = $value_string, feature = "vectord", feature = "vectord"))]
144 Value::[<Matrix $input_type>](Matrix::<$target_type>::DVector(arg)) => Ok(Box::new(StatsSumColumnVD{arg: arg.clone(), out: Ref::new(DVector::from_element(arg.borrow().len(),$target_type::default())) })),
145 #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "matrix1"))]
146 Value::[<Matrix $input_type>](Matrix::<$target_type>::RowDVector(arg)) => Ok(Box::new(StatsSumColumnRD{arg: arg.clone(), out: Ref::new(Matrix1::from_element($target_type::default())) })),
147 #[cfg(all(feature = $value_string, feature = "row_vectord", feature = "matrixd", not(feature = "matrix1")))]
148 Value::[<Matrix $input_type>](Matrix::<$target_type>::RowDVector(arg)) => Ok(Box::new(StatsSumColumnRD2{arg: arg.clone(), out: Ref::new(DMatrix::from_element(1,1,$target_type::default())) })),
149 #[cfg(all(feature = $value_string, feature = "matrixd", feature = "vectord"))]
150 Value::[<Matrix $input_type>](Matrix::<$target_type>::DMatrix(arg)) => Ok(Box::new(StatsSumColumnMD{arg: arg.clone(), out: Ref::new(DVector::from_element(arg.borrow().nrows(),$target_type::default())) })),
151 )+
152 )+
153 _ => Err(MechError2::new(
154 UnhandledFunctionArgumentKind1 {arg: $arg.kind(), fxn_name: stringify!(StatsSumColumn).to_string() },
155 None
156 ).with_compiler_loc()),
157 }
158 }
159 }
160}
161
162fn impl_stats_sum_column_fxn(lhs_value: Value) -> MResult<Box<dyn MechFunction>> {
163 impl_stats_sum_column_match_arms!(
164 lhs_value,
165 I8, i8, "i8";
166 I16, i16, "i16";
167 I32, i32, "i32";
168 I64, i64, "i64";
169 I128, i128, "i128";
170 U8, u8, "u8";
171 U16, u16, "u16";
172 U32, u32, "u32";
173 U64, u64, "u64";
174 U128, u128, "u128";
175 F32, f32, "f32";
176 F64, f64, "f64";
177 C64, C64, "complex";
178 R64, R64, "rational"
179 )
180}
181
182impl_mech_urnop_fxn!(StatsSumColumn,impl_stats_sum_column_fxn,"stats/sum/column");