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> 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 [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 [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 [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 [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 [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 [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 [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 #[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 #[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 #[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 #[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 [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 [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 [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 [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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}