mech_core/
matrix.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
use crate::*;
use crate::types::Ref;
use na::{Vector3, DVector, Vector2, Vector4, RowDVector, Matrix1, Matrix3, Matrix4, RowVector3, RowVector4, RowVector2, DMatrix, Rotation3, Matrix2x3, Matrix3x2, Matrix6, Matrix2};
use tabled::{
    builder::Builder,
    settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
    Tabled,
  };
use std::fmt::Debug;
use std::hash::{Hash, Hasher};

// Matrix ---------------------------------------------------------------------

pub trait ToMatrix: Clone {
  fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self>;
}
  
macro_rules! impl_to_matrix {
  ($t:ty) => {
    impl ToMatrix for $t {
      fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
        match (rows,cols) {
          (1,1) => Matrix::Matrix1(new_ref(Matrix1::from_element(elements[0].clone()))),
          (2,2) => Matrix::Matrix2(new_ref(Matrix2::from_vec(elements))),
          (3,3) => Matrix::Matrix3(new_ref(Matrix3::from_vec(elements))),
          (4,2) => Matrix::Matrix4(new_ref(Matrix4::from_vec(elements))),
          (2,3) => Matrix::Matrix2x3(new_ref(Matrix2x3::from_vec(elements))),
          (3,2) => Matrix::Matrix3x2(new_ref(Matrix3x2::from_vec(elements))),
          (1,2) => Matrix::RowVector2(new_ref(RowVector2::from_vec(elements))),
          (1,3) => Matrix::RowVector3(new_ref(RowVector3::from_vec(elements))),
          (1,4) => Matrix::RowVector4(new_ref(RowVector4::from_vec(elements))),
          (2,1) => Matrix::Vector2(new_ref(Vector2::from_vec(elements))),
          (3,1) => Matrix::Vector3(new_ref(Vector3::from_vec(elements))),
          (4,1) => Matrix::Vector4(new_ref(Vector4::from_vec(elements))),
          (1,n) => Matrix::RowDVector(new_ref(RowDVector::from_vec(elements))),
          (m,1) => Matrix::DVector(new_ref(DVector::from_vec(elements))),
          (m,n) => Matrix::DMatrix(new_ref(DMatrix::from_vec(m,n,elements))),
        }}}};}

impl ToMatrix for usize {
  fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
    match (rows,cols) {
      (1,n) => Matrix::RowDVector(new_ref(RowDVector::from_vec(elements))),
      (m,1) => Matrix::DVector(new_ref(DVector::from_vec(elements))),
      (m,n) => Matrix::DMatrix(new_ref(DMatrix::from_vec(m,n,elements))),
    }
  }
}

impl_to_matrix!(Value);
impl_to_matrix!(bool);
impl_to_matrix!(u8);
impl_to_matrix!(u16);
impl_to_matrix!(u32);
impl_to_matrix!(u64);
impl_to_matrix!(u128);
impl_to_matrix!(i8);
impl_to_matrix!(i16);
impl_to_matrix!(i32);
impl_to_matrix!(i64);
impl_to_matrix!(i128);
impl_to_matrix!(F32);
impl_to_matrix!(F64);
  
