1use crate::*;
2use mech_core::*;
3
4macro_rules! mul_op {
7  ($lhs:expr, $rhs:expr, $out:expr) => {
8    unsafe { *$out = *$lhs * *$rhs; }
9  };}
10
11macro_rules! matmul_op {
12  ($lhs:expr, $rhs:expr, $out:expr) => {
13    unsafe { (*$lhs).mul_to(&*$rhs,&mut *$out); }
14  };}
15
16impl_binop!(MatMulScalar, T,T,T,mul_op);
17#[cfg(feature = "RowVector4")]
18impl_binop!(MatMulR4V4, RowVector4<T>,Vector4<T>,Matrix1<T>,matmul_op);
19#[cfg(feature = "RowVector4")]
20impl_binop!(MatMulR4M4, RowVector4<T>,Matrix4<T>,RowVector4<T>,matmul_op);
21#[cfg(feature = "RowVector4")]
22impl_binop!(MatMulR4MD, RowVector4<T>,DMatrix<T>,RowDVector<T>,matmul_op);
23
24#[cfg(feature = "RowVector3")]
25impl_binop!(MatMulR3V3, RowVector3<T>,Vector3<T>,Matrix1<T>,matmul_op);
26#[cfg(feature = "RowVector3")]
27impl_binop!(MatMulR3M3, RowVector3<T>,Matrix3<T>,RowVector3<T>,matmul_op);
28#[cfg(feature = "RowVector3")]
29impl_binop!(MatMulR2M3x2, RowVector3<T>,Matrix3x2<T>,RowVector2<T>,matmul_op);
30#[cfg(feature = "RowVector3")]
31impl_binop!(MatMulR3MD, RowVector3<T>,DMatrix<T>,RowDVector<T>,matmul_op);
32
33#[cfg(feature = "RowVector2")]
34impl_binop!(MatMulR2V2, RowVector2<T>,Vector2<T>,Matrix1<T>,matmul_op);
35#[cfg(feature = "RowVector2")]
36impl_binop!(MatMulR2M2, RowVector2<T>,Matrix2<T>,RowVector2<T>,matmul_op);
37#[cfg(feature = "RowVector2")]
38impl_binop!(MatMulR2M2x3, RowVector2<T>,Matrix2x3<T>,RowVector3<T>,matmul_op);
39#[cfg(feature = "RowVector2")]
40impl_binop!(MatMulR2MD, RowVector2<T>,DMatrix<T>,RowDVector<T>,matmul_op);
41
42#[cfg(feature = "RowVectorD")]
43impl_binop!(MatMulRDVD, RowDVector<T>, DVector<T>, Matrix1<T>,matmul_op);
44#[cfg(feature = "RowVectorD")]
45impl_binop!(MatMulRDMD, RowDVector<T>, DMatrix<T>, RowDVector<T>,matmul_op);
46
47#[cfg(feature = "Vector4")]
48impl_binop!(MatMulV4R4, Vector4<T>, RowVector4<T>, Matrix4<T>,matmul_op);
49#[cfg(feature = "Vector3")]
50impl_binop!(MatMulV3R3, Vector3<T>, RowVector3<T>, Matrix3<T>,matmul_op);
51#[cfg(feature = "Vector2")]
52impl_binop!(MatMulV2R2, Vector2<T>, RowVector2<T>, Matrix2<T>,matmul_op);
53
54#[cfg(feature = "VectorD")]
55impl_binop!(MatMulVDRD, DVector<T>,RowDVector<T>,DMatrix<T>,matmul_op);
56
57#[cfg(feature = "Matrix4")]
58impl_binop!(MatMulM4V4, Matrix4<T>, Vector4<T>, Vector4<T>,matmul_op);
59#[cfg(feature = "Matrix4")]
60impl_binop!(MatMulM4M4, Matrix4<T>, Matrix4<T>, Matrix4<T>,matmul_op);
61#[cfg(feature = "Matrix4")]
62impl_binop!(MatMulM4MD, Matrix4<T>, DMatrix<T>, DMatrix<T>,matmul_op);
63
64#[cfg(feature = "Matrix2")]
65impl_binop!(MatMulM2M2x3, Matrix2<T>, Matrix2x3<T>, Matrix2x3<T>,matmul_op);
66#[cfg(feature = "Matrix2")]
67impl_binop!(MatMulM2M2, Matrix2<T>, Matrix2<T>, Matrix2<T>,matmul_op);
68#[cfg(feature = "Matrix2")]
69impl_binop!(MatMulM2V2, Matrix2<T>, Vector2<T>, Vector2<T>,matmul_op);
70#[cfg(feature = "Matrix2")]
71impl_binop!(MatMulM2MD, Matrix2<T>, DMatrix<T>, DMatrix<T>,matmul_op);
72
73#[cfg(feature = "Matrix3")]
74impl_binop!(MatMulM3M3, Matrix3<T>, Matrix3<T>, Matrix3<T>,matmul_op);
75#[cfg(feature = "Matrix3")]
76impl_binop!(MatMulM2M3x2, Matrix3<T>, Matrix3x2<T>, Matrix3x2<T>,matmul_op);
77#[cfg(feature = "Matrix3")]
78impl_binop!(MatMulM3V3, Matrix3<T>, Vector3<T>, Vector3<T>,matmul_op);
79#[cfg(feature = "Matrix3")]
80impl_binop!(MatMulM3MD, Matrix3<T>, DMatrix<T>, DMatrix<T>,matmul_op);
81
82#[cfg(feature = "Matrix1")]
83impl_binop!(MatMulM1M1, Matrix1<T>, Matrix1<T>, Matrix1<T>,matmul_op);
84
85#[cfg(feature = "Matrix2x3")]
86impl_binop!(MatMulM2x3V2, Matrix2x3<T>, Vector3<T>, Vector2<T>,matmul_op);
87#[cfg(feature = "Matrix2x3")]
88impl_binop!(MatMulM2x3M3, Matrix2x3<T>, Matrix3<T>, Matrix2x3<T>,matmul_op);
89#[cfg(feature = "Matrix2x3")]
90impl_binop!(MatMulM2x3M3x2, Matrix2x3<T>, Matrix3x2<T>, Matrix2<T>,matmul_op);
91#[cfg(feature = "Matrix2x3")]
92impl_binop!(MatMulM2x3MD, Matrix2x3<T>, DMatrix<T>, DMatrix<T>,matmul_op);
93
94#[cfg(feature = "Matrix3x2")]
95impl_binop!(MatMulM3x2V2, Matrix3x2<T>, Vector2<T>, Vector3<T>,matmul_op);
96#[cfg(feature = "Matrix3x2")]
97impl_binop!(MatMulM3x2M2, Matrix3x2<T>, Matrix2<T>, Matrix3x2<T>,matmul_op);
98#[cfg(feature = "Matrix3x2")]
99impl_binop!(MatMulM3x2M2x3, Matrix3x2<T>, Matrix2x3<T>, Matrix3<T>,matmul_op);
100#[cfg(feature = "Matrix3x2")]
101impl_binop!(MatMulM3x2MD, Matrix3x2<T>, DMatrix<T>, DMatrix<T>,matmul_op);
102
103#[cfg(feature = "MatrixD")]
104impl_binop!(MatMulMDMD, DMatrix<T>,DMatrix<T>,DMatrix<T>,matmul_op);
105#[cfg(feature = "MatrixD")]
106impl_binop!(MatMulMDM3x2, DMatrix<T>,Matrix3x2<T>,DMatrix<T>,matmul_op);
107#[cfg(feature = "MatrixD")]
108impl_binop!(MatMulMDVD, DMatrix<T>,DVector<T>,DVector<T>,matmul_op);
109#[cfg(feature = "MatrixD")]
110impl_binop!(MatMulMDRD, DMatrix<T>,RowDVector<T>,DMatrix<T>,matmul_op);
111
112macro_rules! impl_matmul_match_arms {
113  ($arg:expr, $($lhs_type:ident, $rhs_type:ident => $($matrix_kind:ident, $target_type:ident, $value_string:tt),+);+ $(;)?) => {
114    match $arg {
115      $(
116        $(
117          #[cfg(feature = $value_string)]
118          (Value::$lhs_type(lhs), Value::$rhs_type(rhs)) => Ok(Box::new(MatMulScalar { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref($target_type::zero()) })),
119          #[cfg(feature = "RowVector4")]
120          (Value::$matrix_kind(Matrix::RowVector4(lhs)), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new(MatMulR4V4 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix1::from_element($target_type::zero())) })),
121          #[cfg(feature = "RowVector4")]
122          (Value::$matrix_kind(Matrix::RowVector4(lhs)), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new(MatMulR4M4 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector4::from_element($target_type::zero())) })),
123          #[cfg(feature = "RowVector4")]
124          (Value::$matrix_kind(Matrix::RowVector4(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulR4MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowDVector::from_element(rhs.borrow().ncols(),$target_type::zero())) })),
125          
126          #[cfg(feature = "RowVector3")]
127          (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new(MatMulR3V3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix1::from_element($target_type::zero())) })),
128          #[cfg(feature = "RowVector3")]
129          (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new(MatMulR3M3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector3::from_element($target_type::zero())) })),
130          #[cfg(feature = "RowVector3")]
131          (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new(MatMulR2M3x2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector2::from_element($target_type::zero())) })),
132          #[cfg(feature = "RowVector3")]
133          (Value::$matrix_kind(Matrix::RowVector3(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulR3MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowDVector::from_element(rhs.borrow().ncols(), $target_type::zero())) })),
134                    
135          #[cfg(feature = "RowVector2")]
136          (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new(MatMulR2V2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix1::from_element($target_type::zero())) })),
137          #[cfg(feature = "RowVector2")]
138          (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new(MatMulR2M2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector2::from_element($target_type::zero())) })),
139          #[cfg(feature = "RowVector2")]
140          (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new(MatMulR2M2x3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector3::from_element($target_type::zero())) })),
141          #[cfg(feature = "RowVector2")]
142          (Value::$matrix_kind(Matrix::RowVector2(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulR2MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowDVector::from_element(rhs.borrow().ncols(), $target_type::zero())) })),
143
144          #[cfg(feature = "RowVectorD")]
145          (Value::$matrix_kind(Matrix::RowDVector(lhs)), Value::$matrix_kind(Matrix::DVector(rhs))) => Ok(Box::new(MatMulRDVD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix1::from_element($target_type::zero())) })),
146          #[cfg(feature = "RowVectorD")]
147          (Value::$matrix_kind(Matrix::RowDVector(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulRDMD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowDVector::from_element(rhs.borrow().ncols(), $target_type::zero())) })),
148                    
149          #[cfg(feature = "Vector4")]
150          (Value::$matrix_kind(Matrix::Vector4(lhs)), Value::$matrix_kind(Matrix::RowVector4(rhs))) => Ok(Box::new(MatMulV4R4 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix4::from_element($target_type::zero())) })),
151          #[cfg(feature = "Vector3")]
152          (Value::$matrix_kind(Matrix::Vector3(lhs)), Value::$matrix_kind(Matrix::RowVector3(rhs))) => Ok(Box::new(MatMulV3R3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix3::from_element($target_type::zero())) })),
153          #[cfg(feature = "Vector2")]
154          (Value::$matrix_kind(Matrix::Vector2(lhs)), Value::$matrix_kind(Matrix::RowVector2(rhs))) => Ok(Box::new(MatMulV2R2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix2::from_element($target_type::zero())) })),
155
156          #[cfg(feature = "VectorD")]
157          (Value::$matrix_kind(Matrix::DVector(lhs)), Value::$matrix_kind(Matrix::RowDVector(rhs))) => Ok(Box::new(MatMulVDRD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
158
159          #[cfg(feature = "Matrix4")]
160          (Value::$matrix_kind(Matrix::Matrix4(lhs)), Value::$matrix_kind(Matrix::Vector4(rhs))) => Ok(Box::new(MatMulM4V4 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector4::from_element($target_type::zero())) })),
161          #[cfg(feature = "Matrix4")]
162          (Value::$matrix_kind(Matrix::Matrix4(lhs)), Value::$matrix_kind(Matrix::Matrix4(rhs))) => Ok(Box::new(MatMulM4M4 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix4::from_element($target_type::zero())) })),
163          #[cfg(feature = "Matrix4")]
164          (Value::$matrix_kind(Matrix::Matrix4(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulM4MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
165
166          #[cfg(feature = "Matrix2")]
167          (Value::$matrix_kind(Matrix::Matrix2(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new(MatMulM2M2x3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix2x3::from_element($target_type::zero())) })),
168          #[cfg(feature = "Matrix2")]
169          (Value::$matrix_kind(Matrix::Matrix2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new(MatMulM2M2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix2::from_element($target_type::zero())) })),
170          #[cfg(feature = "Matrix2")]
171          (Value::$matrix_kind(Matrix::Matrix2(lhs)), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new(MatMulM2V2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector2::from_element($target_type::zero())) })),
172          #[cfg(feature = "Matrix2")]
173          (Value::$matrix_kind(Matrix::Matrix2(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulM2MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
174
175          #[cfg(feature = "Matrix3")]
176          (Value::$matrix_kind(Matrix::Matrix3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new(MatMulM3M3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix3::from_element($target_type::zero())) })),
177          #[cfg(feature = "Matrix3")]
178          (Value::$matrix_kind(Matrix::Matrix3(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new(MatMulM2M3x2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix3x2::from_element($target_type::zero())) })),
179          #[cfg(feature = "Matrix3")]
180          (Value::$matrix_kind(Matrix::Matrix3(lhs)), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new(MatMulM3V3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector3::from_element($target_type::zero())) })),
181          #[cfg(feature = "Matrix3")]
182          (Value::$matrix_kind(Matrix::Matrix3(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulM3MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
183
184          #[cfg(feature = "Matrix1")]
185          (Value::$matrix_kind(Matrix::Matrix1(lhs)), Value::$matrix_kind(Matrix::Matrix1(rhs))) => Ok(Box::new(MatMulM1M1 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix1::from_element($target_type::zero())) })),
186
187          #[cfg(feature = "Matrix2x3")]
188          (Value::$matrix_kind(Matrix::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::Vector3(rhs))) => Ok(Box::new(MatMulM2x3V2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector2::from_element($target_type::zero())) })),
189          #[cfg(feature = "Matrix2x3")]
190          (Value::$matrix_kind(Matrix::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::Matrix3(rhs))) => Ok(Box::new(MatMulM2x3M3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix2x3::from_element($target_type::zero())) })),
191          #[cfg(feature = "Matrix2x3")]
192          (Value::$matrix_kind(Matrix::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => Ok(Box::new(MatMulM2x3M3x2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix2::from_element($target_type::zero())) })),
193          #[cfg(feature = "Matrix2x3")]
194          (Value::$matrix_kind(Matrix::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulM2x3MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
195
196          #[cfg(feature = "Matrix3x2")]
197          (Value::$matrix_kind(Matrix::Matrix3x2(lhs)), Value::$matrix_kind(Matrix::Vector2(rhs))) => Ok(Box::new(MatMulM3x2V2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Vector3::from_element($target_type::zero())) })),
198          #[cfg(feature = "Matrix3x2")]
199          (Value::$matrix_kind(Matrix::Matrix3x2(lhs)), Value::$matrix_kind(Matrix::Matrix2(rhs))) => Ok(Box::new(MatMulM3x2M2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix3x2::from_element($target_type::zero())) })),
200          #[cfg(feature = "Matrix3x2")]
201          (Value::$matrix_kind(Matrix::Matrix3x2(lhs)), Value::$matrix_kind(Matrix::Matrix2x3(rhs))) => Ok(Box::new(MatMulM3x2M2x3 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(Matrix3::from_element($target_type::zero())) })),
202          #[cfg(feature = "Matrix3x2")]
203          (Value::$matrix_kind(Matrix::Matrix3x2(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => Ok(Box::new(MatMulM3x2MD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs.borrow().nrows(), rhs.borrow().ncols(), $target_type::zero())) })),
204
205          #[cfg(feature = "MatrixD")]
206          (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::DMatrix(rhs))) => {
207            let (lhs_rows,lhs_cols) = {lhs.borrow().shape()};
208            let (rhs_rows,rhs_cols) = {rhs.borrow().shape()};
209            if lhs_cols != rhs_rows {
210              return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });
211            }
212            Ok(Box::new(MatMulMDMD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs_rows, rhs_cols, $target_type::zero())) }))
213          },
214          #[cfg(feature = "MatrixD")]
215          (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::DVector(rhs))) => {
216            let (lhs_rows,lhs_cols) = {lhs.borrow().shape()};
217            let (rhs_rows,rhs_cols) = {rhs.borrow().shape()};
218            if lhs_cols != rhs_rows {
219              return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });
220            }
221            Ok(Box::new(MatMulMDVD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DVector::from_element(lhs_rows, $target_type::zero())) }))
222          },
223          #[cfg(feature = "MatrixD")]
224          (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::RowDVector(rhs))) => {
225            let (lhs_rows,lhs_cols) = {lhs.borrow().shape()};
226            let (rhs_rows,rhs_cols) = {rhs.borrow().shape()};
227            if lhs_cols != rhs_rows {
228              return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });
229            }
230            Ok(Box::new(MatMulMDRD { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs_rows, rhs_cols, $target_type::zero())) }))
231          },
232          #[cfg(feature = "Matrix3x2")]
233          (Value::$matrix_kind(Matrix::DMatrix(lhs)), Value::$matrix_kind(Matrix::Matrix3x2(rhs))) => {
234            let (lhs_rows,lhs_cols) = {lhs.borrow().shape()};
235            let (rhs_rows,rhs_cols) = {rhs.borrow().shape()};
236            if lhs_cols != rhs_rows {
237              return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });
238            }
239            Ok(Box::new(MatMulMDM3x2 { lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(DMatrix::from_element(lhs_rows, rhs_cols, $target_type::zero())) }))
240          },
241          (Value::$matrix_kind(lhs), Value::$matrix_kind(rhs)) => {
242            let lhs_shape = lhs.shape();
243            let rhs_shape = rhs.shape();
244            return Err(MechError{file: file!().to_string(),  tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::DimensionMismatch(vec![]) });
245          }
246        )+
247      )+
248      x => Err(MechError{file: file!().to_string(),  tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
249    }
250  }
251}
252
253fn impl_matmul_fxn(lhs_value: Value, rhs_value: Value) -> Result<Box<dyn MechFunction>, MechError> {
254  impl_matmul_match_arms!(
255    (lhs_value, rhs_value),
256    I8,   I8   => MatrixI8,   i8, "I8";
257    I16,  I16  => MatrixI16,  i16, "I16";
258    I32,  I32  => MatrixI32,  i32, "I32";
259    I64,  I64  => MatrixI64,  i64, "I64";
260    I128, I128 => MatrixI128, i128, "I128";
261    U8,   U8   => MatrixU8,   u8, "U8";
262    U16,  U16  => MatrixU16,  u16, "U16";
263    U32,  U32  => MatrixU32,  u32, "U32";
264    U64,  U64  => MatrixU64,  u64, "U64";
265    U128, U128 => MatrixU128, u128, "U128";
266    F32,  F32  => MatrixF32,  F32, "F32";
267    F64,  F64  => MatrixF64,  F64, "F64";
268  )
269}
270
271impl_mech_binop_fxn!(MatrixMatMul,impl_matmul_fxn);