opensrdk_linear_algebra/macros/
stack.rs1use crate::{macros::sub_matrix::SubMatrix, number::Number, Matrix};
2
3#[macro_export]
4macro_rules! stack_v {
5 ($e: expr) => {{
6 use $crate::macros::stack::Stack;
7 Stack::Vertical($e)
8 }};
9}
10
11#[macro_export]
12macro_rules! stack_h {
13 ($e: expr) => {{
14 use $crate::macros::stack::Stack;
15 Stack::Horizontal($e)
16 }};
17}
18
19#[macro_export]
20macro_rules! stack {
21 ($e: expr) => {
22 {
23 use $crate::macros::stack::Stack;
24 Stack::Only(Box::new($e))
25 }
26 };
27 ($($e: expr),+) => {
28 {
29 use $crate::stack_h;
30 stack_h!(vec![$(stack!($e)),+])
31 }
32 };
33 ($($($e: expr),+);+) => {
34 {
35 use $crate::stack_v;
36 stack_v!(vec![$(stack!($($e),+)),+])
37 }
38 };
39}
40
41pub enum Stack<'a, T: Number> {
42 Only(Box<dyn SubMatrix<T> + 'a>),
43 Horizontal(Vec<Stack<'a, T>>),
44 Vertical(Vec<Stack<'a, T>>),
45}
46
47impl<'a, T> Stack<'a, T>
48where
49 T: Number,
50{
51 pub fn matrix(&self) -> Matrix<T> {
52 let size = self.size();
53 let mut matrix = Matrix::<T>::new(size.0, size.1);
54 self.transcript(&mut matrix, 0, 0);
55
56 matrix
57 }
58
59 fn size(&self) -> (usize, usize) {
60 match self {
61 Stack::Only(sub_matrix) => sub_matrix.size(),
62 Stack::Horizontal(vec) => {
63 let mut rows = 0usize;
64 let mut columns = 0usize;
65
66 for e in vec.iter() {
67 let size = e.size();
68
69 if rows == 0 {
70 rows = size.0;
71 } else if rows != size.0 {
72 panic!("Dimension mismatch.")
73 }
74
75 columns += size.1;
76 }
77
78 (rows, columns)
79 }
80 Stack::Vertical(vec) => {
81 let mut rows = 0usize;
82 let mut columns = 0usize;
83
84 for e in vec.iter() {
85 let size = e.size();
86
87 if columns == 0 {
88 columns = size.1;
89 } else if columns != size.1 {
90 panic!("Dimension mismatch.")
91 }
92
93 rows += size.0;
94 }
95
96 (rows, columns)
97 }
98 }
99 }
100
101 fn transcript(&self, matrix: &mut Matrix<T>, i: usize, j: usize) -> (usize, usize) {
102 match self {
103 Stack::Only(sub_matrix) => {
104 let size = sub_matrix.size();
105
106 for l in 0..size.1 {
107 for k in 0..size.0 {
108 matrix[j + l][i + k] = sub_matrix.index(k, l);
109 }
110 }
111
112 size
113 }
114 Stack::Horizontal(vec) => {
115 let mut size = (0usize, 0usize);
116
117 for e in vec.iter() {
118 let s = e.transcript(matrix, i, j + size.1);
119 size.0 = s.0;
120 size.1 += s.1;
121 }
122
123 size
124 }
125 Stack::Vertical(vec) => {
126 let mut size = (0usize, 0usize);
127
128 for e in vec.iter() {
129 let s = e.transcript(matrix, i + size.0, j);
130 size.0 += s.0;
131 size.1 = s.1;
132 }
133
134 size
135 }
136 }
137 }
138}