pub trait ToIndex: Clone {
  fn to_index(elements: Vec<Self>) -> Matrix<Self>;
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Matrix<T> {
  RowVector2(Ref<RowVector2<T>>),
  RowVector3(Ref<RowVector3<T>>),
  RowVector4(Ref<RowVector4<T>>),
  Vector2(Ref<Vector2<T>>),
  Vector3(Ref<Vector3<T>>),
  Vector4(Ref<Vector4<T>>),  
  Matrix1(Ref<Matrix1<T>>),
  Matrix2(Ref<Matrix2<T>>),
  Matrix3(Ref<Matrix3<T>>),
  Matrix4(Ref<Matrix4<T>>),
  Matrix2x3(Ref<Matrix2x3<T>>),
  Matrix3x2(Ref<Matrix3x2<T>>),
  DMatrix(Ref<DMatrix<T>>),
  DVector(Ref<DVector<T>>),
  RowDVector(Ref<RowDVector<T>>),
}
  
impl<T> Hash for Matrix<T> 
where T: Hash + na::Scalar
{
  fn hash<H: Hasher>(&self, state: &mut H) {
    match self {
      Matrix::RowVector2(x) => x.borrow().hash(state),
      Matrix::RowVector3(x) => x.borrow().hash(state),
      Matrix::RowVector4(x) => x.borrow().hash(state),
      Matrix::Vector2(x) => x.borrow().hash(state),
      Matrix::Vector3(x) => x.borrow().hash(state),
      Matrix::Vector4(x) => x.borrow().hash(state),
      Matrix::Matrix1(x) => x.borrow().hash(state),
      Matrix::Matrix2(x) => x.borrow().hash(state),
      Matrix::Matrix3(x) => x.borrow().hash(state),
      Matrix::Matrix4(x) => x.borrow().hash(state),
      Matrix::Matrix2x3(x) => x.borrow().hash(state),
      Matrix::Matrix3x2(x) => x.borrow().hash(state),
      Matrix::DMatrix(x) => x.borrow().hash(state),
      Matrix::RowDVector(x) => x.borrow().hash(state),
      Matrix::DVector(x) => x.borrow().hash(state),
    }
  }
}

impl<T> Matrix<T> 
where T: Debug + Clone + PartialEq + 'static
{

  pub fn pretty_print(&self) -> String {
    let mut builder = Builder::default();
    match self {
      Matrix::RowVector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::RowVector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::RowVector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Vector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Vector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Vector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix1(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix2x3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::Matrix3x2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::DMatrix(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::RowDVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      Matrix::DVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()));}
      _ => todo!(),
    };
    let mut table = builder.build();
    table.with(Style::modern());
    format!("{table}")
  }

  pub fn shape(&self) -> Vec<usize> {
    let shape = match self {
      Matrix::RowVector2(x) => x.borrow().shape(),
      Matrix::RowVector3(x) => x.borrow().shape(),
      Matrix::RowVector4(x) => x.borrow().shape(),
      Matrix::Vector2(x) => x.borrow().shape(),
      Matrix::Vector3(x) => x.borrow().shape(),
      Matrix::Vector4(x) => x.borrow().shape(),
      Matrix::Matrix1(x) => x.borrow().shape(),
      Matrix::Matrix2(x) => x.borrow().shape(),
      Matrix::Matrix3(x) => x.borrow().shape(),
      Matrix::Matrix4(x) => x.borrow().shape(),
      Matrix::Matrix2x3(x) => x.borrow().shape(),
      Matrix::Matrix3x2(x) => x.borrow().shape(),
      Matrix::DMatrix(x) => x.borrow().shape(),
      Matrix::RowDVector(x) => x.borrow().shape(),
      Matrix::DVector(x) => x.borrow().shape(),
    };
    vec![shape.0, shape.1]
  }

  pub fn index1d(&self, ix: usize) -> T {
    match self {
      Matrix::RowVector2(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::RowVector3(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::RowVector4(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Vector2(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Vector3(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Vector4(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix1(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix2(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix3(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix4(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix2x3(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::Matrix3x2(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::DMatrix(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::RowDVector(x) => (*x.borrow().index(ix-1)).clone(),
      Matrix::DVector(x) => (*x.borrow().index(ix-1)).clone(),
    }
  }

  pub fn index2d(&self, row: usize, col: usize) -> T {
    match self {
      Matrix::RowVector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::RowVector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::RowVector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Vector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Vector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Vector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix1(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix2(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix3(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix4(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix2x3(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::Matrix3x2(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::DMatrix(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::RowDVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
      Matrix::DVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
    }
  }

  pub fn as_vec(&self) -> Vec<T> {
    match self {
      Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(),
      Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(),
      Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(),
      Matrix::Vector2(x) => x.borrow().as_slice().to_vec(),
      Matrix::Vector3(x) => x.borrow().as_slice().to_vec(),
      Matrix::Vector4(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(),
      Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(),
      Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(),
      Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(),
      Matrix::DVector(x) => x.borrow().as_slice().to_vec(),
    }
  }
}


impl ToValue for Matrix<Value> {

  fn to_value(&self) -> Value {
    Value::MatrixValue(self.clone())
  }
  
}