1#[macro_use]
2use crate::stdlib::*;
3
4macro_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> MechFunction for $fxn<T>
14 where
15 T: Copy + 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_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 };}
29
30macro_rules! vertcat_two_args {
31 ($fxn:ident, $e1:ident, $e2:ident, $out:ident, $opt:ident) => {
32 #[derive(Debug)]
33 struct $fxn<T> {
34 e0: Ref<$e1<T>>,
35 e1: Ref<$e2<T>>,
36 out: Ref<$out<T>>,
37 }
38 impl<T> MechFunction for $fxn<T>
39 where
40 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
41 Ref<$out<T>>: ToValue
42 {
43 fn solve(&self) {
44 unsafe {
45 let e0_ptr = (*(self.e0.as_ptr())).clone();
46 let e1_ptr = (*(self.e1.as_ptr())).clone();
47 let mut out_ptr = (&mut *(self.out.as_ptr()));
48 $opt!(out_ptr,e0_ptr,e1_ptr);
49 }
50 }
51 fn out(&self) -> Value { self.out.to_value() }
52 fn to_string(&self) -> String { format!("{:#?}", self) }
53 }
54 };}
55
56macro_rules! vertcat_three_args {
57 ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $out:ident, $opt:ident) => {
58 #[derive(Debug)]
59 struct $fxn<T> {
60 e0: Ref<$e0<T>>,
61 e1: Ref<$e1<T>>,
62 e2: Ref<$e2<T>>,
63 out: Ref<$out<T>>,
64 }
65 impl<T> MechFunction for $fxn<T>
66 where
67 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
68 Ref<$out<T>>: ToValue
69 {
70 fn solve(&self) {
71 unsafe {
72 let e0_ptr = (*(self.e0.as_ptr())).clone();
73 let e1_ptr = (*(self.e1.as_ptr())).clone();
74 let e2_ptr = (*(self.e2.as_ptr())).clone();
75 let mut out_ptr = (&mut *(self.out.as_ptr()));
76 $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr);
77 }
78 }
79 fn out(&self) -> Value { self.out.to_value() }
80 fn to_string(&self) -> String { format!("{:#?}", self) }
81 }
82 };}
83
84macro_rules! vertcat_four_args {
85 ($fxn:ident, $e0:ident, $e1:ident, $e2:ident, $e3:ident, $out:ident, $opt:ident) => {
86 #[derive(Debug)]
87 struct $fxn<T> {
88 e0: Ref<$e0<T>>,
89 e1: Ref<$e1<T>>,
90 e2: Ref<$e2<T>>,
91 e3: Ref<$e3<T>>,
92 out: Ref<$out<T>>,
93 }
94 impl<T> MechFunction for $fxn<T>
95 where
96 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
97 Ref<$out<T>>: ToValue
98 {
99 fn solve(&self) {
100 unsafe {
101 let e0_ptr = (*(self.e0.as_ptr())).clone();
102 let e1_ptr = (*(self.e1.as_ptr())).clone();
103 let e2_ptr = (*(self.e2.as_ptr())).clone();
104 let e3_ptr = (*(self.e3.as_ptr())).clone();
105 let mut out_ptr = (&mut *(self.out.as_ptr()));
106 $opt!(out_ptr,e0_ptr,e1_ptr,e2_ptr,e3_ptr);
107 }
108 }
109 fn out(&self) -> Value { self.out.to_value() }
110 fn to_string(&self) -> String { format!("{:#?}", self) }
111 }
112 };}
113
114struct VerticalConcatenateTwoArgs<T> {
115 e0: Box<dyn CopyMat<T>>,
116 e1: Box<dyn CopyMat<T>>,
117 out: Ref<DMatrix<T>>,
118}
119impl<T> MechFunction for VerticalConcatenateTwoArgs<T>
120where
121 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
122 Ref<DMatrix<T>>: ToValue
123{
124 fn solve(&self) {
125 let offset = self.e0.copy_into_row_major(&self.out,0);
126 self.e1.copy_into_row_major(&self.out,offset);
127 }
128 fn out(&self) -> Value { self.out.to_value() }
129 fn to_string(&self) -> String { format!("VerticalConcatenateTwoArgs\n{:#?}", self.out) }
130}
131
132struct VerticalConcatenateThreeArgs<T> {
133 e0: Box<dyn CopyMat<T>>,
134 e1: Box<dyn CopyMat<T>>,
135 e2: Box<dyn CopyMat<T>>,
136 out: Ref<DMatrix<T>>,
137}
138impl<T> MechFunction for VerticalConcatenateThreeArgs<T>
139where
140 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
141 Ref<DMatrix<T>>: ToValue
142{
143 fn solve(&self) {
144 let mut offset = self.e0.copy_into_row_major(&self.out,0);
145 offset += self.e1.copy_into_row_major(&self.out,offset);
146 self.e2.copy_into_row_major(&self.out,offset);
147 }
148 fn out(&self) -> Value { self.out.to_value() }
149 fn to_string(&self) -> String { format!("VerticalConcatenateThreeArgs\n{:#?}", self.out) }
150}
151
152struct VerticalConcatenateFourArgs<T> {
153 e0: Box<dyn CopyMat<T>>,
154 e1: Box<dyn CopyMat<T>>,
155 e2: Box<dyn CopyMat<T>>,
156 e3: Box<dyn CopyMat<T>>,
157 out: Ref<DMatrix<T>>,
158}
159impl<T> MechFunction for VerticalConcatenateFourArgs<T>
160where
161 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
162 Ref<DMatrix<T>>: ToValue
163{
164 fn solve(&self) {
165 let mut offset = self.e0.copy_into_row_major(&self.out,0);
166 offset += self.e1.copy_into_row_major(&self.out,offset);
167 offset += self.e2.copy_into_row_major(&self.out,offset);
168 self.e3.copy_into_row_major(&self.out,offset);
169
170 }
171 fn out(&self) -> Value { self.out.to_value() }
172 fn to_string(&self) -> String { format!("VerticalConcatenateFourArgs\n{:#?}", self.out) }
173}
174
175struct VerticalConcatenateNArgs<T> {
176 e0: Vec<Box<dyn CopyMat<T>>>,
177 out: Ref<DMatrix<T>>,
178}
179impl<T> MechFunction for VerticalConcatenateNArgs<T>
180where
181 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
182 Ref<DMatrix<T>>: ToValue
183{
184 fn solve(&self) {
185 let mut offset = 0;
186 for e in &self.e0 {
187 offset += e.copy_into_row_major(&self.out,offset);
188 }
189 }
190 fn out(&self) -> Value { self.out.to_value() }
191 fn to_string(&self) -> String { format!("VerticalConcatenateNArgs\n{:#?}", self.out) }
192}
193
194macro_rules! vertical_concatenate {
195 ($name:ident, $vec_size:expr) => {
196 paste!{
197 #[derive(Debug)]
198 struct $name<T> {
199 out: Ref<[<$vec_size>]<T>>,
200 }
201
202 impl<T> MechFunction for $name<T>
203 where
204 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
205 Ref<[<$vec_size>]<T>>: ToValue
206 {
207 fn solve(&self) {}
208 fn out(&self) -> Value { self.out.to_value() }
209 fn to_string(&self) -> String { format!("{:#?}", self) }
210 }
211 }
212 };}
213
214struct VerticalConcatenateVD2<T> {
215 e0: Box<dyn CopyMat<T>>,
216 e1: Box<dyn CopyMat<T>>,
217 out: Ref<DVector<T>>,
218}
219
220impl<T> MechFunction for VerticalConcatenateVD2<T>
221where
222 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
223 Ref<DVector<T>>: ToValue
224{
225 fn solve(&self) {
226 let mut offset = self.e0.copy_into_v(&self.out,0);
227 self.e1.copy_into_v(&self.out,offset);
228 }
229 fn out(&self) -> Value { self.out.to_value() }
230 fn to_string(&self) -> String { format!("VerticalConcatenateVD2\n{:#?}", self.out) }
231}
232
233struct VerticalConcatenateVD3<T> {
234 e0: Box<dyn CopyMat<T>>,
235 e1: Box<dyn CopyMat<T>>,
236 e2: Box<dyn CopyMat<T>>,
237 out: Ref<DVector<T>>,
238}
239
240impl<T> MechFunction for VerticalConcatenateVD3<T>
241where
242 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
243 Ref<DVector<T>>: ToValue
244{
245 fn solve(&self) {
246 let mut offset = self.e0.copy_into_v(&self.out,0);
247 offset += self.e1.copy_into_v(&self.out,offset);
248 self.e2.copy_into_v(&self.out,offset);
249 }
250 fn out(&self) -> Value { self.out.to_value() }
251 fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
252}
253
254struct VerticalConcatenateVD4<T> {
255 e0: Box<dyn CopyMat<T>>,
256 e1: Box<dyn CopyMat<T>>,
257 e2: Box<dyn CopyMat<T>>,
258 e3: Box<dyn CopyMat<T>>,
259 out: Ref<DVector<T>>,
260}
261
262impl<T> MechFunction for VerticalConcatenateVD4<T>
263where
264 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
265 Ref<DVector<T>>: ToValue
266{
267 fn solve(&self) {
268 let mut offset = self.e0.copy_into_v(&self.out,0);
269 offset += self.e1.copy_into_v(&self.out,offset);
270 offset += self.e2.copy_into_v(&self.out,offset);
271 self.e3.copy_into_v(&self.out,offset);
272 }
273 fn out(&self) -> Value { self.out.to_value() }
274 fn to_string(&self) -> String { format!("VerticalConcatenateVD3\n{:#?}", self.out) }
275}
276
277struct VerticalConcatenateVDN<T> {
278 scalar: Vec<(Ref<T>,usize)>,
279 matrix: Vec<(Box<dyn CopyMat<T>>,usize)>,
280 out: Ref<DVector<T>>,
281}
282
283impl<T> MechFunction for VerticalConcatenateVDN<T>
284where
285 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
286 Ref<DVector<T>>: ToValue
287{
288 fn solve(&self) {
289 unsafe {
290 let mut out_ptr = (&mut *(self.out.as_ptr()));
291 for (e,i) in &self.matrix {
292 e.copy_into_v(&self.out,*i);
293 }
294 for (e,i) in &self.scalar {
295 out_ptr[*i] = e.borrow().clone();
296 }
297 }
298 }
299 fn out(&self) -> Value { self.out.to_value() }
300 fn to_string(&self) -> String { format!("VerticalConcatenateVDN\n{:#?}", self.out) }
301}
302
303#[derive(Debug)]
304struct VerticalConcatenateS1<T> {
305 out: Ref<Matrix1<T>>,
306}
307
308impl<T> MechFunction for VerticalConcatenateS1<T>
309where
310 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
311 Ref<Matrix1<T>>: ToValue
312{
313 fn solve(&self) {}
314 fn out(&self) -> Value { self.out.to_value() }
315 fn to_string(&self) -> String { format!("{:#?}", self) }
316}
317
318vertical_concatenate!(VerticalConcatenateS2,Vector2);
319vertical_concatenate!(VerticalConcatenateS3,Vector3);
320vertical_concatenate!(VerticalConcatenateS4,Vector4);
321vertical_concatenate!(VerticalConcatenateV2,Vector2);
322vertical_concatenate!(VerticalConcatenateV3,Vector3);
323vertical_concatenate!(VerticalConcatenateV4,Vector4);
324vertical_concatenate!(VerticalConcatenateM2,Matrix2);
325vertical_concatenate!(VerticalConcatenateM3,Matrix3);
326vertical_concatenate!(VerticalConcatenateM2x3,Matrix2x3);
327vertical_concatenate!(VerticalConcatenateM3x2,Matrix3x2);
328vertical_concatenate!(VerticalConcatenateM4,Matrix4);
329vertical_concatenate!(VerticalConcatenateMD,DMatrix);
330vertical_concatenate!(VerticalConcatenateVD,DVector);
331
332#[derive(Debug)]
333struct VerticalConcatenateSD<T> {
334 out: Ref<DVector<T>>,
335}
336impl<T> MechFunction for VerticalConcatenateSD<T>
337where
338 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
339 Ref<DVector<T>>: ToValue
340{
341 fn solve(&self) { }
342 fn out(&self) -> Value { self.out.to_value() }
343 fn to_string(&self) -> String { format!("{:#?}", self) }
344}
345
346macro_rules! vertcat_m1m1 {
347 ($out:expr, $e0:expr, $e1:expr) => {
348 $out[0] = $e0[0].clone();
349 $out[1] = $e1[0].clone();
350 };}
351vertcat_two_args!(VerticalConcatenateM1M1,Matrix1,Matrix1,Vector2,vertcat_m1m1);
352
353macro_rules! vertcat_r2r2 {
354 ($out:expr, $e0:expr, $e1:expr) => {
355 $out[0] = $e0[0].clone();
356 $out[1] = $e0[1].clone();
357 $out[2] = $e1[0].clone();
358 $out[3] = $e1[1].clone();
359 };}
360vertcat_two_args!(VerticalConcatenateV2V2,Vector2,Vector2,Vector4,vertcat_r2r2);
361
362macro_rules! vertcat_m1r3 {
363 ($out:expr, $e0:expr, $e1:expr) => {
364 $out[0] = $e0[0].clone();
365 $out[1] = $e1[0].clone();
366 $out[2] = $e1[1].clone();
367 $out[3] = $e1[2].clone();
368 };}
369vertcat_two_args!(VerticalConcatenateM1V3,Matrix1,Vector3,Vector4,vertcat_m1r3);
370
371macro_rules! vertcat_r3m1 {
372 ($out:expr, $e0:expr, $e1:expr) => {
373 $out[0] = $e0[0].clone();
374 $out[1] = $e0[1].clone();
375 $out[2] = $e0[2].clone();
376 $out[3] = $e1[0].clone();
377 };}
378vertcat_two_args!(VerticalConcatenateV3M1,Vector3,Matrix1,Vector4,vertcat_r3m1);
379
380macro_rules! vertcat_m1r2 {
381 ($out:expr, $e0:expr, $e1:expr) => {
382 $out[0] = $e0[0].clone();
383 $out[1] = $e1[0].clone();
384 $out[2] = $e1[1].clone();
385 };
386}
387vertcat_two_args!(VerticalConcatenateM1V2, Matrix1, Vector2, Vector3, vertcat_m1r2);
388
389macro_rules! vertcat_r2m1 {
390 ($out:expr, $e0:expr, $e1:expr) => {
391 $out[0] = $e0[0].clone();
392 $out[1] = $e0[1].clone();
393 $out[2] = $e1[0].clone();
394 };
395}
396vertcat_two_args!(VerticalConcatenateV2M1, Vector2, Matrix1, Vector3, vertcat_r2m1);
397
398macro_rules! vertcat_m1m1m1 {
399 ($out:expr, $e0:expr,$e1:expr,$e2:expr) => {
400 $out[0] = $e0[0].clone();
401 $out[1] = $e1[0].clone();
402 $out[2] = $e2[0].clone();
403 };
404}
405vertcat_three_args!(VerticalConcatenateM1M1M1,Matrix1,Matrix1,Matrix1,Vector3, vertcat_m1m1m1);
406
407macro_rules! vertcat_m1m1r2 {
408 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
409 $out[0] = $e0[0].clone();
410 $out[1] = $e1[0].clone();
411 $out[2] = $e2[0].clone();
412 $out[3] = $e2[1].clone();
413 };
414}
415vertcat_three_args!(VerticalConcatenateM1M1V2, Matrix1, Matrix1, Vector2, Vector4, vertcat_m1m1r2);
416
417macro_rules! vertcat_m1r2m1 {
418 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
419 $out[0] = $e0[0].clone();
420 $out[1] = $e1[0].clone();
421 $out[2] = $e1[1].clone();
422 $out[3] = $e2[0].clone();
423 };
424}
425vertcat_three_args!(VerticalConcatenateM1V2M1, Matrix1, Vector2, Matrix1, Vector4, vertcat_m1r2m1);
426
427macro_rules! vertcat_r2m1m1 {
428 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
429 $out[0] = $e0[0].clone();
430 $out[1] = $e0[1].clone();
431 $out[2] = $e1[0].clone();
432 $out[3] = $e2[0].clone();
433 };
434}
435vertcat_three_args!(VerticalConcatenateV2M1M1, Vector2, Matrix1, Matrix1, Vector4, vertcat_r2m1m1);
436
437#[derive(Debug)]
438struct VerticalConcatenateM1M1M1M1<T> {
439 e0: Ref<Matrix1<T>>,
440 e1: Ref<Matrix1<T>>,
441 e2: Ref<Matrix1<T>>,
442 e3: Ref<Matrix1<T>>,
443 out: Ref<Vector4<T>>,
444}
445impl<T> MechFunction for VerticalConcatenateM1M1M1M1<T>
446where
447 T: Copy + Debug + Clone + Sync + Send + PartialEq + 'static,
448 Ref<Vector4<T>>: ToValue
449{
450 fn solve(&self) {
451 unsafe {
452 let e0_ptr = (*(self.e0.as_ptr())).clone();
453 let e1_ptr = (*(self.e1.as_ptr())).clone();
454 let e2_ptr = (*(self.e2.as_ptr())).clone();
455 let e3_ptr = (*(self.e3.as_ptr())).clone();
456 let mut out_ptr = (&mut *(self.out.as_ptr()));
457 out_ptr[0] = e0_ptr[0].clone();
458 out_ptr[1] = e1_ptr[0].clone();
459 out_ptr[2] = e2_ptr[0].clone();
460 out_ptr[3] = e3_ptr[0].clone();
461 }
462 }
463 fn out(&self) -> Value { self.out.to_value() }
464 fn to_string(&self) -> String { format!("{:#?}", self) }
465}
466
467macro_rules! vertcat_r2r2 {
468 ($out:expr, $e0:expr, $e1:expr) => {
469 $out[0] = $e0[0].clone();
470 $out[2] = $e0[1].clone();
471 $out[1] = $e1[0].clone();
472 $out[3] = $e1[1].clone();
473 };
474}
475vertcat_two_args!(VerticalConcatenateR2R2, RowVector2, RowVector2, Matrix2, vertcat_r2r2);
476
477macro_rules! vertcat_r3r3 {
478 ($out:expr, $e0:expr, $e1:expr) => {
479 $out[0] = $e0[0].clone();
480 $out[2] = $e0[1].clone();
481 $out[4] = $e0[2].clone();
482 $out[1] = $e1[0].clone();
483 $out[3] = $e1[1].clone();
484 $out[5] = $e1[2].clone();
485 };
486}
487vertcat_two_args!(VerticalConcatenateR3R3, RowVector3, RowVector3, Matrix2x3, vertcat_r3r3);
488
489macro_rules! vertcat_r2m2 {
490 ($out:expr, $e0:expr, $e1:expr) => {
491 $out[0] = $e0[0].clone();
492 $out[3] = $e0[1].clone();
493 $out[1] = $e1[0].clone();
494 $out[2] = $e1[1].clone();
495 $out[4] = $e1[2].clone();
496 $out[5] = $e1[3].clone();
497 };
498}
499vertcat_two_args!(VerticalConcatenateR2M2, RowVector2, Matrix2, Matrix3x2, vertcat_r2m2);
500
501macro_rules! vertcat_m2r2 {
502 ($out:expr, $e0:expr, $e1:expr) => {
503 $out[0] = $e0[0].clone();
504 $out[1] = $e0[1].clone();
505 $out[3] = $e0[2].clone();
506 $out[4] = $e0[3].clone();
507 $out[2] = $e1[0].clone();
508 $out[5] = $e1[1].clone();
509 };
510}
511vertcat_two_args!(VerticalConcatenateM2R2, Matrix2, RowVector2, Matrix3x2, vertcat_m2r2);
512
513macro_rules! vertcat_m2x3r3 {
514 ($out:expr, $e0:expr, $e1:expr) => {
515 $out[0] = $e0[0].clone();
516 $out[1] = $e0[1].clone();
517 $out[3] = $e0[2].clone();
518 $out[4] = $e0[3].clone();
519 $out[6] = $e0[4].clone();
520 $out[7] = $e0[5].clone();
521 $out[2] = $e1[0].clone();
522 $out[5] = $e1[1].clone();
523 $out[8] = $e1[2].clone();
524 };
525}
526vertcat_two_args!(VerticalConcatenateM2x3R3, Matrix2x3, RowVector3, Matrix3, vertcat_m2x3r3);
527
528macro_rules! vertcat_r3m2x3 {
529 ($out:expr, $e0:expr, $e1:expr) => {
530 $out[0] = $e0[0].clone();
531 $out[3] = $e0[1].clone();
532 $out[6] = $e0[2].clone();
533 $out[1] = $e1[0].clone();
534 $out[2] = $e1[1].clone();
535 $out[4] = $e1[2].clone();
536 $out[5] = $e1[3].clone();
537 $out[7] = $e1[4].clone();
538 $out[8] = $e1[5].clone();
539 };
540}
541vertcat_two_args!(VerticalConcatenateR3M2x3, RowVector3, Matrix2x3, Matrix3, vertcat_r3m2x3);
542
543
544macro_rules! vertcat_mdv4 {
545 ($out:expr, $e0:expr, $e1:expr) => {
546 let e0_len = $e0.len();
547 for i in 0..e0_len {
548 $out[i] = $e0[i].clone();
549 }
550 let offset = e0_len;
551 $out[offset] = $e1[0].clone();
552 $out[offset + 1] = $e1[1].clone();
553 $out[offset + 2] = $e1[2].clone();
554 $out[offset + 3] = $e1[3].clone();
555 };
556}
557vertcat_two_args!(VerticalConcatenateMDR4, DMatrix, RowVector4, Matrix4, vertcat_mdv4);
558
559macro_rules! vertcat_mdmd {
560 ($out:expr, $e0:expr, $e1:expr) => {
561 let dest_rows = $out.nrows();
562 let mut offset = 0;
563 let mut dest_ix = 0;
564
565 let src_rows = $e0.nrows();
566 let stride = dest_rows - src_rows;
567 dest_ix = offset;
568 for ix in 0..$e0.len() {
569 $out[dest_ix] = $e0[ix].clone();
570 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
571 }
572 offset += src_rows;
573
574 let src_rows = $e1.nrows();
575 let stride = dest_rows - src_rows;
576 dest_ix = offset;
577 for ix in 0..$e1.len() {
578 $out[dest_ix] = $e1[ix].clone();
579 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
580 }
581 };
582}
583vertcat_two_args!(VerticalConcatenateMDMD, DMatrix, DMatrix, Matrix4, vertcat_mdmd);
584vertcat_two_args!(VerticalConcatenateR4MD, RowVector4, DMatrix, Matrix4, vertcat_mdmd);
585
586
587macro_rules! vertcat_mdmdmd {
588 ($out:expr, $e0:expr, $e1:expr, $e2:expr) => {
589 let dest_rows = $out.nrows();
590 let mut offset = 0;
591 let mut dest_ix = 0;
592
593 let src_rows = $e0.nrows();
594 let stride = dest_rows - src_rows;
595 dest_ix = offset;
596 for ix in 0..$e0.len() {
597 $out[dest_ix] = $e0[ix].clone();
598 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
599 }
600 offset += src_rows;
601
602 let src_rows = $e1.nrows();
603 let stride = dest_rows - src_rows;
604 dest_ix = offset;
605 for ix in 0..$e1.len() {
606 $out[dest_ix] = $e1[ix].clone();
607 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
608 }
609 offset += src_rows;
610
611 let src_rows = $e2.nrows();
612 let stride = dest_rows - src_rows;
613 dest_ix = offset;
614 for ix in 0..$e2.len() {
615 $out[dest_ix] = $e2[ix].clone();
616 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
617 }
618 };
619}
620
621vertcat_three_args!(VerticalConcatenateR2R2R2, RowVector2, RowVector2, RowVector2, Matrix3x2, vertcat_mdmdmd);
622vertcat_three_args!(VerticalConcatenateR3R3R3, RowVector3, RowVector3, RowVector3, Matrix3, vertcat_mdmdmd);
623vertcat_three_args!(VerticalConcatenateR4R4MD, RowVector4, RowVector4, DMatrix, Matrix4, vertcat_mdmdmd);
624vertcat_three_args!(VerticalConcatenateR4MDR4, RowVector4, DMatrix, RowVector4, Matrix4, vertcat_mdmdmd);
625vertcat_three_args!(VerticalConcatenateMDR4R4, DMatrix, RowVector4, RowVector4, Matrix4, vertcat_mdmdmd);
626
627macro_rules! vertcat_mdmdmdmd {
628 ($out:expr, $e0:expr, $e1:expr, $e2:expr, $e3:expr) => {
629 let dest_rows = $out.nrows();
630 let mut offset = 0;
631 let mut dest_ix = 0;
632
633 let src_rows = $e0.nrows();
634 let stride = dest_rows - src_rows;
635 dest_ix = offset;
636 for ix in 0..$e0.len() {
637 $out[dest_ix] = $e0[ix].clone();
638 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
639 }
640 offset += src_rows;
641
642 let src_rows = $e1.nrows();
643 let stride = dest_rows - src_rows;
644 dest_ix = offset;
645 for ix in 0..$e1.len() {
646 $out[dest_ix] = $e1[ix].clone();
647 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
648 }
649 offset += src_rows;
650
651 let src_rows = $e2.nrows();
652 let stride = dest_rows - src_rows;
653 dest_ix = offset;
654 for ix in 0..$e2.len() {
655 $out[dest_ix] = $e2[ix].clone();
656 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
657 }
658 offset += src_rows;
659
660 let src_rows = $e3.nrows();
661 let stride = dest_rows - src_rows;
662 dest_ix = offset;
663 for ix in 0..$e3.len() {
664 $out[dest_ix] = $e3[ix].clone();
665 dest_ix += ((ix + 1) % src_rows == 0) as usize * stride + 1;
666 }
667 };
668}
669
670vertcat_four_args!(VerticalConcatenateR4R4R4R4, RowVector4, RowVector4, RowVector4, RowVector4, Matrix4, vertcat_mdmdmdmd);
671
672macro_rules! impl_vertcat_arms {
673 ($kind:ident, $args:expr, $default:expr) => {
674 paste!{
675 {
676 let arguments = $args;
677 let rows = arguments[0].shape()[0];
678 let rows:usize = arguments.iter().fold(0, |acc, x| acc + x.shape()[0]);
679 let columns:usize = arguments[0].shape()[1];
680 let nargs = arguments.len();
681 let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
682 let no_refs = !kinds.iter().any(|x| {
683 match x {
684 ValueKind::Reference(_) => true,
685 ValueKind::Matrix(_,_) => true,
686 _ => false,
687 }});
688 if no_refs {
689 let mat: Vec<$kind> = arguments.iter().flat_map(|v| v.[<as_vec $kind:lower>]().unwrap()).collect::<Vec<$kind>>();
690 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> {
691 (0..col_n).flat_map(|col| out.iter().map({let value = extract_fn.clone();move |row| value(row).unwrap()[col].clone()})).collect()
692 }
693 let mat = to_column_major(&arguments, rows, columns, |v| v.[<as_vec $kind:lower>]());
694 match (rows,columns) {
695 (2,1) => {return Ok(Box::new(VerticalConcatenateS2{out:new_ref(Vector2::from_vec(mat))}));}
696 (3,1) => {return Ok(Box::new(VerticalConcatenateS3{out:new_ref(Vector3::from_vec(mat))}));}
697 (4,1) => {return Ok(Box::new(VerticalConcatenateS4{out:new_ref(Vector4::from_vec(mat))}));}
698 (m,1) => {return Ok(Box::new(VerticalConcatenateSD{out:new_ref(DVector::from_vec(mat))}));}
699 (2,2) => {return Ok(Box::new(VerticalConcatenateM2{out:new_ref(Matrix2::from_vec(mat))}));}
700 (3,3) => {return Ok(Box::new(VerticalConcatenateM3{out:new_ref(Matrix3::from_vec(mat))}));}
701 (4,4) => {return Ok(Box::new(VerticalConcatenateM4{out:new_ref(Matrix4::from_vec(mat))}));}
702 (2,3) => {return Ok(Box::new(VerticalConcatenateM2x3{out:new_ref(Matrix2x3::from_vec(mat))}));}
703 (3,2) => {return Ok(Box::new(VerticalConcatenateM3x2{out:new_ref(Matrix3x2::from_vec(mat))}));}
704 (m,n) => {return Ok(Box::new(VerticalConcatenateMD{out:new_ref(DMatrix::from_vec(m,n,mat))}));}
705 }
706 } else {
707 match (nargs,rows,columns) {
708 #[cfg(feature = "Vector2")]
709 (1,2,1) => {
710 match &arguments[..] {
711 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0))] => {
713 return Ok(Box::new(VerticalConcatenateV2{out: e0.clone()}));
714 }
715 _ => todo!(),
716 }
717 }
718 #[cfg(feature = "Vector3")]
719 (1,3,1) => {
720 match &arguments[..] {
721 [Value::MutableReference(e0)] => {
723 match *e0.borrow() {
724 Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)) => {
725 return Ok(Box::new(VerticalConcatenateV3{out: e0.clone()}));
726 }
727 _ => todo!(),
728 }
729 }
730 _ => todo!(),
731 }
732 }
733 #[cfg(feature = "Vector4")]
734 (1,4,1) => {
735 match &arguments[..] {
736 [Value::[<Matrix $kind:camel>](Matrix::Vector4(ref e0))] => {
738 return Ok(Box::new(VerticalConcatenateV4{out: e0.clone()}));
739 }
740 _ => todo!(),
741 }
742 }
743 #[cfg(feature = "VectorD")]
744 (1,m,1) => {
745 match &arguments[..] {
746 [Value::[<Matrix $kind:camel>](Matrix::DVector(ref e0))] => {
748 return Ok(Box::new(VerticalConcatenateVD{out: e0.clone()}));
749 }
750 _ => todo!(),
751 }
752 }
753 #[cfg(feature = "Vector2")]
754 (2,2,1) => {
755 let mut out = Vector2::from_element($default);
756 match &arguments[..] {
757 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
759 return Ok(Box::new(VerticalConcatenateM1M1{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
760 }
761 _ => todo!(),
762 }
763 }
764 #[cfg(feature = "Vector3")]
765 (2,3,1) => {
766 let mut out = Vector3::from_element($default);
767 match &arguments[..] {
768 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
770 return Ok(Box::new(VerticalConcatenateM1V2{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
771 }
772 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
774 return Ok(Box::new(VerticalConcatenateV2M1{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
775 }
776 _ => todo!(),
777 }
778 }
779 #[cfg(feature = "Vector4")]
780 (2,4,1) => {
781 let mut out = Vector4::from_element($default);
782 match &arguments[..] {
783 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e1))] => {
785 return Ok(Box::new(VerticalConcatenateM1V3{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
786 }
787 [Value::[<Matrix $kind:camel>](Matrix::Vector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1))] => {
789 return Ok(Box::new(VerticalConcatenateV3M1{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
790 }
791 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1))] => {
793 return Ok(Box::new(VerticalConcatenateV2V2{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
794 }
795 _ => todo!(),
796 }
797 }
798 #[cfg(feature = "VectorD")]
799 (2,m,1) => {
800 let mut out = DVector::from_element(m,$default);
801 match &arguments[..] {
802 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1)] => {
803 let e0 = e0.get_copyable_matrix();
804 let e1 = e1.get_copyable_matrix();
805 return Ok(Box::new(VerticalConcatenateVD2{e0, e1, out: new_ref(out)}));
806 }
807 _ => todo!(),
808 }
809 }
810 #[cfg(feature = "Vector3")]
811 (3,3,1) => {
812 let mut out = Vector3::from_element($default);
813 match &arguments[..] {
814 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)), Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
816 return Ok(Box::new(VerticalConcatenateM1M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: new_ref(out)}));
817 }
818 _ => todo!()
819 }
820 }
821 #[cfg(feature = "Vector4")]
822 (3,4,1) => {
823 let mut out = Vector4::from_element($default);
824 match &arguments[..] {
825 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e2))] => {
827 return Ok(Box::new(VerticalConcatenateM1M1V2{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: new_ref(out)}));
828 }
829 [Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
831 return Ok(Box::new(VerticalConcatenateM1V2M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: new_ref(out)}));
832 }
833 [Value::[<Matrix $kind:camel>](Matrix::Vector2(ref e0)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e1)),Value::[<Matrix $kind:camel>](Matrix::Matrix1(ref e2))] => {
835 return Ok(Box::new(VerticalConcatenateV2M1M1{e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), out: new_ref(out)}));
836 }
837 _ => todo!()
838 }
839 }
840 #[cfg(feature = "VectorD")]
841 (3,m,1) => {
842 let mut out = DVector::from_element(m,$default);
843 match &arguments[..] {
844 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2)] => {
845 let e0 = e0.get_copyable_matrix();
846 let e1 = e1.get_copyable_matrix();
847 let e2 = e2.get_copyable_matrix();
848 return Ok(Box::new(VerticalConcatenateVD3{e0, e1, e2, out: new_ref(out)}));
849 }
850 _ => todo!(),
851 }
852 }
853 #[cfg(feature = "Vector4")]
854 (4,4,1) => {
855 let mut out = Vector4::from_element($default);
856 match &arguments[..] {
857 [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))] => {
859 return Ok(Box::new(VerticalConcatenateM1M1M1M1{ e0: e0.clone(), e1: e1.clone(), e2: e2.clone(), e3: e3.clone(), out: new_ref(out) }));
860 }
861 _ => todo!(),
862 }
863 }
864 #[cfg(feature = "VectorD")]
865 (4,m,1) => {
866 let mut out = DVector::from_element(m,$default);
867 match &arguments[..] {
868 [Value::[<Matrix $kind:camel>](e0),Value::[<Matrix $kind:camel>](e1),Value::[<Matrix $kind:camel>](e2),Value::[<Matrix $kind:camel>](e3)] => {
869 let e0 = e0.get_copyable_matrix();
870 let e1 = e1.get_copyable_matrix();
871 let e2 = e2.get_copyable_matrix();
872 let e3 = e3.get_copyable_matrix();
873 return Ok(Box::new(VerticalConcatenateVD4{e0, e1, e2, e3, out: new_ref(out)}));
874 }
875 _ => todo!(),
876 }
877 }
878 #[cfg(feature = "VectorD")]
879 (l,m,1) => {
880 let mut out = DVector::from_element(m,$default);
881 let mut matrix_args: Vec<(Box<dyn CopyMat<$kind>>,usize)> = vec![];
882 let mut scalar_args: Vec<(Ref<$kind>,usize)> = vec![];
883 let mut i = 0;
884 for arg in arguments.iter() {
885 match &arg {
886 Value::[<$kind:camel>](e0) => {
887 scalar_args.push((e0.clone(),i));
888 i += 1;
889 }
890 Value::[<Matrix $kind:camel>](e0) => {
891 matrix_args.push((e0.get_copyable_matrix(),i));
892 i += e0.shape()[0];
893 }
894 _ => todo!(),
895 }
896 }
897 return Ok(Box::new(VerticalConcatenateVDN{scalar: scalar_args, matrix: matrix_args, out: new_ref(out)}));
898 }
899 #[cfg(feature = "Matrix2")]
900 (2,2,2) => {
901 let mut out = Matrix2::from_element($default);
902 match &arguments[..] {
903 [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: new_ref(out)}));}
905 _ => todo!(),
906 }
907 }
908 #[cfg(feature = "Matrix2x3")]
909 (2,2,3) => {
910 let mut out = Matrix2x3::from_element($default);
911 match &arguments[..] {
912 [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: new_ref(out)}));}
914 _ => todo!(),
915 }
916 }
917 #[cfg(feature = "Matrix3x2")]
918 (2,3,2) => {
919 let mut out = Matrix3x2::from_element($default);
920 match &arguments[..] {
921 [Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e1))] => {
923 return Ok(Box::new(VerticalConcatenateR2M2{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
924 }
925 [Value::[<Matrix $kind:camel>](Matrix::Matrix2(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector2(ref e1))] => {
927 return Ok(Box::new(VerticalConcatenateM2R2{e0: e0.clone(), e1: e1.clone(), out: new_ref(out)}));
928 }
929 _ => todo!(),
930 }
931
932 }
933 #[cfg(feature = "Matrix3")]
934 (2,3,3) => {
935 let mut out = Matrix3::from_element($default);
936 match &arguments[..] {
937 [Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e1))] => {
939 return Ok(Box::new(VerticalConcatenateR3M2x3 { e0: e0.clone(), e1: e1.clone(), out: new_ref(out) }));
940 }
941 [Value::[<Matrix $kind:camel>](Matrix::Matrix2x3(ref e0)), Value::[<Matrix $kind:camel>](Matrix::RowVector3(ref e1))] => {
943 return Ok(Box::new(VerticalConcatenateM2x3R3 { e0: e0.clone(), e1: e1.clone(), out: new_ref(out) }));
944 }
945 _ => todo!(),
946 }
947
948 }
949 #[cfg(feature = "Matrix4")]
950 (2,4,4) => {
951 let mut out = Matrix4::from_element($default);
952 match &arguments[..] {
953 [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:new_ref(out)})),
955 [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:new_ref(out)})),
957 [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:new_ref(out)})),
959 _ => todo!(),
960 }
961
962 }
963 #[cfg(feature = "MatrixD")]
964 (2,m,n) => {
965 let mut out = DMatrix::from_element(m,n,$default);
966 match &arguments[..] {
967 [Value::[<Matrix $kind:camel>](m0), Value::[<Matrix $kind:camel>](m1)] => {
968 let e0 = m0.get_copyable_matrix();
969 let e1 = m1.get_copyable_matrix();
970 Ok(Box::new(VerticalConcatenateTwoArgs{e0, e1, out: new_ref(out)}))
971 }
972 _ => todo!(),
973 }
974 }
975 #[cfg(feature = "Matrix3x2")]
976 (3,3,2) => {
977 let mut out = Matrix3x2::from_element($default);
978 match &arguments[..] {
979 [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:new_ref(out)})),
981 _ => todo!(),
982 }
983 }
984 #[cfg(feature = "Matrix3")]
985 (3,3,3) => {
986 let mut out = Matrix3::from_element($default);
987 match &arguments[..] {
988 [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:new_ref(out)})),
990 _ => todo!(),
991 }
992 }
993 #[cfg(feature = "Matrix4")]
994 (3,4,4) => {
995 let mut out = Matrix4::from_element($default);
996 match &arguments[..] {
997 [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:new_ref(out)})),
999 [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:new_ref(out)})),
1001 [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:new_ref(out)})),
1003 _ => todo!(),
1004 }
1005 }
1006 #[cfg(feature = "MatrixD")]
1007 (3,m,n) => {
1008 let mut out = DMatrix::from_element(m,n,$default);
1009 match &arguments[..] {
1010 [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2)] => {
1011 let e0 = m0.get_copyable_matrix();
1012 let e1 = m1.get_copyable_matrix();
1013 let e2 = m2.get_copyable_matrix();
1014 Ok(Box::new(VerticalConcatenateThreeArgs{e0,e1,e2,out:new_ref(out)}))
1015 }
1016 _ => todo!(),
1017 }
1018 }
1019 #[cfg(feature = "Matrix4")]
1020 (4,4,4) => {
1021 let mut out = Matrix4::from_element($default);
1022 match &arguments[..] {
1023 [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:new_ref(out)})),
1025 _ => todo!(),
1026 }
1027 }
1028 #[cfg(feature = "MatrixD")]
1029 (4,m,n) => {
1030 let mut out = DMatrix::from_element(m,n,$default);
1031 match &arguments[..] {
1032 [Value::[<Matrix $kind:camel>](m0),Value::[<Matrix $kind:camel>](m1),Value::[<Matrix $kind:camel>](m2),Value::[<Matrix $kind:camel>](m3)] => {
1033 let e0 = m0.get_copyable_matrix();
1034 let e1 = m1.get_copyable_matrix();
1035 let e2 = m2.get_copyable_matrix();
1036 let e3 = m3.get_copyable_matrix();
1037 Ok(Box::new(VerticalConcatenateFourArgs{e0,e1,e2,e3,out:new_ref(out)}))
1038 }
1039 _ => todo!(),
1040 }
1041 }
1042 #[cfg(feature = "MatrixD")]
1043 (l,m,n) => {
1044 let mut out = DMatrix::from_element(m,n,$default);
1045 let mut args = vec![];
1046 for arg in arguments {
1047 match arg {
1048 Value::[<Matrix $kind:camel>](m0) => {
1049 let e0 = m0.get_copyable_matrix();
1050 args.push(e0);
1051 }
1052 _ => todo!(),
1053 }
1054 }
1055 Ok(Box::new(VerticalConcatenateNArgs{e0: args, out:new_ref(out)}))
1056 }
1057 _ => {return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind});}
1058 }
1059 }}}}}
1060
1061fn impl_vertcat_fxn(arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1062 let kinds: Vec<ValueKind> = arguments.iter().map(|x| x.kind()).collect::<Vec<ValueKind>>();
1065 let target_kind = kinds[0].clone();
1066 if ValueKind::is_compatible(target_kind.clone(), ValueKind::F64) { impl_vertcat_arms!(F64,arguments,F64::zero())
1067 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::F32) { impl_vertcat_arms!(F32,arguments,F32::zero())
1068 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::U8) { impl_vertcat_arms!(u8,arguments,u8::zero())
1069 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::U16) { impl_vertcat_arms!(u16,arguments,u16::zero())
1070 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::U32) { impl_vertcat_arms!(u32,arguments,u32::zero())
1071 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::U64) { impl_vertcat_arms!(u64,arguments,u64::zero())
1072 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::U128) { impl_vertcat_arms!(u128,arguments,u128::zero())
1073 } else if ValueKind::is_compatible(target_kind.clone(), ValueKind::Bool) { impl_vertcat_arms!(bool,arguments,false)
1074 } else {
1075 todo!();
1076 }
1077}
1078
1079pub struct MaxtrixVertCat {}
1080impl NativeFunctionCompiler for MaxtrixVertCat {
1081 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
1082 impl_vertcat_fxn(arguments)
1085 }
1086}