mech_interpreter/stdlib/
vertcat.rs

1#[macro_use]
2use crate::stdlib::*;
3
4// Vertical Concatenate -----------------------------------------------------
5
6macro_rules! vertcat_one_arg {
7  ($fxn:ident, $e0:ident, $out:ident, $opt:ident) => {
8    #[derive(Debug)]
9    struct $fxn<T> {
10      e0: Ref<$e0<T>>,
11      out: Ref<$out<T>>,
12    }
13    impl<T> MechFunctionImpl for $fxn<T>
14    where
15      T: Debug + Clone + Sync + Send + PartialEq + 'static,
16      Ref<$out<T>>: ToValue
17    {
18      fn solve(&self) { 
19        unsafe {
20          let e0_ptr = (*(self.e0.as_ptr())).clone();
21          let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
22          $opt!(out_ptr,e0_ptr);
23        }
24      }
25      fn out(&self) -> Value { self.out.to_value() }
26      fn to_string(&self) -> String { format!("{:#?}", self) }
27    }
28    #[cfg(feature = "compiler")]
29    impl<T> MechFunctionCompiler for $fxn<T> {
30      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
31        todo!();
32      }
33    }
34  };}
35
36macro_rules! vertcat_two_args {
37  ($fxn:ident, $e1:ident, $e2:ident, $out:ident, $opt:ident) => {
38    #[derive(Debug)]
39    struct $fxn<T> {
40      e0: Ref<$e1<T>>,
41      e1: Ref<$e2<T>>,
42      out: Ref<$out<T>>,
43    }
44    impl<T> MechFunctionImpl for $fxn<T>
45    where
46      T: Debug + Clone + Sync + Send + PartialEq + 'static,
47      Ref<$out<T>>: ToValue
48    {
49      fn solve(&self) { 
50        unsafe {
51          let e0_ptr = (*(self.e0.as_ptr())).clone();
52          let e1_ptr = (*(self.e1.as_ptr())).clone();
53          let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
54          $opt!(out_ptr,e0_ptr,e1_ptr);
55        }
56      }
57      fn out(&self) -> Value { self.out.to_value() }
58      fn to_string(&self) -> String { format!("{:#?}", self) }
59    }
60    #[cfg(feature = "compiler")]
61    impl<T> MechFunctionCompiler for $fxn<T> {
62      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
63        todo!();
64      }
65    }
66  };}
67
68macro_rules! vertcat_three_args {
69  ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $out:ident, $opt:ident) => {
70    #[derive(Debug)]
71    struct $fxn<T> {
72      e0: Ref<$e0<T>>,
73      e1: Ref<$e1<T>>,
74      e2: Ref<$e2<T>>,
75      out: Ref<$out<T>>,
76    }
77    impl<T> MechFunctionImpl for $fxn<T>
78    where
79      T: Debug + Clone + Sync + Send + PartialEq + 'static,
80      Ref<$out<T>>: ToValue
81    {
82      fn solve(&self) { 
83        unsafe {
84          let e0_ptr = (*(self.e0.as_ptr())).clone();
85          let e1_ptr = (*(self.e1.as_ptr())).clone();
86          let e2_ptr = (*(self.e2.as_ptr())).clone();
87          let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
88          $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr);
89        }
90      }
91      fn out(&self) -> Value { self.out.to_value() }
92      fn to_string(&self) -> String { format!("{:#?}", self) }
93    }
94    #[cfg(feature = "compiler")]
95    impl<T> MechFunctionCompiler for $fxn<T> {
96      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
97        todo!();
98      }
99    }
100  };} 
101  
102macro_rules! vertcat_four_args {
103  ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $e3:ident, $out:ident, $opt:ident) => {
104    #[derive(Debug)]
105    struct $fxn<T> {
106      e0: Ref<$e0<T>>,
107      e1: Ref<$e1<T>>,
108      e2: Ref<$e2<T>>,
109      e3: Ref<$e3<T>>,
110      out: Ref<$out<T>>,
111    }
112    impl<T> MechFunctionImpl for $fxn<T>
113    where
114      T: Debug + Clone + Sync + Send + PartialEq + 'static,
115      Ref<$out<T>>: ToValue
116    {
117      fn solve(&self) { 
118        unsafe {
119          let e0_ptr = (*(self.e0.as_ptr())).clone();
120          let e1_ptr = (*(self.e1.as_ptr())).clone();
121          let e2_ptr = (*(self.e2.as_ptr())).clone();
122          let e3_ptr = (*(self.e3.as_ptr())).clone();
123          let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
124          $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr,e3_ptr);
125        }
126      }
127      fn out(&self) -> Value { self.out.to_value() }
128      fn to_string(&self) -> String { format!("{:#?}", self) }
129    }
130    #[cfg(feature = "compiler")]
131    impl<T> MechFunctionCompiler for $fxn<T> {
132      fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
133        todo!();
134      }
135    }
136  };}   
137
138struct VerticalConcatenateTwoArgs<T> {
139  e0: Box<dyn CopyMat<T>>,
140  e1: Box<dyn CopyMat<T>>,
141  out: Ref<DMatrix<T>>,
142}
143impl<T> MechFunctionImpl for VerticalConcatenateTwoArgs<T>
144where
145  T: Debug + Clone + Sync + Send + PartialEq + 'static,
146  Ref<DMatrix<T>>: ToValue
147{
148  fn solve(&self) {
149    let offset = self.e0.copy_into_row_major(&self.out,0);
150    self.e1.copy_into_row_major(&self.out,offset);
151  }
152  fn out(&self) -> Value { self.out.to_value() }
153  fn to_string(&self) -> String { format!("VerticalConcatenateTwoArgs\n{:#?}", self.out) }
154}
155#[cfg(feature = "compiler")]
156impl<T> MechFunctionCompiler for VerticalConcatenateTwoArgs<T> {
157  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
158    todo!();
159  }
160}
161    
162struct VerticalConcatenateThreeArgs<T> {
163  e0: Box<dyn CopyMat<T>>,
164  e1: Box<dyn CopyMat<T>>,
165  e2: Box<dyn CopyMat<T>>,
166  out: Ref<DMatrix<T>>,
167}
168impl<T> MechFunctionImpl for VerticalConcatenateThreeArgs<T>
169where
170  T: Debug + Clone + Sync + Send + PartialEq + 'static,
171  Ref<DMatrix<T>>: ToValue
172{
173  fn solve(&self) {
174    let mut offset = self.e0.copy_into_row_major(&self.out,0);
175    offset += self.e1.copy_into_row_major(&self.out,offset);
176    self.e2.copy_into_row_major(&self.out,offset);
177  }
178  fn out(&self) -> Value { self.out.to_value() }
179  fn to_string(&self) -> String { format!("VerticalConcatenateThreeArgs\n{:#?}", self.out) }
180}
181#[cfg(feature = "compiler")]
182impl<T> MechFunctionCompiler for VerticalConcatenateThreeArgs<T> {
183  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
184    todo!();
185  }
186}
187
188struct VerticalConcatenateFourArgs<T> {
189  e0: Box<dyn CopyMat<T>>,
190  e1: Box<dyn CopyMat<T>>,
191  e2: Box<dyn CopyMat<T>>,
192  e3: Box<dyn CopyMat<T>>,
193  out: Ref<DMatrix<T>>,
194}
195impl<T> MechFunctionImpl for VerticalConcatenateFourArgs<T>
196where
197  T: Debug + Clone + Sync + Send + PartialEq + 'static,
198  Ref<DMatrix<T>>: ToValue
199{
200  fn solve(&self) {
201    let mut offset = self.e0.copy_into_row_major(&self.out,0);
202    offset += self.e1.copy_into_row_major(&self.out,offset);
203    offset += self.e2.copy_into_row_major(&self.out,offset);
204    self.e3.copy_into_row_major(&self.out,offset);
205
206  }
207  fn out(&self) -> Value { self.out.to_value() }
208  fn to_string(&self) -> String { format!("VerticalConcatenateFourArgs\n{:#?}", self.out) }
209}
210#[cfg(feature = "compiler")]
211impl<T> MechFunctionCompiler for VerticalConcatenateFourArgs<T> {
212  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
213    todo!();
214  }
215}
216
217struct VerticalConcatenateNArgs<T> {
218  e0: Vec<Box<dyn CopyMat<T>>>,
219  out: Ref<DMatrix<T>>,
220}
221impl<T> MechFunctionImpl for VerticalConcatenateNArgs<T>
222where
223  T: Debug + Clone + Sync + Send + PartialEq + 'static,
224  Ref<DMatrix<T>>: ToValue
225{
226  fn solve(&self) {
227    let mut offset = 0;
228    for e in &self.e0 {
229      offset += e.copy_into_row_major(&self.out,offset);
230    }
231  }
232  fn out(&self) -> Value { self.out.to_value() }
233  fn to_string(&self) -> String { format!("VerticalConcatenateNArgs\n{:#?}", self.out) }
234}
235#[cfg(feature = "compiler")]
236impl<T> MechFunctionCompiler for VerticalConcatenateNArgs<T> {
237  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
238    todo!();
239  }
240}
241
242macro_rules! vertical_concatenate {
243  ($name:ident, $vec_size:expr) => {
244    paste!{
245      #[derive(Debug)]
246      struct $name<T> {
247        out: Ref<[<$vec_size>]<T>>,
248      }
249
250      impl<T> MechFunctionImpl for $name<T> 
251      where
252        T: Debug + Clone + Sync + Send + PartialEq + 'static,
253        Ref<[<$vec_size>]<T>>: ToValue
254      {
255        fn solve(&self) {}
256        fn out(&self) -> Value { self.out.to_value() }
257        fn to_string(&self) -> String { format!("{:#?}", self) }
258      }
259      #[cfg(feature = "compiler")]
260      impl<T> MechFunctionCompiler for $name<T> {
261        fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
262          todo!();
263        }
264      }
265    }
266  };}  
267
268struct VerticalConcatenateVD2<T> {
269  e0: Box<dyn CopyMat<T>>,
270  e1: Box<dyn CopyMat<T>>,
271  out: Ref<DVector<T>>,
272}
273
274impl<T> MechFunctionImpl for VerticalConcatenateVD2<T> 
275where
276  T: Debug + Clone + Sync + Send + PartialEq + 'static,
277  Ref<DVector<T>>: ToValue
278{
279  fn solve(&self) {   
280    let mut offset = self.e0.copy_into_v(&self.out,0);
281    self.e1.copy_into_v(&self.out,offset);
282  }
283  fn out(&self) -> Value { self.out.to_value() }
284  fn to_string(&self) -> String { format!("VerticalConcatenateVD2\n{:#?}", self.out) }
285}
286#[cfg(feature = "compiler")]
287impl<T> MechFunctionCompiler for VerticalConcatenateVD2<T> {
288  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
289    todo!();
290  }
291}
292
293struct VerticalConcatenateVD3<T> {
294  e0: Box<dyn CopyMat<T>>,
295  e1: Box<dyn CopyMat<T>>,
296  e2: Box<dyn CopyMat<T>>,
297  out: Ref<DVector<T>>,
298}
299
300impl<T> MechFunctionImpl for VerticalConcatenateVD3<T>
301where
302  T: Debug + Clone + Sync + Send + PartialEq + 'static,
303  Ref<DVector<T>>: ToValue
304{
305  fn solve(&self) {   
306    let mut offset = self.e0.copy_into_v(&self.out,0);
307    offset += self.e1.copy_into_v(&self.out,offset);
308    self.e2.copy_into_v(&self.out,offset);
309  }
310  fn out(&self) -> Value { self.out.to_value() }
311  fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
312}
313
314#[cfg(feature = "compiler")]
315impl<T> MechFunctionCompiler for VerticalConcatenateVD3<T> {
316  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
317    todo!();
318  }
319}
320
321struct VerticalConcatenateVD4<T> {
322  e0: Box<dyn CopyMat<T>>,
323  e1: Box<dyn CopyMat<T>>,
324  e2: Box<dyn CopyMat<T>>,
325  e3: Box<dyn CopyMat<T>>,
326  out: Ref<DVector<T>>,
327}
328
329impl<T> MechFunctionImpl for VerticalConcatenateVD4<T>
330where
331  T: Debug + Clone + Sync + Send + PartialEq + 'static,
332  Ref<DVector<T>>: ToValue
333{
334  fn solve(&self) {   
335    let mut offset = self.e0.copy_into_v(&self.out,0);
336    offset += self.e1.copy_into_v(&self.out,offset);
337    offset += self.e2.copy_into_v(&self.out,offset);
338    self.e3.copy_into_v(&self.out,offset);
339  }
340  fn out(&self) -> Value { self.out.to_value() }
341  fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
342}
343#[cfg(feature = "compiler")]
344impl<T> MechFunctionCompiler for VerticalConcatenateVD4<T> {
345  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
346    todo!();
347  }
348}
349
350struct VerticalConcatenateVDN<T> {
351  scalar: Vec<(Ref<T>,usize)>,
352  matrix: Vec<(Box<dyn CopyMat<T>>,usize)>,
353  out: Ref<DVector<T>>,
354}
355
356impl<T> MechFunctionImpl for VerticalConcatenateVDN<T>
357where
358  T: Debug + Clone + Sync + Send + PartialEq + 'static,
359  Ref<DVector<T>>: ToValue
360{
361  fn solve(&self) {
362    unsafe {
363      let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
364      for (e,i) in &self.matrix {
365        e.copy_into_v(&self.out,*i);
366      }
367      for (e,i) in &self.scalar {
368        out_ptr[*i] = e.borrow().clone();
369      }
370    }
371  }
372  fn out(&self) -> Value { self.out.to_value() }
373  fn to_string(&self) -> String { format!("VerticalConcatenateVDN\n{:#?}", self.out) }
374}
375#[cfg(feature = "compiler")]
376impl<T> MechFunctionCompiler for VerticalConcatenateVDN<T> {
377  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
378    todo!();
379  }
380}
381
382#[cfg(feature = "matrix1")]
383#[derive(Debug)]
384struct VerticalConcatenateS1<T> {
385  out: Ref<Matrix1<T>>,
386}
387
388#[cfg(feature = "matrix1")]
389impl<T> MechFunctionImpl for VerticalConcatenateS1<T>
390where
391  T: Debug + Clone + Sync + Send + PartialEq + 'static,
392  Ref<Matrix1<T>>: ToValue
393{
394  fn solve(&self) {}
395  fn out(&self) -> Value { self.out.to_value() }
396  fn to_string(&self) -> String { format!("{:#?}", self) }
397}
398
399#[cfg(all(feature = "matrix1", feature = "compiler"))]
400impl<T> MechFunctionCompiler for VerticalConcatenateS1<T> {
401  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
402    todo!();
403  }
404}
405
406#[cfg(feature = "vector2")]
407vertical_concatenate!(VerticalConcatenateS2,Vector2);
408#[cfg(feature = "vector3")]
409vertical_concatenate!(VerticalConcatenateS3,Vector3);
410#[cfg(feature = "vector4")]
411vertical_concatenate!(VerticalConcatenateS4,Vector4);
412#[cfg(feature = "vector2")]
413vertical_concatenate!(VerticalConcatenateV2,Vector2);
414#[cfg(feature = "vector3")]
415vertical_concatenate!(VerticalConcatenateV3,Vector3);
416#[cfg(feature = "vector4")]
417vertical_concatenate!(VerticalConcatenateV4,Vector4);
418#[cfg(feature = "matrix2")]
419vertical_concatenate!(VerticalConcatenateM2,Matrix2);
420#[cfg(feature = "matrix3")]
421vertical_concatenate!(VerticalConcatenateM3,Matrix3);
422#[cfg(feature = "matrix2x3")]
423vertical_concatenate!(VerticalConcatenateM2x3,Matrix2x3);
424#[cfg(feature = "matrix3x2")]
425vertical_concatenate!(VerticalConcatenateM3x2,Matrix3x2);
426#[cfg(feature = "matrix4")]
427vertical_concatenate!(VerticalConcatenateM4,Matrix4);
428#[cfg(feature = "matrixd")]
429vertical_concatenate!(VerticalConcatenateMD,DMatrix);
430#[cfg(feature = "vectord")]
431vertical_concatenate!(VerticalConcatenateVD,DVector);
432
433#[cfg(feature = "vectord")]
434#[derive(Debug)]
435struct VerticalConcatenateSD<T> {
436  out: Ref<DVector<T>>,
437}
438#[cfg(feature = "vectord")]
439impl<T> MechFunctionImpl for VerticalConcatenateSD<T>
440where
441  T: Debug + Clone + Sync + Send + PartialEq + 'static,
442  Ref<DVector<T>>: ToValue
443{
444  fn solve(&self) { }
445  fn out(&self) -> Value { self.out.to_value() }
446  fn to_string(&self) -> String { format!("{:#?}", self) }
447}
448#[cfg(all(feature = "vectord", feature = "compiler"))]
449impl<T> MechFunctionCompiler for VerticalConcatenateSD<T> {
450  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
451    todo!();
452  }
453}
454
455macro_rules! vertcat_m1m1 {
456  ($out:expr, $e0:expr, $e1:expr) => {
457    $out[0] = $e0[0].clone();
458    $out[1] = $e1[0].clone();
459  };}
460#[cfg(feature = "matrix1")]
461vertcat_two_args!(VerticalConcatenateM1M1,Matrix1,Matrix1,Vector2,vertcat_m1m1);
462
463macro_rules! vertcat_r2r2 {
464  ($out:expr, $e0:expr, $e1:expr) => {
465    $out[0] = $e0[0].clone();
466    $out[1] = $e0[1].clone();
467    $out[2] = $e1[0].clone();
468    $out[3] = $e1[1].clone();
469  };}
470#[cfg(feature = "vector2")]
471vertcat_two_args!(VerticalConcatenateV2V2,Vector2,Vector2,Vector4,vertcat_r2r2);
472
473macro_rules! vertcat_m1r3 {
474  ($out:expr, $e0:expr, $e1:expr) => {
475    $out[0] = $e0[0].clone();
476    $out[1] = $e1[0].clone();
477    $out[2] = $e1[1].clone();
478    $out[3] = $e1[2].clone();
479  };}
480#[cfg(all(feature = "matrix1", feature = "vector3", feature = "vector4"))]
481vertcat_two_args!(VerticalConcatenateM1V3,Matrix1,Vector3,Vector4,vertcat_m1r3);
482
483macro_rules! vertcat_r3m1 {
484  ($out:expr, $e0:expr, $e1:expr) => {
485    $out[0] = $e0[0].clone();
486    $out[1] = $e0[1].clone();
487    $out[2] = $e0[2].clone();
488    $out[3] = $e1[0].clone();
489  };}
490#[cfg(all(feature = "vector3", feature = "matrix1", feature = "vector4"))]
491vertcat_two_args!(VerticalConcatenateV3M1,Vector3,Matrix1,Vector4,vertcat_r3m1);
492
493macro_rules! vertcat_m1r2 {
494  ($out:expr, $e0:expr, $e1:expr) => {
495    $out[0] = $e0[0].clone();
496    $out[1] = $e1[0].clone();
497    $out[2] = $e1[1].clone();
498  };
499}
500#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector3"))]
501vertcat_two_args!(VerticalConcatenateM1V2, Matrix1, Vector2, Vector3, vertcat_m1r2);
502
503macro_rules! vertcat_r2m1 {
504  ($out:expr, $e0:expr, $e1:expr) => {
505    $out[0] = $e0[0].clone();
506    $out[1] = $e0[1].clone();
507    $out[2] = $e1[0].clone();
508  };
509}
510#[cfg(all(feature = "vector2", feature = "matrix1", feature = "vector3"))]
511vertcat_two_args!(VerticalConcatenateV2M1, Vector2, Matrix1, Vector3, vertcat_r2m1);
512
513macro_rules! vertcat_m1m1m1 {
514  ($out:expr, $e0:expr,$e1:expr,$e2:expr) => {
515    $out[0] = $e0[0].clone();
516    $out[1] = $e1[0].clone();
517    $out[2] = $e2[0].clone();
518  };
519}
520#[cfg(all(feature = "matrix1", feature = "vector3"))]
521vertcat_three_args!(VerticalConcatenateM1M1M1,Matrix1,Matrix1,Matrix1,Vector3, vertcat_m1m1m1);
522
523macro_rules! vertcat_m1m1r2 {
524  ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
525    $out[0] = $e0[0].clone();
526    $out[1] = $e1[0].clone();
527    $out[2] = $e2[0].clone();
528    $out[3] = $e2[1].clone();
529  };
530}
531#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
532vertcat_three_args!(VerticalConcatenateM1M1V2, Matrix1, Matrix1, Vector2, Vector4, vertcat_m1m1r2);
533
534macro_rules! vertcat_m1r2m1 {
535  ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
536    $out[0] = $e0[0].clone();
537    $out[1] = $e1[0].clone();
538    $out[2] = $e1[1].clone();
539    $out[3] = $e2[0].clone();
540  };
541}
542#[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
543vertcat_three_args!(VerticalConcatenateM1V2M1, Matrix1, Vector2, Matrix1, Vector4, vertcat_m1r2m1);
544
545macro_rules! vertcat_r2m1m1 {
546  ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
547    $out[0] = $e0[0].clone();
548    $out[1] = $e0[1].clone();
549    $out[2] = $e1[0].clone();
550    $out[3] = $e2[0].clone();
551  };
552}
553#[cfg(all(feature = "vector2", feature = "matrix1", feature = "vector4"))]
554vertcat_three_args!(VerticalConcatenateV2M1M1, Vector2, Matrix1, Matrix1, Vector4, vertcat_r2m1m1);
555
556#[cfg(all(feature = "matrix1", feature = "vector4"))]
557#[derive(Debug)]
558struct VerticalConcatenateM1M1M1M1<T> {
559  e0: Ref<Matrix1<T>>,
560  e1: Ref<Matrix1<T>>,
561  e2: Ref<Matrix1<T>>,
562  e3: Ref<Matrix1<T>>,
563  out: Ref<Vector4<T>>,
564}
565#[cfg(all(feature = "matrix1", feature = "vector4"))]
566impl<T> MechFunctionImpl for VerticalConcatenateM1M1M1M1<T>
567where
568  T: Debug + Clone + Sync + Send + PartialEq + 'static,
569  Ref<Vector4<T>>: ToValue
570{
571  fn solve(&self) { 
572    unsafe {
573      let e0_ptr = (*(self.e0.as_ptr())).clone();
574      let e1_ptr = (*(self.e1.as_ptr())).clone();
575      let e2_ptr = (*(self.e2.as_ptr())).clone();
576      let e3_ptr = (*(self.e3.as_ptr())).clone();
577      let mut out_ptr = (&mut *(self.out.as_mut_ptr()));
578      out_ptr[0] = e0_ptr[0].clone();
579      out_ptr[1] = e1_ptr[0].clone();
580      out_ptr[2] = e2_ptr[0].clone();
581      out_ptr[3] = e3_ptr[0].clone();
582    }
583  }
584  fn out(&self) -> Value { self.out.to_value() }
585  fn to_string(&self) -> String { format!("{:#?}", self) }
586}
587#[cfg(all(feature = "matrix1", feature = "vector4", feature = "compiler"))]
588impl<T> MechFunctionCompiler for VerticalConcatenateM1M1M1M1<T> {
589  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
590    todo!();
591  }
592}
593
594macro_rules! vertcat_r2r2 {
595  ($out:expr, $e0:expr, $e1:expr) => {
596    $out[0] = $e0[0].clone();
597    $out[2] = $e0[1].clone();
598    $out[1] = $e1[0].clone();
599    $out[3] = $e1[1].clone();
600  };
601}
602#[cfg(all(feature = "row_vector2", feature = "matrix2"))]
603vertcat_two_args!(VerticalConcatenateR2R2, RowVector2, RowVector2, Matrix2, vertcat_r2r2);
604
605macro_rules! vertcat_r3r3 {
606  ($out:expr, $e0:expr, $e1:expr) => {
607    $out[0] = $e0[0].clone();
608    $out[2] = $e0[1].clone();
609    $out[4] = $e0[2].clone();
610    $out[1] = $e1[0].clone();
611    $out[3] = $e1[1].clone();
612    $out[5] = $e1[2].clone();
613  };
614}
615#[cfg(all(feature = "row_vector3", feature = "matrix2x3"))]
616vertcat_two_args!(VerticalConcatenateR3R3, RowVector3, RowVector3, Matrix2x3, vertcat_r3r3);
617
618macro_rules! vertcat_r2m2 {
619  ($out:expr, $e0:expr, $e1:expr) => {
620    $out[0] = $e0[0].clone();
621    $out[3] = $e0[1].clone();
622    $out[1] = $e1[0].clone();
623    $out[2] = $e1[1].clone();
624    $out[4] = $e1[2].clone();
625    $out[5] = $e1[3].clone();
626  };
627}
628#[cfg(all(feature = "row_vector2", feature = "matrix2", feature = "matrix3x2"))]
629vertcat_two_args!(VerticalConcatenateR2M2, RowVector2, Matrix2, Matrix3x2, vertcat_r2m2);
630
631macro_rules! vertcat_m2r2 {
632  ($out:expr, $e0:expr, $e1:expr) => {
633    $out[0] = $e0[0].clone();
634    $out[1] = $e0[1].clone();
635    $out[3] = $e0[2].clone();
636    $out[4] = $e0[3].clone();
637    $out[2] = $e1[0].clone();
638    $out[5] = $e1[1].clone();
639  };
640}
641#[cfg(all(feature = "matrix2", feature = "row_vector2", feature = "matrix3x2"))]
642vertcat_two_args!(VerticalConcatenateM2R2, Matrix2, RowVector2, Matrix3x2, vertcat_m2r2);
643
644macro_rules! vertcat_m2x3r3 {
645  ($out:expr, $e0:expr, $e1:expr) => {
646    $out[0] = $e0[0].clone();
647    $out[1] = $e0[1].clone();
648    $out[3] = $e0[2].clone();
649    $out[4] = $e0[3].clone();
650    $out[6] = $e0[4].clone();
651    $out[7] = $e0[5].clone();
652    $out[2] = $e1[0].clone();
653    $out[5] = $e1[1].clone();
654    $out[8] = $e1[2].clone();
655  };
656}
657#[cfg(all(feature = "matrix2x3", feature = "row_vector3", feature = "matrix3"))]
658vertcat_two_args!(VerticalConcatenateM2x3R3, Matrix2x3, RowVector3, Matrix3, vertcat_m2x3r3);
659
660macro_rules! vertcat_r3m2x3 {
661  ($out:expr, $e0:expr, $e1:expr) => {
662    $out[0] = $e0[0].clone();
663    $out[3] = $e0[1].clone();
664    $out[6] = $e0[2].clone();
665    $out[1] = $e1[0].clone();
666    $out[2] = $e1[1].clone();
667    $out[4] = $e1[2].clone();
668    $out[5] = $e1[3].clone();
669    $out[7] = $e1[4].clone();
670    $out[8] = $e1[5].clone();
671  };
672}
673#[cfg(all(feature = "row_vector3", feature = "matrix2x3", feature = "matrix3"))]
674vertcat_two_args!(VerticalConcatenateR3M2x3, RowVector3, Matrix2x3, Matrix3, vertcat_r3m2x3);
675
676
677macro_rules! vertcat_mdv4 {
678  ($out:expr, $e0:expr, $e1:expr) => {
679    let e0_len = $e0.len();
680    for i in 0..e0_len {
681      $out[i] = $e0[i].clone();
682    }
683    let offset = e0_len;
684    $out[offset] = $e1[0].clone();
685    $out[offset + 1] = $e1[1].clone();
686    $out[offset + 2] = $e1[2].clone();
687    $out[offset + 3] = $e1[3].clone();
688  };
689}
690#[cfg(all(feature = "matrixd", feature = "row_vector4", feature = "matrix4"))]
691vertcat_two_args!(VerticalConcatenateMDR4, DMatrix, RowVector4, Matrix4, vertcat_mdv4);
692
693macro_rules! vertcat_mdmd {
694  ($out:expr, $e0:expr, $e1:expr) => {
695    let dest_rows = $out.nrows();
696    let mut offset = 0;
697    let mut dest_ix = 0;
698
699    let src_rows = $e0.nrows();
700    let stride = dest_rows - src_rows;
701    dest_ix = offset;
702    for ix in 0..$e0.len() {
703      $out[dest_ix] = $e0[ix].clone();
704      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
705    }
706    offset += src_rows;
707
708    let src_rows = $e1.nrows();
709    let stride = dest_rows - src_rows;
710    dest_ix = offset;
711    for ix in 0..$e1.len() {
712      $out[dest_ix] = $e1[ix].clone();
713      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
714    }
715  };
716}
717#[cfg(all(feature = "matrixd", feature = "matrix4"))]
718vertcat_two_args!(VerticalConcatenateMDMD, DMatrix, DMatrix, Matrix4, vertcat_mdmd);
719#[cfg(all(feature = "matrixd", feature = "matrix4", feature = "row_vector4"))]
720vertcat_two_args!(VerticalConcatenateR4MD, RowVector4, DMatrix, Matrix4, vertcat_mdmd);
721
722
723macro_rules! vertcat_mdmdmd {
724  ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
725    let dest_rows = $out.nrows();
726    let mut offset = 0;
727    let mut dest_ix = 0;
728
729    let src_rows = $e0.nrows();
730    let stride = dest_rows - src_rows;
731    dest_ix = offset;
732    for ix in 0..$e0.len() {
733      $out[dest_ix] = $e0[ix].clone();
734      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
735    }
736    offset += src_rows;
737
738    let src_rows = $e1.nrows();
739    let stride = dest_rows - src_rows;
740    dest_ix = offset;
741    for ix in 0..$e1.len() {
742      $out[dest_ix] = $e1[ix].clone();
743      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
744    }
745    offset += src_rows;
746
747    let src_rows = $e2.nrows();
748    let stride = dest_rows - src_rows;
749    dest_ix = offset;
750    for ix in 0..$e2.len() {
751      $out[dest_ix] = $e2[ix].clone();
752      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
753    }
754  };
755}
756
757#[cfg(all(feature = "row_vector2", feature = "matrix3x2"))]
758vertcat_three_args!(VerticalConcatenateR2R2R2, RowVector2, RowVector2, RowVector2, Matrix3x2, vertcat_mdmdmd);
759#[cfg(all(feature = "row_vector3", feature = "matrix3"))]
760vertcat_three_args!(VerticalConcatenateR3R3R3, RowVector3, RowVector3, RowVector3, Matrix3, vertcat_mdmdmd);
761#[cfg(all(feature = "row_vector4", feature = "matrixd", feature = "matrix4"))]
762vertcat_three_args!(VerticalConcatenateR4R4MD, RowVector4, RowVector4, DMatrix, Matrix4, vertcat_mdmdmd);
763#[cfg(all(feature = "row_vector4", feature = "matrixd", feature = "row_vector4", feature = "matrix4"))]
764vertcat_three_args!(VerticalConcatenateR4MDR4, RowVector4, DMatrix, RowVector4, Matrix4, vertcat_mdmdmd);
765#[cfg(all(feature = "matrixd", feature = "row_vector4", feature = "row_vector4", feature = "matrix4"))]
766vertcat_three_args!(VerticalConcatenateMDR4R4, DMatrix, RowVector4, RowVector4, Matrix4, vertcat_mdmdmd);
767
768macro_rules! vertcat_mdmdmdmd {
769  ($out:expr, $e0:expr, $e1:expr, $e2:expr, $e3:expr) => {
770    let dest_rows = $out.nrows();
771    let mut offset = 0;
772    let mut dest_ix = 0;
773
774    let src_rows = $e0.nrows();
775    let stride = dest_rows - src_rows;
776    dest_ix = offset;
777    for ix in 0..$e0.len() {
778      $out[dest_ix] = $e0[ix].clone();
779      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
780    }
781    offset += src_rows;
782
783    let src_rows = $e1.nrows();
784    let stride = dest_rows - src_rows;
785    dest_ix = offset;
786    for ix in 0..$e1.len() {
787      $out[dest_ix] = $e1[ix].clone();
788      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
789    }
790    offset += src_rows;
791
792    let src_rows = $e2.nrows();
793    let stride = dest_rows - src_rows;
794    dest_ix = offset;
795    for ix in 0..$e2.len() {
796      $out[dest_ix] = $e2[ix].clone();
797      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
798    }
799    offset += src_rows;
800
801    let src_rows = $e3.nrows();
802    let stride = dest_rows - src_rows;
803    dest_ix = offset;
804    for ix in 0..$e3.len() {
805      $out[dest_ix] = $e3[ix].clone();
806      dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
807    }
808  };
809}
810
811#[cfg(all(feature = "matrix4", feature = "row_vector4"))]
812vertcat_four_args!(VerticalConcatenateR4R4R4R4, RowVector4, RowVector4, RowVector4, RowVector4, Matrix4, vertcat_mdmdmdmd);
813
814macro_rules! impl_vertcat_arms {
815  ($kind:ident, $args:expr, $default:expr) => {
816    paste!{
817    {
818      let arguments = $args;  
819      let rows = arguments[0].shape()[0];
820      let rows:usize = arguments.iter().fold(0, |acc, x| acc + x.shape()[0]);
821      let columns:usize = arguments[0].shape()[1];
822      let nargs = arguments.len();
823      let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
824      let no_refs = !kinds.iter().any(|x| {
825        match x {
826          ValueKind::Reference(_) => true,
827          ValueKind::Matrix(_,_) => true,
828          _ => false,
829      }});
830      if no_refs {
831        let mat: Vec<$kind> = arguments.iter().flat_map(|v| v.[<as_vec $kind:lower>]().unwrap()).collect::<Vec<$kind>>();
832        fn to_column_major<T: Clone>(out: &[Value], row_n: usize, col_n: usize, extract_fn: impl Fn(&Value) -> Option<Vec<T>> + Clone) -> Vec<T> {
833          (0..col_n).flat_map(|col| out.iter().map({let value = extract_fn.clone();move |row| value(row).unwrap()[col].clone()})).collect()
834        }
835        let mat = to_column_major(&arguments, rows, columns, |v| v.[<as_vec $kind:lower>]());
836        match (rows,columns) {
837          #[cfg(feature = "matrix1")]
838          (1,1) => {return Ok(Box::new(VerticalConcatenateS1{out:Ref::new(Matrix1::from_vec(mat))}));}
839          #[cfg(feature = "vector2")]
840          (2,1) => {return Ok(Box::new(VerticalConcatenateS2{out:Ref::new(Vector2::from_vec(mat))}));}
841          #[cfg(feature = "vector3")]
842          (3,1) => {return Ok(Box::new(VerticalConcatenateS3{out:Ref::new(Vector3::from_vec(mat))}));}
843          #[cfg(feature = "vector4")]
844          (4,1) => {return Ok(Box::new(VerticalConcatenateS4{out:Ref::new(Vector4::from_vec(mat))}));}
845          #[cfg(feature = "vectord")]
846          (m,1) => {return Ok(Box::new(VerticalConcatenateSD{out:Ref::new(DVector::from_vec(mat))}));}
847          #[cfg(feature = "matrix2")]
848          (2,2) => {return Ok(Box::new(VerticalConcatenateM2{out:Ref::new(Matrix2::from_vec(mat))}));}
849          #[cfg(feature = "matrix3")]
850          (3,3) => {return Ok(Box::new(VerticalConcatenateM3{out:Ref::new(Matrix3::from_vec(mat))}));}
851          #[cfg(feature = "matrix4")]
852          (4,4) => {return Ok(Box::new(VerticalConcatenateM4{out:Ref::new(Matrix4::from_vec(mat))}));}
853          #[cfg(feature = "matrix2x3")]
854          (2,3) => {return Ok(Box::new(VerticalConcatenateM2x3{out:Ref::new(Matrix2x3::from_vec(mat))}));}
855          #[cfg(feature = "matrix3x2")]
856          (3,2) => {return Ok(Box::new(VerticalConcatenateM3x2{out:Ref::new(Matrix3x2::from_vec(mat))}));}
857          #[cfg(feature = "matrixd")]
858          (m,n) => {return Ok(Box::new(VerticalConcatenateMD{out:Ref::new(DMatrix::from_vec(m,n,mat))}));}
859          x => Err(MechError{file: file!().to_string(), tokens: vec![], msg: format!("{:?}",x), id: line!(), kind: MechErrorKind::None})?,
860        }
861      } else {
862        match (nargs,rows,columns) {
863          #[cfg(feature = "vector2")]
864          (1,2,1) => {
865            match &arguments[..] {
866              // r2
867              [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0))] => {
868                return Ok(Box::new(VerticalConcatenateV2{out: e0.clone()}));
869              }
870              _ => todo!(),
871            }
872          }
873          #[cfg(feature = "vector3")]
874          (1,3,1) => {
875            match &arguments[..] {
876              // r3
877              [Value::MutableReference(e0)] => {
878                match *e0.borrow() {
879                  Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)) => {
880                    return Ok(Box::new(VerticalConcatenateV3{out: e0.clone()}));
881                  }
882                  _ => todo!(),
883                }
884              }
885              _ => todo!(),
886            }
887          }
888          #[cfg(feature = "vector4")]
889          (1,4,1) => {
890            match &arguments[..] {
891              // r4
892              [Value::[<Matrix $kind:camel>](Matrix::Vector4(ref e0))] => {
893                return Ok(Box::new(VerticalConcatenateV4{out: e0.clone()}));
894              }
895              _ => todo!(),
896            }
897          }
898          #[cfg(feature = "vectord")]
899          (1,m,1) => {
900            match &arguments[..] {
901              // rd
902              [Value::[<Matrix $kind:camel>](Matrix::DVector(ref e0))] => {
903                return Ok(Box::new(VerticalConcatenateVD{out: e0.clone()}));
904              }
905              _ => todo!(),
906            }
907          }
908          #[cfg(all(feature = "matrix1", feature = "vector2"))]
909          (2,2,1) => {
910            let mut out = Vector2::from_element($default);
911            match &arguments[..] {
912              // m1m1
913              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
914                return Ok(Box::new(VerticalConcatenateM1M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
915              }
916              _ => todo!(),
917            }
918          }
919          #[cfg(all(feature = "matrix1", feature = "vector3", feature = "vector2"))]
920          (2,3,1) => {
921            let mut out = Vector3::from_element($default);
922            match &arguments[..] {
923              //m1v2
924              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
925                return Ok(Box::new(VerticalConcatenateM1V2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
926              }
927              //v2m1
928              [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
929                return Ok(Box::new(VerticalConcatenateV2M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
930              }
931              _ => todo!(),
932            }
933          }
934          #[cfg(feature = "vector4")]
935          (2,4,1) => {
936            let mut out = Vector4::from_element($default);
937            match &arguments[..] {
938              // m1v3
939              #[cfg(all(feature = "matrix1", feature = "vector3"))]
940              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e1))] => {
941                return Ok(Box::new(VerticalConcatenateM1V3{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
942              }
943              // v3m1
944              #[cfg(all(feature = "matrix1", feature = "vector3"))]
945              [Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
946                return Ok(Box::new(VerticalConcatenateV3M1{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
947              }
948              // v2v2
949              #[cfg(feature = "vector2")]
950              [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
951                return Ok(Box::new(VerticalConcatenateV2V2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
952              }              
953              _ => todo!(),
954            }
955          } 
956          #[cfg(feature = "vectord")]
957          (2,m,1) => {
958            let mut out = DVector::from_element(m,$default);
959            match &arguments[..] {
960              [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1)] => {
961                let e0 = e0.get_copyable_matrix();
962                let e1 = e1.get_copyable_matrix();
963                return Ok(Box::new(VerticalConcatenateVD2{e0, e1, out: Ref::new(out)}));
964              }
965              _ => todo!(),
966            }
967          }
968          #[cfg(feature = "vector3")]
969          (3,3,1) => {  
970            let mut out = Vector3::from_element($default);
971            match &arguments[..] {
972              // m1 m1 m1
973              #[cfg(feature = "matrix1")]
974              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
975                return Ok(Box::new(VerticalConcatenateM1M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
976              }    
977              _ => todo!()
978            }
979          }
980          #[cfg(all(feature = "matrix1", feature = "vector2", feature = "vector4"))]
981          (3,4,1) => {
982            let mut out = Vector4::from_element($default);
983            match &arguments[..] {
984              // m1 m1 v2
985              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e2))] => {
986                return Ok(Box::new(VerticalConcatenateM1M1V2{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
987              }
988              // m1 v2 m1
989              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
990                return Ok(Box::new(VerticalConcatenateM1V2M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
991              }
992              // v2 m1 m1
993              [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
994                return Ok(Box::new(VerticalConcatenateV2M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: Ref::new(out)}));
995              }
996              _ => todo!()
997            }
998          }
999          #[cfg(feature = "vectord")]
1000          (3,m,1) => {
1001            let mut out = DVector::from_element(m,$default);
1002            match &arguments[..] {
1003              [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2)] => {
1004                let e0 = e0.get_copyable_matrix();
1005                let e1 = e1.get_copyable_matrix();
1006                let e2 = e2.get_copyable_matrix();
1007                return Ok(Box::new(VerticalConcatenateVD3{e0, e1, e2, out: Ref::new(out)}));
1008              }
1009              _ => todo!(),
1010            }
1011          }
1012          #[cfg(all(feature = "matrix1", feature = "vector4"))]
1013          (4,4,1) => {
1014            let mut out = Vector4::from_element($default);
1015            match &arguments[..] {
1016              // m1 m1 m1 m1
1017              [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e3))] => {
1018                return Ok(Box::new(VerticalConcatenateM1M1M1M1{ e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), e3: e3.clone(), out: Ref::new(out) }));
1019              }
1020              _ => todo!(),
1021            }
1022          }
1023          #[cfg(feature = "vectord")]
1024          (4,m,1) => {
1025            let mut out = DVector::from_element(m,$default);
1026            match &arguments[..] {
1027              [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2),Value::[<Matrix $kind:camel>](e3)] => {
1028                let e0 = e0.get_copyable_matrix();
1029                let e1 = e1.get_copyable_matrix();
1030                let e2 = e2.get_copyable_matrix();
1031                let e3 = e3.get_copyable_matrix();
1032                return Ok(Box::new(VerticalConcatenateVD4{e0, e1, e2, e3, out: Ref::new(out)}));
1033              }
1034              _ => todo!(),
1035            }
1036          }
1037          #[cfg(feature = "vectord")]
1038          (l,m,1) => {
1039            let mut out = DVector::from_element(m,$default);
1040            let mut matrix_args: Vec<(Box<dyn CopyMat<$kind>>,usize)> = vec![];
1041            let mut scalar_args: Vec<(Ref<$kind>,usize)> = vec![];
1042            let mut i = 0;
1043            for arg in arguments.iter() {
1044              match &arg {
1045                Value::[<$kind:camel>](e0) => {
1046                  scalar_args.push((e0.clone(),i));
1047                  i += 1;
1048                }
1049                Value::[<Matrix $kind:camel>](e0) => {
1050                  matrix_args.push((e0.get_copyable_matrix(),i));
1051                  i += e0.shape()[0];
1052                }
1053                _ => todo!(),
1054              }
1055            }
1056            return Ok(Box::new(VerticalConcatenateVDN{scalar: scalar_args, matrix: matrix_args, out: Ref::new(out)}));
1057          }
1058          #[cfg(feature = "matrix2")]
1059          (2,2,2) => {
1060            let mut out = Matrix2::from_element($default);
1061            match &arguments[..] {
1062              // v2v2
1063              #[cfg(feature = "row_vector2")]
1064              [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1))] => {return Ok(Box::new(VerticalConcatenateR2R2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));}
1065              _ => todo!(),
1066            }
1067          }
1068          #[cfg(feature = "matrix2x3")]
1069          (2,2,3) => {
1070            let mut out = Matrix2x3::from_element($default);
1071            match &arguments[..] {
1072              // r3r3
1073              #[cfg(feature = "row_vector3")]
1074              [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1))] => {return Ok(Box::new(VerticalConcatenateR3R3{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));}
1075              _ => todo!(),
1076            }
1077          }
1078          #[cfg(feature = "matrix3x2")]
1079          (2,3,2) => {
1080            let mut out = Matrix3x2::from_element($default);
1081            match &arguments[..] {
1082              // v2m2
1083              #[cfg(all(feature = "row_vector2", feature = "matrix2"))]
1084              [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e1))] => {
1085                return Ok(Box::new(VerticalConcatenateR2M2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1086              }
1087              // m2v2
1088              #[cfg(all(feature = "matrix2", feature = "row_vector2"))]
1089              [Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1))] => {
1090                return Ok(Box::new(VerticalConcatenateM2R2{e0: e0.clone(), e1: e1.clone(), out: Ref::new(out)}));
1091              }
1092              _ => todo!(),
1093            }
1094            
1095          }
1096          #[cfg(feature = "matrix3")]
1097          (2,3,3) => {
1098            let mut out = Matrix3::from_element($default);
1099            match &arguments[..] {
1100              // v3m3x2
1101              #[cfg(all(feature = "row_vector3", feature = "matrix2x3"))]
1102              [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e1))] => {
1103                return Ok(Box::new(VerticalConcatenateR3M2x3 { e0: e0.clone(), e1: e1.clone(), out: Ref::new(out) }));
1104              }
1105              // m3x2v3
1106              #[cfg(all(feature = "matrix2x3", feature = "row_vector3"))]
1107              [Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1))] => {
1108                return Ok(Box::new(VerticalConcatenateM2x3R3 { e0: e0.clone(), e1: e1.clone(), out: Ref::new(out) }));
1109              }
1110              _ => todo!(),
1111            }
1112            
1113          }
1114          #[cfg(feature = "matrix4")]
1115          (2,4,4) => {
1116            let mut out = Matrix4::from_element($default);
1117            match &arguments[..] {
1118              // r4md
1119              #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1120              [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)), Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1))] => Ok(Box::new(VerticalConcatenateR4MD{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1121              // mdr4
1122              #[cfg(all(feature = "matrixd", feature = "row_vector4"))]
1123              [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1))] => Ok(Box::new(VerticalConcatenateMDR4{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1124              // mdmd
1125              #[cfg(feature = "matrixd")]
1126              [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)), Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1))] => Ok(Box::new(VerticalConcatenateMDMD{e0:e0.clone(),e1:e1.clone(),out:Ref::new(out)})),
1127              _ => todo!(),
1128            }
1129            
1130          }
1131          #[cfg(feature = "matrixd")]
1132          (2,m,n) => {
1133            let mut out = DMatrix::from_element(m,n,$default);
1134            match &arguments[..] {
1135              [Value::[<Matrix $kind:camel>](m0), Value::[<Matrix $kind:camel>](m1)] => {
1136                let e0 = m0.get_copyable_matrix();
1137                let e1 = m1.get_copyable_matrix();
1138                Ok(Box::new(VerticalConcatenateTwoArgs{e0, e1, out: Ref::new(out)}))
1139              }
1140              _ => todo!(),
1141            }            
1142          }
1143          #[cfg(feature = "matrix3x2")]
1144          (3,3,2) => {
1145            let mut out = Matrix3x2::from_element($default);
1146            match &arguments[..] {
1147              // r2r2r2
1148              #[cfg(feature = "row_vector2")]
1149              [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e2))]=>Ok(Box::new(VerticalConcatenateR2R2R2{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1150              _ => todo!(),
1151            }
1152          }
1153          #[cfg(feature = "matrix3")]
1154          (3,3,3) => {
1155            let mut out = Matrix3::from_element($default);
1156            match &arguments[..] {
1157              // r3r3r3
1158              #[cfg(feature = "row_vector3")]
1159              [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e2))]=>Ok(Box::new(VerticalConcatenateR3R3R3{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1160              _ => todo!(),
1161            }
1162          }
1163          #[cfg(feature = "matrix4")]
1164          (3,4,4) => {
1165            let mut out = Matrix4::from_element($default);
1166            match &arguments[..] {
1167              // r4r4md
1168              #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1169              [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e2))]=>Ok(Box::new(VerticalConcatenateR4R4MD{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1170              // r4mdr4
1171              #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1172              [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2))]=>Ok(Box::new(VerticalConcatenateR4MDR4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1173              // mdr4r4
1174              #[cfg(all(feature = "row_vector4", feature = "matrixd"))]
1175              [Value::[<Matrix $kind:camel>](Matrix::DMatrix(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2))]=>Ok(Box::new(VerticalConcatenateMDR4R4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),out:Ref::new(out)})),
1176              _ => todo!(),
1177            }
1178          }
1179          #[cfg(feature = "matrixd")]
1180          (3,m,n) => {
1181            let mut out = DMatrix::from_element(m,n,$default);
1182            match &arguments[..] {
1183              [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2)] => {
1184                let e0 = m0.get_copyable_matrix();
1185                let e1 = m1.get_copyable_matrix();
1186                let e2 = m2.get_copyable_matrix();
1187                Ok(Box::new(VerticalConcatenateThreeArgs{e0,e1,e2,out:Ref::new(out)}))
1188              }   
1189              _ => todo!(),
1190            }
1191          }
1192          #[cfg(feature = "matrix4")]
1193          (4,4,4) => {
1194            let mut out = Matrix4::from_element($default);
1195            match &arguments[..] {
1196              // r4r4r4r4
1197              #[cfg(feature = "row_vector4")]
1198              [Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e0)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e1)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e2)),Value::[<Matrix $kind:camel>](Matrix::RowVector4(ref e3))]=>Ok(Box::new(VerticalConcatenateR4R4R4R4{e0:e0.clone(),e1:e1.clone(),e2:e2.clone(),e3:e3.clone(),out:Ref::new(out)})),
1199              _ => todo!(),
1200            }
1201          }
1202          #[cfg(feature = "matrixd")]
1203          (4,m,n) => {
1204            let mut out = DMatrix::from_element(m,n,$default);
1205            match &arguments[..] {
1206              [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2),Value::[<Matrix $kind:camel>](m3)] => {
1207                let e0 = m0.get_copyable_matrix();
1208                let e1 = m1.get_copyable_matrix();
1209                let e2 = m2.get_copyable_matrix();
1210                let e3 = m3.get_copyable_matrix();
1211                Ok(Box::new(VerticalConcatenateFourArgs{e0,e1,e2,e3,out:Ref::new(out)}))
1212              }   
1213              _ => todo!(),
1214            }
1215          }
1216          #[cfg(feature = "matrixd")]
1217          (l,m,n) => {
1218            let mut out = DMatrix::from_element(m,n,$default);
1219            let mut args = vec![];
1220            for arg in arguments {
1221              match arg {
1222                Value::[<Matrix $kind:camel>](m0) => {
1223                  let e0 = m0.get_copyable_matrix();
1224                  args.push(e0);
1225                }
1226                _ => todo!(),
1227              }
1228            }
1229            Ok(Box::new(VerticalConcatenateNArgs{e0: args, out:Ref::new(out)}))
1230          }
1231          _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind});}
1232        }
1233  }}}}}
1234
1235fn impl_vertcat_fxn(arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1236
1237  let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
1238  let target_kind = kinds[0].clone();
1239
1240  #[cfg(feature = "f64")]
1241  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::F64) { return impl_vertcat_arms!(F64, arguments, F64::default()) } }
1242
1243  #[cfg(feature = "f32")]
1244  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::F32) { return impl_vertcat_arms!(F32, arguments, F32::default()) } }
1245
1246  #[cfg(feature = "u8")]
1247  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U8)  { return impl_vertcat_arms!(u8,  arguments, u8::default()) } }
1248
1249  #[cfg(feature = "u16")]
1250  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U16) { return impl_vertcat_arms!(u16, arguments, u16::default()) } }
1251
1252  #[cfg(feature = "u32")]
1253  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U32) { return impl_vertcat_arms!(u32, arguments, u32::default()) } }
1254
1255  #[cfg(feature = "u64")]
1256  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U64) { return impl_vertcat_arms!(u64, arguments, u64::default()) } }
1257
1258  #[cfg(feature = "u128")]
1259  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::U128){ return impl_vertcat_arms!(u128, arguments, u128::default()) } }
1260
1261  #[cfg(feature = "bool")]
1262  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::Bool) { return impl_vertcat_arms!(bool, arguments, bool::default()) } }
1263
1264  #[cfg(feature = "string")]
1265  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::String) { return impl_vertcat_arms!(String, arguments, String::default()) } }
1266
1267  #[cfg(feature = "rational")]
1268  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::RationalNumber) { return impl_vertcat_arms!(RationalNumber, arguments, RationalNumber::default()) } }
1269
1270  #[cfg(feature = "complex")]
1271  { if ValueKind::is_compatible(target_kind.clone(), ValueKind::ComplexNumber) { return impl_vertcat_arms!(ComplexNumber, arguments, ComplexNumber::default()) } }
1272
1273  Err(MechError {
1274    file: file!().to_string(),
1275    tokens: vec![],
1276    msg: format!("Vertical concatenation not implemented for type {:?}", target_kind),
1277    id: line!(),
1278    kind: MechErrorKind::UnhandledFunctionArgumentKind,
1279  })
1280}
1281
1282
1283pub struct MatrixVertCat {}
1284impl NativeFunctionCompiler for MatrixVertCat {
1285  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1286    impl_vertcat_fxn(arguments)
1287  }
1288}