mech_interpreter/stdlib/convert/
mat_to_mat.rs

1#[macro_use]
2use crate::stdlib::*;
3
4use nalgebra::{Scalar, Matrix3, Matrix4, DVector, ArrayStorage, Const};
5use std::fmt::Debug;
6use std::ops::{Index, IndexMut};
7use std::marker::PhantomData;
8
9#[derive(Debug)]
10pub struct ConvertMatToMat2<TFrom, TTo, FromMat, ToMat> {
11    pub arg: Ref<FromMat>,
12    pub out: Ref<ToMat>,
13    _marker: PhantomData<(TFrom, TTo)>, 
14}
15
16impl<TFrom, TTo, FromMat, ToMat> MechFunctionImpl for ConvertMatToMat2<TFrom, TTo, FromMat, ToMat>
17where
18    Ref<ToMat>: ToValue,
19    TFrom: LosslessInto<TTo> + Debug + Scalar + Clone,
20    TTo: Debug + Scalar,
21    for<'a> &'a FromMat: IntoIterator<Item = &'a TFrom>,
22    for<'a> &'a mut ToMat: IntoIterator<Item = &'a mut TTo>,
23    FromMat: Debug,
24    ToMat: Debug,
25  {
26    fn solve(&self) {
27      let arg_ptr = self.arg.as_ptr();
28      let out_ptr = self.out.as_mut_ptr();
29      unsafe {
30        let arg_ref: &FromMat = &*arg_ptr;
31        let out_ref: &mut ToMat = &mut *out_ptr;
32        for (dst, src) in (&mut *out_ref).into_iter().zip((&*arg_ref).into_iter()) {
33          *dst = src.clone().lossless_into();
34        }
35      }
36    }
37    fn out(&self) -> Value {self.out.to_value()}
38    fn to_string(&self) -> String { format!("{:#?}",self) }
39  }
40#[cfg(feature = "compiler")]
41impl<TFrom, TTo, FromMat, ToMat> MechFunctionCompiler for ConvertMatToMat2<TFrom, TTo, FromMat, ToMat> 
42where
43  TFrom: ConstElem + CompileConst + AsValueKind,
44  TTo: ConstElem + CompileConst + AsValueKind,
45  FromMat: CompileConst + ConstElem + AsValueKind,
46  ToMat: CompileConst + ConstElem + AsValueKind,
47{
48  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
49    let name = format!("ConvertMatToMat2<{},{}>", FromMat::as_value_kind(), ToMat::as_value_kind());
50    compile_unop!(name, self.out, self.arg, ctx, FeatureFlag::Builtin(FeatureKind::Convert));
51  }
52}
53
54fn create_convert_mat_to_mat<TFrom, TTo>(
55  v: Matrix<TFrom>,
56  shape: &[usize],
57) -> MResult<Box<dyn MechFunction>>
58where
59  #[cfg(feature = "matrix1")]
60  Ref<na::Matrix1<TTo>>: ToValue,
61  #[cfg(feature = "matrix2")]
62  Ref<na::Matrix2<TTo>>: ToValue,
63  #[cfg(feature = "matrix3")]
64  Ref<na::Matrix3<TTo>>: ToValue,
65  #[cfg(feature = "matrix4")]
66  Ref<na::Matrix4<TTo>>: ToValue,
67  #[cfg(feature = "matrix3x2")]
68  Ref<na::Matrix3x2<TTo>>: ToValue,
69  #[cfg(feature = "matrix2x3")]
70  Ref<na::Matrix2x3<TTo>>: ToValue,
71  #[cfg(feature = "row_vector2")]
72  Ref<na::RowVector2<TTo>>: ToValue,
73  #[cfg(feature = "row_vector3")]
74  Ref<na::RowVector3<TTo>>: ToValue,
75  #[cfg(feature = "row_vector4")]
76  Ref<na::RowVector4<TTo>>: ToValue,
77  #[cfg(feature = "vector2")]
78  Ref<na::Vector2<TTo>>: ToValue,
79  #[cfg(feature = "vector3")]
80  Ref<na::Vector3<TTo>>: ToValue,
81  #[cfg(feature = "vector4")]
82  Ref<na::Vector4<TTo>>: ToValue,
83  #[cfg(feature = "vectord")]
84  Ref<na::DVector<TTo>>: ToValue,
85  #[cfg(feature = "row_vectord")]
86  Ref<na::RowDVector<TTo>>: ToValue,
87  #[cfg(feature = "matrixd")]
88  Ref<na::DMatrix<TTo>>: ToValue,
89  TFrom: LosslessInto<TTo> + Debug + Scalar + Clone + ConstElem + CompileConst + AsValueKind,
90  TTo: Debug + Scalar + Default + ConstElem + CompileConst + AsValueKind,
91{
92  let zero = TTo::default();
93  match v {
94    #[cfg(feature = "matrix1")]
95    Matrix::Matrix1(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix1::from_element(zero)), _marker: PhantomData })),
96    #[cfg(feature = "matrix2")]
97    Matrix::Matrix2(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2::from_element(zero)), _marker: PhantomData })),
98    #[cfg(feature = "matrix3")]
99    Matrix::Matrix3(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3::from_element(zero)), _marker: PhantomData })),
100    #[cfg(feature = "matrix4")]
101    Matrix::Matrix4(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix4::from_element(zero)), _marker: PhantomData })),
102    #[cfg(feature = "matrix3x2")]
103    Matrix::Matrix3x2(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3x2::from_element(zero)), _marker: PhantomData })),
104    #[cfg(feature = "matrix2x3")]
105    Matrix::Matrix2x3(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2x3::from_element(zero)), _marker: PhantomData })),
106    #[cfg(feature = "row_vector2")]
107    Matrix::RowVector2(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector2::from_element(zero)), _marker: PhantomData })),
108    #[cfg(feature = "row_vector3")]
109    Matrix::RowVector3(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector3::from_element(zero)), _marker: PhantomData })),
110    #[cfg(feature = "row_vector4")]
111    Matrix::RowVector4(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector4::from_element(zero)), _marker: PhantomData })),
112    #[cfg(feature = "vector2")]
113    Matrix::Vector2(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector2::from_element(zero)), _marker: PhantomData })),
114    #[cfg(feature = "vector3")]
115    Matrix::Vector3(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector3::from_element(zero)), _marker: PhantomData })),
116    #[cfg(feature = "vector4")]
117    Matrix::Vector4(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector4::from_element(zero)), _marker: PhantomData })),
118    #[cfg(feature = "vectord")]
119    Matrix::DVector(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DVector::from_element(shape[0], zero)), _marker: PhantomData })),
120    #[cfg(feature = "row_vectord")]
121    Matrix::RowDVector(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowDVector::from_element(shape[1], zero)), _marker: PhantomData })),
122    #[cfg(feature = "matrixd")]
123    Matrix::DMatrix(v) => Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DMatrix::from_element(shape[0], shape[1], zero)), _marker: PhantomData })),
124    _ => Err(MechError2::new(
125        FeatureNotEnabledError,
126        None
127      ).with_compiler_loc()
128    ),
129  }
130}
131
132fn create_reshape_mat_to_mat<TFrom, TTo>(
133  v: Matrix<TFrom>,
134  shape: &[usize],
135) -> MResult<Box<dyn MechFunction>>
136where
137  #[cfg(feature = "matrix1")]
138  Ref<na::Matrix1<TTo>>: ToValue,
139  #[cfg(feature = "matrix2")]
140  Ref<na::Matrix2<TTo>>: ToValue,
141  #[cfg(feature = "matrix3")]
142  Ref<na::Matrix3<TTo>>: ToValue,
143  #[cfg(feature = "matrix4")]
144  Ref<na::Matrix4<TTo>>: ToValue,
145  #[cfg(feature = "matrix3x2")]
146  Ref<na::Matrix3x2<TTo>>: ToValue,
147  #[cfg(feature = "matrix2x3")]
148  Ref<na::Matrix2x3<TTo>>: ToValue,
149  #[cfg(feature = "row_vector2")]
150  Ref<na::RowVector2<TTo>>: ToValue,
151  #[cfg(feature = "row_vector3")]
152  Ref<na::RowVector3<TTo>>: ToValue,
153  #[cfg(feature = "row_vector4")]
154  Ref<na::RowVector4<TTo>>: ToValue,
155  #[cfg(feature = "vector2")]
156  Ref<na::Vector2<TTo>>: ToValue,
157  #[cfg(feature = "vector3")]
158  Ref<na::Vector3<TTo>>: ToValue,
159  #[cfg(feature = "vector4")]
160  Ref<na::Vector4<TTo>>: ToValue,
161  #[cfg(feature = "vectord")]
162  Ref<na::DVector<TTo>>: ToValue,
163  #[cfg(feature = "row_vectord")]
164  Ref<na::RowDVector<TTo>>: ToValue,
165  #[cfg(feature = "matrixd")]
166  Ref<na::DMatrix<TTo>>: ToValue,
167  TFrom: LosslessInto<TTo> + Debug + Scalar + Clone + ConstElem + CompileConst + AsValueKind,
168  TTo: Debug + Scalar + Default + ConstElem + CompileConst + AsValueKind,
169{
170  let zero = TTo::default();
171  let dims = v.shape();
172  match (v,shape[0],shape[1]) {
173    #[cfg(all(feature = "matrix2", feature = "row_vector4"))]
174    (Matrix::Matrix2(v), 1, 4) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(RowVector4::from_element(zero)), _marker: PhantomData}));},
175    #[cfg(all(feature = "matrix2", feature = "vector4"))]
176    (Matrix::Matrix2(v), 4, 1) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(Vector4::from_element(zero)), _marker: PhantomData}));},
177
178    #[cfg(all(feature = "matrix3", feature = "row_vectord"))]
179    (Matrix::Matrix3(v), 1, 9) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(RowDVector::from_element(9, zero)), _marker: PhantomData}));},
180    #[cfg(all(feature = "matrix3", feature = "vectord"))]
181    (Matrix::Matrix3(v), 9, 1) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(DVector::from_element(9, zero)), _marker: PhantomData}));},
182
183    #[cfg(all(feature = "matrix4", feature = "row_vectord"))]
184    (Matrix::Matrix4(v), 1, 16) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(RowDVector::from_element(16, zero)), _marker: PhantomData}));},
185    #[cfg(all(feature = "matrix4", feature = "vectord"))]
186    (Matrix::Matrix4(v), 16, 1) => {return Ok(Box::new(ConvertMatToMat2 {arg: v,out: Ref::new(DVector::from_element(16, zero)), _marker: PhantomData}));},
187    
188    #[cfg(all(feature = "matrix3x2", feature = "row_vectord"))]
189    (Matrix::Matrix3x2(v), 1, 6) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowDVector::from_element(6, zero)), _marker: PhantomData })); },
190    #[cfg(all(feature = "matrix3x2", feature = "vectord"))]
191    (Matrix::Matrix3x2(v), 6, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DVector::from_element(6, zero)), _marker: PhantomData })); },
192    #[cfg(all(feature = "matrix3x2", feature = "matrix2x3"))]
193    (Matrix::Matrix3x2(v), 2, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2x3::from_element(zero)), _marker: PhantomData })); },
194
195    #[cfg(all(feature = "matrix2x3", feature = "row_vectord"))]
196    (Matrix::Matrix2x3(v), 1, 6) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowDVector::from_element(6, zero)), _marker: PhantomData })); },
197    #[cfg(all(feature = "matrix2x3", feature = "vectord"))]
198    (Matrix::Matrix2x3(v), 6, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DVector::from_element(6, zero)), _marker: PhantomData })); },
199    #[cfg(all(feature = "matrix2x3", feature = "matrix3x2"))]
200    (Matrix::Matrix2x3(v), 3, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3x2::from_element(zero)), _marker: PhantomData })); },
201
202    #[cfg(all(feature = "vector2", feature = "row_vector2"))]
203    (Matrix::Vector2(v), 1, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector2::from_element(zero)), _marker: PhantomData })); },
204    #[cfg(all(feature = "vector3", feature = "row_vector3"))]
205    (Matrix::Vector3(v), 1, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector3::from_element(zero)), _marker: PhantomData })); },
206    
207    #[cfg(all(feature = "vector4", feature = "row_vector4"))]
208    (Matrix::Vector4(v), 1, 4) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowVector4::from_element(zero)), _marker: PhantomData })); },
209    #[cfg(all(feature = "vector4", feature = "matrix2"))]
210    (Matrix::Vector4(v), 2, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2::from_element(zero)), _marker: PhantomData })); },
211
212    #[cfg(all(feature = "row_vector2", feature = "vector2"))]
213    (Matrix::RowVector2(v), 2, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector2::from_element(zero)), _marker: PhantomData })); },
214    #[cfg(all(feature = "row_vector3", feature = "vector3"))]
215    (Matrix::RowVector3(v), 3, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector3::from_element(zero)), _marker: PhantomData })); },
216    
217    #[cfg(all(feature = "row_vector4", feature = "vector4"))]
218    (Matrix::RowVector4(v), 4, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Vector4::from_element(zero)), _marker: PhantomData })); },
219    #[cfg(all(feature = "row_vector4", feature = "matrix2"))]
220    (Matrix::RowVector4(v), 2, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2::from_element(zero)), _marker: PhantomData })); },
221    
222    #[cfg(all(feature = "row_vectord", feature = "matrix3"))]
223    (Matrix::RowDVector(v), 3, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3::from_element(zero)), _marker: PhantomData })); },
224    #[cfg(all(feature = "row_vectord", feature = "matrix4"))]
225    (Matrix::RowDVector(v), 4, 4) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix4::from_element(zero)), _marker: PhantomData })); },
226    #[cfg(all(feature = "row_vectord", feature = "matrix2x3"))]
227    (Matrix::RowDVector(v), 2, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2x3::from_element(zero)), _marker: PhantomData })); },
228    #[cfg(all(feature = "row_vectord", feature = "matrix3x2"))]
229    (Matrix::RowDVector(v), 3, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3x2::from_element(zero)), _marker: PhantomData })); },
230    #[cfg(all(feature = "row_vectord", feature = "vectord"))]
231    (Matrix::RowDVector(v), n, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DVector::from_element(n, zero)), _marker: PhantomData })); },
232    #[cfg(all(feature = "row_vectord", feature = "matrixd"))]
233    (Matrix::RowDVector(v), n, m) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DMatrix::from_element(n, m, zero)), _marker: PhantomData })); },
234    
235    #[cfg(all(feature = "vectord", feature = "matrix3"))]
236    (Matrix::DVector(v), 3, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3::from_element(zero)), _marker: PhantomData })); },
237    #[cfg(all(feature = "vectord", feature = "matrix4"))]
238    (Matrix::DVector(v), 4, 4) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix4::from_element(zero)), _marker: PhantomData })); },
239    #[cfg(all(feature = "vectord", feature = "matrix3x2"))]
240    (Matrix::DVector(v), 3, 2) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix3x2::from_element(zero)), _marker: PhantomData })); },
241    #[cfg(all(feature = "vectord", feature = "matrix2x3"))]
242    (Matrix::DVector(v), 2, 3) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(Matrix2x3::from_element(zero)), _marker: PhantomData })); },
243    #[cfg(all(feature = "vectord", feature = "row_vectord"))]
244    (Matrix::DVector(v), 1, n) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowDVector::from_element(n, zero)), _marker: PhantomData })); },
245    #[cfg(all(feature = "vectord", feature = "matrixd"))]
246    (Matrix::DVector(v), n, m) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DMatrix::from_element(n, m, zero)), _marker: PhantomData })); },
247    
248    #[cfg(all(feature = "matrixd", feature = "vectord"))]
249    (Matrix::DMatrix(v), n, 1) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DVector::from_element(n, zero)), _marker: PhantomData })); },
250    #[cfg(all(feature = "matrixd", feature = "row_vectord"))]
251    (Matrix::DMatrix(v), 1, n) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(RowDVector::from_element(n, zero)), _marker: PhantomData })); },
252    #[cfg(feature = "matrixd")]
253    (Matrix::DMatrix(v), n, m) => { return Ok(Box::new(ConvertMatToMat2 { arg: v, out: Ref::new(DMatrix::from_element(n, m, zero)), _marker: PhantomData })); },
254    _ => {
255      return Err(MechError2::new(
256        ReshapeError { original: (dims[0], dims[1]), requested: (shape[0], shape[1]) },
257        None
258      ).with_compiler_loc());
259    }
260  }
261}
262
263macro_rules! impl_conversion_mat_to_mat_fxn {
264  (
265    $(
266      $src:tt, $src_string:tt => [ $( $dst:tt, $dst_string:tt ),+ $(,)? ]
267    );+ $(;)?
268  ) => {
269    pub fn impl_conversion_mat_to_mat_fxn(
270      source_value: Value,
271      target_kind: ValueKind
272    ) -> MResult<Box<dyn MechFunction>> {
273      let shape = source_value.shape();
274
275      paste::paste! {
276        match (source_value.clone(), target_kind.clone()) {
277          $(
278            $(
279              #[cfg(all(feature = "matrix", feature = $src_string, feature = $dst_string))]
280              (Value::[<Matrix $src:camel>](v), ValueKind::Matrix(box ValueKind::[<$dst:camel>], dims)) => {
281                if dims.is_empty() { 
282                  create_convert_mat_to_mat::<$src, $dst>(v, &shape)
283                } else if ((shape[0] == dims[0]) && (shape[1] == dims[1])) {
284                  create_convert_mat_to_mat::<$src, $dst>(v, &dims)
285                } else if shape[0] * shape[1] == dims[0] * dims[1] {
286                  create_reshape_mat_to_mat::<$src, $dst>(v, &dims)
287                } else {
288                  Err(MechError2::new(UnsupportedConversionError{from: source_value.kind(), to: target_kind.clone()}, None).with_compiler_loc())
289                }
290              }
291            )+
292          )+
293          _ => Err(MechError2::new(UnsupportedConversionError{from: source_value.kind(), to: target_kind.clone()}, None).with_compiler_loc()),
294        }
295      }
296    }
297  };
298}
299
300#[cfg(not(target_arch = "wasm32"))]
301impl_conversion_mat_to_mat_fxn! {
302  f64, "f64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128", R64, "rational"];
303  f32, "f32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128", R64, "rational"];
304  u8,  "u8"  => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
305  u16, "u16" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
306  u32, "u32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
307  u64, "u64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
308  u128,"u128"=> [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
309  i8,  "i8"  => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
310  i16, "i16" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
311  i32, "i32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
312  i64, "i64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
313  i128,"i128"=> [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", u128, "u128", i8, "i8", i16, "i16", i32, "i32", i64, "i64", i128, "i128"];
314  String, "string" => [String, "string"];
315  R64, "rational" => [String, "string"];
316  C64, "complex" => [String, "string"];
317}
318
319
320#[cfg(target_arch = "wasm32")]
321impl_conversion_mat_to_mat_fxn! {
322  f64, "f64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64", R64, "rational"];
323  f32, "f32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64", R64, "rational"];
324  u8,  "u8"  => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
325  u16, "u16" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
326  u32, "u32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
327  u64, "u64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
328  i8,  "i8"  => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
329  i16, "i16" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
330  i32, "i32" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
331  i64, "i64" => [String, "string", f64, "f64", f32, "f32", u8, "u8", u16, "u16", u32, "u32", u64, "u64", i8, "i8", i16, "i16", i32, "i32", i64, "i64"];
332  String, "string" => [String, "string"];
333  R64, "rational" => [String, "string"];
334  C64, "complex" => [String, "string"];
335}
336
337pub struct ConvertMatToMat {}
338
339impl NativeFunctionCompiler for ConvertMatToMat {
340  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
341    if arguments.len() != 2 {
342      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 2, found: arguments.len() }, None).with_compiler_loc());
343    }
344    let source_value = arguments[0].clone();
345    let source_kind = source_value.kind();
346    let target_kind = arguments[1].kind();
347    match impl_conversion_mat_to_mat_fxn(source_value.clone(), target_kind.clone()) {
348      Ok(fxn) => Ok(fxn),
349      Err(_) => {
350        match source_value {
351          Value::MutableReference(rhs) => impl_conversion_mat_to_mat_fxn(rhs.borrow().clone(), target_kind.clone()),
352          x => Err(MechError2::new(
353              UnhandledFunctionArgumentKind2 { arg: (arguments[0].kind(), arguments[1].kind()), fxn_name: "convert/mat-to-mat".to_string() },
354              None
355            ).with_compiler_loc()
356          ),
357        }
358      }
359    }
360  }
361}
362
363
364
365#[derive(Debug, Clone)]
366pub struct ReshapeError {
367  pub requested: (usize, usize),
368  pub original: (usize, usize),
369}
370impl MechErrorKind2 for ReshapeError {
371  fn name(&self) -> &str { "ReshapeError" }
372  fn message(&self) -> String {
373    format!("Cannot reshape matrix of shape {:?} into {:?}",self.original,self.requested)
374  }
375}