mech_core/structures/
matrix.rs

1use crate::*;
2
3#[cfg(feature = "no_std")]
4use core::any::Any;
5#[cfg(not(feature = "no_std"))]
6use std::any::Any;
7
8use nalgebra::{DMatrix, DVector, RowDVector};
9
10// Matrix ---------------------------------------------------------------------
11
12pub trait ToMatrix: Clone {
13  fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self>;
14  fn to_matrixd(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self>;
15}
16  
17macro_rules! impl_to_matrix {
18  ($t:ty) => {
19    impl ToMatrix for $t {
20      fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
21        match (rows,cols) {
22          #[cfg(feature = "matrix1")]
23          (1,1) => Matrix::Matrix1(Ref::new(Matrix1::from_element(elements[0].clone()))),
24          #[cfg(feature = "matrix2")]
25          (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_vec(elements))),
26          #[cfg(feature = "matrix3")]
27          (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_vec(elements))),
28          #[cfg(feature = "matrix4")]
29          (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_vec(elements))),
30          #[cfg(feature = "matrix2x3")]
31          (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_vec(elements))),
32          #[cfg(feature = "matrix3x2")]
33          (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_vec(elements))),
34          #[cfg(feature = "row_vector2")]
35          (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_vec(elements))),
36          #[cfg(feature = "row_vector3")]
37          (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_vec(elements))),
38          #[cfg(feature = "row_vector4")]
39          (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_vec(elements))),
40          #[cfg(feature = "vector2")]
41          (2,1) => Matrix::Vector2(Ref::new(Vector2::from_vec(elements))),
42          #[cfg(feature = "vector3")]
43          (3,1) => Matrix::Vector3(Ref::new(Vector3::from_vec(elements))),
44          #[cfg(feature = "vector4")]
45          (4,1) => Matrix::Vector4(Ref::new(Vector4::from_vec(elements))),
46          (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
47          (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
48          (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
49          _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
50        }
51      }
52      fn to_matrixd(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
53        match (rows,cols) {
54          (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
55          (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
56          (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
57          _ => panic!("Cannot convert to matrixd with rows: {rows} and cols: {cols}"),
58        }
59      }
60    }
61  };    
62}
63
64impl ToMatrix for usize {
65  fn to_matrix(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
66    match (rows,cols) {
67      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
68      (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
69      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
70      _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
71    }
72  }
73  fn to_matrixd(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
74    match (rows,cols) {
75      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
76      (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
77      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
78      _ => panic!("Cannot convert to matrixd with rows: {rows} and cols: {cols}"),
79    }
80  }
81}
82
83impl_to_matrix!(Value);
84#[cfg(feature = "bool")]
85impl_to_matrix!(bool);
86#[cfg(feature = "u8")]
87impl_to_matrix!(u8);
88#[cfg(feature = "u16")]
89impl_to_matrix!(u16);
90#[cfg(feature = "u32")]
91impl_to_matrix!(u32);
92#[cfg(feature = "u64")]
93impl_to_matrix!(u64);
94#[cfg(feature = "u128")]
95impl_to_matrix!(u128);
96#[cfg(feature = "i8")]
97impl_to_matrix!(i8);
98#[cfg(feature = "i16")]
99impl_to_matrix!(i16);
100#[cfg(feature = "i32")]
101impl_to_matrix!(i32);
102#[cfg(feature = "i64")]
103impl_to_matrix!(i64);
104#[cfg(feature = "i128")]
105impl_to_matrix!(i128);
106#[cfg(feature = "f32")]
107impl_to_matrix!(F32);
108#[cfg(feature = "f64")]
109impl_to_matrix!(F64);
110#[cfg(feature = "string")]
111impl_to_matrix!(String);
112#[cfg(feature = "complex")]
113impl_to_matrix!(ComplexNumber);
114#[cfg(feature = "rational")]
115impl_to_matrix!(RationalNumber);
116  
117pub trait ToIndex: Clone {
118  fn to_index(elements: Vec<Self>) -> Matrix<Self>;
119}
120
121#[derive(Clone, Debug, PartialEq, Eq)]
122pub enum Matrix<T> {
123  #[cfg(feature = "row_vector4")]
124  RowVector4(Ref<RowVector4<T>>),
125  #[cfg(feature = "row_vector3")]
126  RowVector3(Ref<RowVector3<T>>),
127  #[cfg(feature = "row_vector2")]
128  RowVector2(Ref<RowVector2<T>>),
129  #[cfg(feature = "vector4")]
130  Vector4(Ref<Vector4<T>>),  
131  #[cfg(feature = "vector3")]
132  Vector3(Ref<Vector3<T>>),
133  #[cfg(feature = "vector2")]
134  Vector2(Ref<Vector2<T>>),
135  #[cfg(feature = "matrix4")]
136  Matrix4(Ref<Matrix4<T>>),
137  #[cfg(feature = "matrix3")]
138  Matrix3(Ref<Matrix3<T>>),
139  #[cfg(feature = "matrix2")]
140  Matrix2(Ref<Matrix2<T>>),
141  #[cfg(feature = "matrix1")]
142  Matrix1(Ref<Matrix1<T>>),
143  #[cfg(feature = "matrix3x2")]
144  Matrix3x2(Ref<Matrix3x2<T>>),
145  #[cfg(feature = "matrix2x3")]
146  Matrix2x3(Ref<Matrix2x3<T>>),
147  DVector(Ref<DVector<T>>),
148  RowDVector(Ref<RowDVector<T>>),
149  DMatrix(Ref<DMatrix<T>>),
150}
151
152pub trait CopyMat<T> {
153  fn copy_into(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize;
154  fn copy_into_v(&self, dst: &Ref<DVector<T>>, offset: usize) -> usize;
155  fn copy_into_r(&self, dst: &Ref<RowDVector<T>>, offset: usize) -> usize;
156  fn copy_into_row_major(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize;
157}
158
159macro_rules! copy_mat {
160  ($matsize:ident) => {
161    impl<T> CopyMat<T> for Ref<$matsize<T>> 
162    where T: Clone 
163    {
164      fn copy_into(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize {
165        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
166        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
167        for i in 0..src_ptr.len() {
168            dst_ptr[i + offset] = src_ptr[i].clone();
169        }
170        src_ptr.len()
171      }
172      fn copy_into_v(&self, dst: &Ref<DVector<T>>, offset: usize) -> usize {
173        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
174        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
175        for i in 0..src_ptr.len() {
176            dst_ptr[i + offset] = src_ptr[i].clone();
177        }
178        src_ptr.len()
179      }
180      fn copy_into_r(&self, dst: &Ref<RowDVector<T>>, offset: usize) -> usize {
181        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
182        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
183        for i in 0..src_ptr.len() {
184            dst_ptr[i + offset] = src_ptr[i].clone();
185        }
186        src_ptr.len()
187      }
188      fn copy_into_row_major(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize {
189        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
190        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
191        let src_rows = src_ptr.nrows();
192        let dest_rows = dst_ptr.nrows();
193
194        let stride = dest_rows - src_rows;
195        let mut offset = offset;
196        for ix in 0..src_ptr.len() {
197            dst_ptr[offset] = src_ptr[ix].clone();
198            offset += ((ix + 1) % src_rows == 0) as usize * stride + 1;
199        }
200        src_rows
201      }}};}
202      
203#[cfg(feature = "matrix1")]
204copy_mat!(Matrix1);
205#[cfg(feature = "matrix2")]
206copy_mat!(Matrix2);
207#[cfg(feature = "matrix3")]
208copy_mat!(Matrix3);
209#[cfg(feature = "matrix4")]
210copy_mat!(Matrix4);
211#[cfg(feature = "matrix2x3")]
212copy_mat!(Matrix2x3);
213#[cfg(feature = "matrix3x2")]
214copy_mat!(Matrix3x2);
215#[cfg(feature = "vector2")]
216copy_mat!(Vector2);
217#[cfg(feature = "vector3")]
218copy_mat!(Vector3);
219#[cfg(feature = "vector4")]
220copy_mat!(Vector4);
221#[cfg(feature = "row_vector2")]
222copy_mat!(RowVector2);
223#[cfg(feature = "row_vector3")]
224copy_mat!(RowVector3);
225#[cfg(feature = "row_vector4")]
226copy_mat!(RowVector4);
227
228copy_mat!(DVector);
229copy_mat!(DMatrix);
230copy_mat!(RowDVector);
231
232impl<T> Hash for Matrix<T> 
233where T: Hash + nalgebra::Scalar
234{
235  fn hash<H: Hasher>(&self, state: &mut H) {
236    match self {
237      #[cfg(feature = "row_vector4")]
238      Matrix::RowVector4(x) => x.borrow().hash(state),
239      #[cfg(feature = "row_vector3")]
240      Matrix::RowVector3(x) => x.borrow().hash(state),
241      #[cfg(feature = "row_vector2")]
242      Matrix::RowVector2(x) => x.borrow().hash(state),
243      #[cfg(feature = "vector4")]
244      Matrix::Vector4(x) => x.borrow().hash(state),
245      #[cfg(feature = "vector3")]
246      Matrix::Vector3(x) => x.borrow().hash(state),
247      #[cfg(feature = "vector2")]
248      Matrix::Vector2(x) => x.borrow().hash(state),
249
250      #[cfg(feature = "matrix4")]
251      Matrix::Matrix4(x) => x.borrow().hash(state),
252      #[cfg(feature = "matrix3")]
253      Matrix::Matrix3(x) => x.borrow().hash(state),
254      #[cfg(feature = "matrix2")]
255      Matrix::Matrix2(x) => x.borrow().hash(state),
256      #[cfg(feature = "matrix1")]
257      Matrix::Matrix1(x) => x.borrow().hash(state),
258      #[cfg(feature = "matrix3x2")]
259      Matrix::Matrix3x2(x) => x.borrow().hash(state),
260      #[cfg(feature = "matrix2x3")]
261      Matrix::Matrix2x3(x) => x.borrow().hash(state),
262      Matrix::DVector(x) => x.borrow().hash(state),
263      Matrix::RowDVector(x) => x.borrow().hash(state),
264      Matrix::DMatrix(x) => x.borrow().hash(state),
265      _ => panic!("Hashing not implemented for this matrix type"),
266    }
267  }
268}
269
270#[cfg(feature = "pretty_print")]
271impl<T> PrettyPrint for Matrix<T>
272where T: Debug + Display + Clone + PartialEq + 'static + PrettyPrint
273{
274  fn pretty_print(&self) -> String {
275    let mut builder = Builder::default();
276    match self {
277      #[cfg(feature = "row_vector4")]
278      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| x.pretty_print()).collect::<Vec<_>>()));}
279      #[cfg(feature = "row_vector3")]
280      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| x.pretty_print()).collect::<Vec<_>>()));}
281      #[cfg(feature = "row_vector2")]
282      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| x.pretty_print()).collect::<Vec<_>>()));}
283      Matrix::RowDVector(vec) => {
284        let vec_brrw = vec.borrow();
285        let vec_str = if vec_brrw.ncols() > 20 {
286          let mut vec_str = vec_brrw.row(0).iter().take(10).chain(vec_brrw.row(0).iter().rev().take(9).rev()).map(|x| x.pretty_print()).collect::<Vec<_>>();
287          vec_str.insert(10,"...".to_string());
288          vec_str
289        } else {
290          vec_brrw.row(0).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()
291        };
292        builder.push_record(vec_str);
293      }
294      #[cfg(feature = "vector4")]
295      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| x.pretty_print()).collect::<Vec<_>>()));}
296      #[cfg(feature = "vector3")]
297      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| x.pretty_print()).collect::<Vec<_>>()));}
298      #[cfg(feature = "vector2")]
299      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| x.pretty_print()).collect::<Vec<_>>()));}
300      Matrix::DVector(vec) => {
301        let vec_brrw = vec.borrow();
302        let vec_str = if vec_brrw.nrows() > 20 {
303          let mut vec_str = vec_brrw.column(0).iter().take(10).chain(vec_brrw.column(0).iter().rev().take(9).rev()).map(|x| x.pretty_print()).collect::<Vec<_>>();
304          vec_str.insert(10,"...".to_string());
305          vec_str
306        } else {
307          vec_brrw.column(0).iter().map(|x| x.pretty_print()).collect::<Vec<_>>()
308        };
309        for r in vec_str {
310          builder.push_record(vec![r]);
311        }
312      }
313      #[cfg(feature = "matrix4")]
314      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| x.pretty_print()).collect::<Vec<_>>()));}
315      #[cfg(feature = "matrix3")]
316      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| x.pretty_print()).collect::<Vec<_>>()));}
317      #[cfg(feature = "matrix2")]
318      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| x.pretty_print()).collect::<Vec<_>>()));}
319      #[cfg(feature = "matrix1")]
320      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| x.pretty_print()).collect::<Vec<_>>()));}
321      #[cfg(feature = "matrix3x2")]
322      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| x.pretty_print()).collect::<Vec<_>>()));}
323      #[cfg(feature = "matrix2x3")]
324      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| x.pretty_print()).collect::<Vec<_>>()));}
325      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| x.pretty_print()).collect::<Vec<_>>()));}
326      _ => todo!(),
327    };
328    let matrix_style = Style::empty()
329      .top(' ')
330      .left('┃')
331      .right('┃')
332      .bottom(' ')
333      .vertical(' ')
334      .intersection_bottom(' ')
335      .corner_top_left('┏')
336      .corner_top_right('┓')
337      .corner_bottom_left('┗')
338      .corner_bottom_right('┛');
339    let mut table = builder.build();
340    table.with(matrix_style);
341    format!("{table}")
342  }
343}
344
345fn quoted<T: Display + Any>(val: &T) -> String {
346  if let Some(s) = (val as &dyn Any).downcast_ref::<String>() {
347    format!("<div class='mech-string'>\"{}\"</div>", s)
348  } else if let Some(s) = (val as &dyn Any).downcast_ref::<bool>() {
349    format!("<div class='mech-boolean'>{}</div<", s)
350  } else {
351    format!("<div class='mech-number'>{}</div>", val)
352  }
353}
354
355impl<T> Matrix<T> 
356where T: Debug + Display + Clone + PartialEq + 'static + PrettyPrint
357{
358
359  pub fn to_html(&self) -> String {
360    let size = self.shape();
361    let mut html = String::new();
362    html.push_str("<table class='mech-matrix'>");
363    for i in 0..size[0] {
364      html.push_str("<tr>");
365      for j in 0..size[1] {
366        let value = self.index2d(i+1, j+1);
367        html.push_str(&format!("<td>{}</td>", quoted(&value)));
368      }
369      html.push_str("</tr>");
370    }
371    format!("<div class='mech-matrix-outer'><div class='mech-matrix-inner'></div>{}</div>", html)
372  }
373
374}
375
376impl<T> Matrix<T> 
377where T: Debug + Clone + PartialEq + 'static
378{
379
380  pub fn append(&mut self, other: &Matrix<T>) -> MResult<()> {
381    match (self, other) {
382      (Matrix::DVector(lhs), Matrix::DVector(rhs)) => {
383        let mut lhs = lhs.borrow_mut();
384        let rhs = rhs.borrow();
385        let old_len = lhs.len();
386        lhs.resize_vertically_mut(old_len + rhs.len(), rhs[0].clone());
387        for (i, val) in rhs.iter().enumerate() {
388          lhs[old_len + i] = val.clone();
389        }
390        Ok(())
391      }
392      (Matrix::RowDVector(lhs), Matrix::RowDVector(rhs)) => {
393        let mut lhs = lhs.borrow_mut();
394        let rhs = rhs.borrow();
395        let old_len = lhs.len();
396        lhs.resize_horizontally_mut(old_len + rhs.len(), rhs[0].clone());
397        for (i, val) in rhs.iter().enumerate() {
398          lhs[old_len + i] = val.clone();
399        }
400        Ok(())
401      }
402      _ => {
403        return Err(MechError{
404          id: line!(),
405          file: file!().to_string(),
406          tokens: vec![],
407          msg: "".to_string(),
408          kind: MechErrorKind::None,
409        });
410      }    
411    }
412  }
413
414  pub fn push(&mut self, value: T) -> MResult<()> {
415    match self {
416      Matrix::RowDVector(vec) => {
417          let mut vec = vec.borrow_mut();
418          let new_len = vec.ncols() + 1;
419          vec.resize_horizontally_mut(new_len, value.clone()); // row vector: increase columns
420          Ok(())
421      }
422      Matrix::DVector(vec) => {
423          let mut vec = vec.borrow_mut();
424          let new_len = vec.nrows() + 1;
425          vec.resize_vertically_mut(new_len, value.clone()); // column vector: increase rows
426          Ok(())
427      }
428      _ => {
429        return Err(MechError{
430          id: line!(),
431          file: file!().to_string(),
432          tokens: vec![],
433          msg: "".to_string(),
434          kind: MechErrorKind::None,
435        });
436      }
437    }
438  }
439
440  pub fn rows(&self) -> usize {
441    let size = self.shape();
442    size[0]
443  }
444
445  pub fn cols(&self) -> usize {
446    let size = self.shape();
447    size[1]
448  }
449
450  pub fn size_of(&self) -> usize {
451    let vec = self.as_vec();
452    vec.capacity() * size_of::<T>()
453  }       
454
455  pub fn resize_vertically(&mut self, new_size: usize, fill_value: T) -> MResult<()> {
456    match self {
457      Matrix::RowDVector(vec) => {
458        let mut vec = vec.borrow_mut();
459        vec.resize_horizontally_mut(new_size, fill_value);
460        Ok(())
461      }
462      Matrix::DVector(vec) => {
463        let mut vec = vec.borrow_mut();
464        vec.resize_vertically_mut(new_size, fill_value);
465        Ok(())
466      }
467      _ => {
468        return Err(MechError{
469          id: line!(),
470          file: file!().to_string(),
471          tokens: vec![],
472          msg: "".to_string(),
473          kind: MechErrorKind::None,
474        });
475      }
476    }
477  }
478
479  pub fn get_copyable_matrix(&self) -> Box<dyn CopyMat<T>> {
480    match self {
481      #[cfg(feature = "row_vector4")]
482      Matrix::RowVector4(ref x) => Box::new(x.clone()),
483      #[cfg(feature = "row_vector3")]
484      Matrix::RowVector3(ref x) => Box::new(x.clone()),
485      #[cfg(feature = "row_vector2")]
486      Matrix::RowVector2(ref x) => Box::new(x.clone()),
487      Matrix::RowDVector(ref x) => Box::new(x.clone()),
488      #[cfg(feature = "vector4")]
489      Matrix::Vector4(ref x) => Box::new(x.clone()),
490      #[cfg(feature = "vector3")]
491      Matrix::Vector3(ref x) => Box::new(x.clone()),
492      #[cfg(feature = "vector2")]
493      Matrix::Vector2(ref x) => Box::new(x.clone()),
494      Matrix::DVector(ref x) => Box::new(x.clone()),
495      #[cfg(feature = "matrix4")]
496      Matrix::Matrix4(ref x) => Box::new(x.clone()),
497      #[cfg(feature = "matrix3")]
498      Matrix::Matrix3(ref x) => Box::new(x.clone()),
499      #[cfg(feature = "matrix2")]
500      Matrix::Matrix2(ref x) => Box::new(x.clone()),
501      #[cfg(feature = "matrix1")]
502      Matrix::Matrix1(ref x) => Box::new(x.clone()),
503      #[cfg(feature = "matrix3x2")]
504      Matrix::Matrix3x2(ref x) => Box::new(x.clone()),
505      #[cfg(feature = "matrix2x3")]
506      Matrix::Matrix2x3(ref x) => Box::new(x.clone()),
507      Matrix::DMatrix(ref x) => Box::new(x.clone()),
508      _ => panic!("Unsupported matrix size"),
509    }
510  }
511
512  pub fn shape(&self) -> Vec<usize> {
513    let shape = match self {
514      #[cfg(feature = "row_vector4")]
515      Matrix::RowVector4(x) => x.borrow().shape(),
516      #[cfg(feature = "row_vector3")]
517      Matrix::RowVector3(x) => x.borrow().shape(),
518      #[cfg(feature = "row_vector2")]
519      Matrix::RowVector2(x) => x.borrow().shape(),
520      Matrix::RowDVector(x) => x.borrow().shape(),
521      #[cfg(feature = "vector4")]
522      Matrix::Vector4(x) => x.borrow().shape(),
523      #[cfg(feature = "vector3")]
524      Matrix::Vector3(x) => x.borrow().shape(),
525      #[cfg(feature = "vector2")]
526      Matrix::Vector2(x) => x.borrow().shape(),
527      Matrix::DVector(x) => x.borrow().shape(),
528      #[cfg(feature = "matrix4")]
529      Matrix::Matrix4(x) => x.borrow().shape(),
530      #[cfg(feature = "matrix3")]
531      Matrix::Matrix3(x) => x.borrow().shape(),
532      #[cfg(feature = "matrix2")]
533      Matrix::Matrix2(x) => x.borrow().shape(),
534      #[cfg(feature = "matrix1")]
535      Matrix::Matrix1(x) => x.borrow().shape(),
536      #[cfg(feature = "matrix3x2")]
537      Matrix::Matrix3x2(x) => x.borrow().shape(),
538      #[cfg(feature = "matrix2x3")]
539      Matrix::Matrix2x3(x) => x.borrow().shape(),
540      Matrix::DMatrix(x) => x.borrow().shape(),
541      _ => panic!("Unsupported matrix size"),
542    };
543    vec![shape.0, shape.1]
544  }
545
546  pub fn index1d(&self, ix: usize) -> T {
547    match self {
548      #[cfg(feature = "row_vector4")]
549      Matrix::RowVector4(x) => (*x.borrow().index(ix-1)).clone(),
550      #[cfg(feature = "row_vector3")]
551      Matrix::RowVector3(x) => (*x.borrow().index(ix-1)).clone(),
552      #[cfg(feature = "row_vector2")]
553      Matrix::RowVector2(x) => (*x.borrow().index(ix-1)).clone(),
554      Matrix::RowDVector(x) => (*x.borrow().index(ix-1)).clone(),
555      #[cfg(feature = "vector4")]
556      Matrix::Vector4(x) => (*x.borrow().index(ix-1)).clone(),
557      #[cfg(feature = "vector3")]
558      Matrix::Vector3(x) => (*x.borrow().index(ix-1)).clone(),
559      #[cfg(feature = "vector2")]
560      Matrix::Vector2(x) => (*x.borrow().index(ix-1)).clone(),
561      Matrix::DVector(x) => (*x.borrow().index(ix-1)).clone(),
562      #[cfg(feature = "matrix4")]
563      Matrix::Matrix4(x) => (*x.borrow().index(ix-1)).clone(),
564      #[cfg(feature = "matrix3")]
565      Matrix::Matrix3(x) => (*x.borrow().index(ix-1)).clone(),
566      #[cfg(feature = "matrix2")]
567      Matrix::Matrix2(x) => (*x.borrow().index(ix-1)).clone(),
568      #[cfg(feature = "matrix1")]
569      Matrix::Matrix1(x) => (*x.borrow().index(ix-1)).clone(),
570      #[cfg(feature = "matrix3x2")]
571      Matrix::Matrix3x2(x) => (*x.borrow().index(ix-1)).clone(),
572      #[cfg(feature = "matrix2x3")]
573      Matrix::Matrix2x3(x) => (*x.borrow().index(ix-1)).clone(),
574      Matrix::DMatrix(x) => (*x.borrow().index(ix-1)).clone(),
575      _ => panic!("Unsupported matrix size"),
576    }
577  }
578
579  pub fn set_index1d(&self, index: usize, value: T) {
580    match self {
581      #[cfg(feature = "row_vector4")]
582      Matrix::RowVector4(v) => v.borrow_mut()[index] = value,
583      #[cfg(feature = "row_vector3")]
584      Matrix::RowVector3(v) => v.borrow_mut()[index] = value,
585      #[cfg(feature = "row_vector2")]
586      Matrix::RowVector2(v) => v.borrow_mut()[index] = value,
587      Matrix::RowDVector(v) => v.borrow_mut()[index] = value,
588      #[cfg(feature = "vector4")]
589      Matrix::Vector4(v) => v.borrow_mut()[index] = value,
590      #[cfg(feature = "vector3")]
591      Matrix::Vector3(v) => v.borrow_mut()[index] = value,
592      #[cfg(feature = "vector2")]
593      Matrix::Vector2(v) => v.borrow_mut()[index] = value,
594      Matrix::DVector(v) => v.borrow_mut()[index] = value,
595      #[cfg(feature = "matrix1")]
596      Matrix::Matrix1(m) => m.borrow_mut()[index] = value,
597      #[cfg(feature = "matrix2")]
598      Matrix::Matrix2(m) => m.borrow_mut()[index] = value,
599      #[cfg(feature = "matrix3")]
600      Matrix::Matrix3(m) => m.borrow_mut()[index] = value,
601      #[cfg(feature = "matrix4")]
602      Matrix::Matrix4(m) => m.borrow_mut()[index] = value,
603      #[cfg(feature = "matrix2x3")]
604      Matrix::Matrix2x3(m) => m.borrow_mut()[index] = value,
605      #[cfg(feature = "matrix3x2")]
606      Matrix::Matrix3x2(m) => m.borrow_mut()[index] = value,
607      Matrix::DMatrix(m) => m.borrow_mut()[index] = value,
608      _ => panic!("Unsupported matrix size"),
609    }
610  }
611
612  pub fn set(&self, elements: Vec<T>) {
613    match self {
614      #[cfg(feature = "row_vector4")]
615      Matrix::RowVector4(x) => {
616        let mut x = x.borrow_mut();
617        x[0] = elements[0].clone();
618        x[1] = elements[1].clone();
619        x[2] = elements[2].clone();
620        x[3] = elements[3].clone();
621      }
622      #[cfg(feature = "row_vector3")]
623      Matrix::RowVector3(x) => {
624        let mut x = x.borrow_mut();
625        x[0] = elements[0].clone();
626        x[1] = elements[1].clone();
627        x[2] = elements[2].clone();
628      }
629      #[cfg(feature = "row_vector2")]
630      Matrix::RowVector2(x) => {
631        let mut x = x.borrow_mut();
632        x[0] = elements[0].clone();
633        x[1] = elements[1].clone();
634      }
635      Matrix::RowDVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
636      #[cfg(feature = "vector4")]
637      Matrix::Vector4(x) => {
638        let mut x = x.borrow_mut();
639        x[0] = elements[0].clone();
640        x[1] = elements[1].clone();
641        x[2] = elements[2].clone();
642        x[3] = elements[3].clone();
643      }
644      #[cfg(feature = "vector3")]
645      Matrix::Vector3(x) => {
646        let mut x = x.borrow_mut();
647        x[0] = elements[0].clone();
648        x[1] = elements[1].clone();
649        x[2] = elements[2].clone();
650      }
651      #[cfg(feature = "vector2")]
652      Matrix::Vector2(x) => {
653        let mut x = x.borrow_mut();
654        x[0] = elements[0].clone();
655        x[1] = elements[1].clone();
656      }
657      Matrix::DVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
658      #[cfg(feature = "matrix4")]
659      Matrix::Matrix4(x) => {
660        let mut x = x.borrow_mut();
661        x[0] = elements[0].clone();
662        x[1] = elements[1].clone();
663        x[2] = elements[2].clone();
664        x[3] = elements[3].clone();
665        x[4] = elements[4].clone();
666        x[5] = elements[5].clone();
667        x[6] = elements[6].clone();
668        x[7] = elements[7].clone();
669        x[8] = elements[8].clone();
670        x[9] = elements[9].clone();
671        x[10] = elements[10].clone();
672        x[11] = elements[11].clone();
673        x[12] = elements[12].clone();
674        x[13] = elements[13].clone();
675        x[14] = elements[14].clone();
676        x[15] = elements[15].clone();
677      }
678      #[cfg(feature = "matrix3")]
679      Matrix::Matrix3(x) => {
680        let mut x = x.borrow_mut();
681        x[0] = elements[0].clone();
682        x[1] = elements[1].clone();
683        x[2] = elements[2].clone();
684        x[3] = elements[3].clone();
685        x[4] = elements[4].clone();
686        x[5] = elements[5].clone();
687        x[6] = elements[6].clone();
688        x[7] = elements[7].clone();
689        x[8] = elements[8].clone();
690      }
691      #[cfg(feature = "matrix2")]
692      Matrix::Matrix2(x) => {
693        let mut x = x.borrow_mut();
694        x[0] = elements[0].clone();
695        x[1] = elements[1].clone();
696        x[2] = elements[2].clone();
697        x[3] = elements[3].clone();
698      }
699      #[cfg(feature = "matrix1")]
700      Matrix::Matrix1(x) => {let mut x = x.borrow_mut();x[0] = elements[0].clone();},
701      #[cfg(feature = "matrix3x2")]
702      Matrix::Matrix3x2(x) => {
703        let mut x = x.borrow_mut();
704        x[0] = elements[0].clone();
705        x[1] = elements[1].clone();
706        x[2] = elements[2].clone();
707        x[3] = elements[3].clone();
708        x[4] = elements[4].clone();
709        x[5] = elements[5].clone();
710      }
711      #[cfg(feature = "matrix2x3")]
712      Matrix::Matrix2x3(x) => {
713        let mut x = x.borrow_mut();
714        x[0] = elements[0].clone();
715        x[1] = elements[1].clone();
716        x[2] = elements[2].clone();
717        x[3] = elements[3].clone();
718        x[4] = elements[4].clone();
719        x[5] = elements[5].clone();
720      }
721      Matrix::DMatrix(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
722      _ => panic!("Unsupported matrix size"),
723    }
724  }
725
726  pub fn index2d(&self, row: usize, col: usize) -> T {
727    match self {
728      #[cfg(feature = "row_vector4")]
729      Matrix::RowVector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
730      #[cfg(feature = "row_vector3")]
731      Matrix::RowVector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
732      #[cfg(feature = "row_vector2")]
733      Matrix::RowVector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
734      Matrix::RowDVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
735      #[cfg(feature = "vector4")]
736      Matrix::Vector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
737      #[cfg(feature = "vector3")]
738      Matrix::Vector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
739      #[cfg(feature = "vector2")]
740      Matrix::Vector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
741      Matrix::DVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
742      #[cfg(feature = "matrix4")]
743      Matrix::Matrix4(x) => (*x.borrow().index((row-1,col-1))).clone(),
744      #[cfg(feature = "matrix3")]
745      Matrix::Matrix3(x) => (*x.borrow().index((row-1,col-1))).clone(),
746      #[cfg(feature = "matrix2")]
747      Matrix::Matrix2(x) => (*x.borrow().index((row-1,col-1))).clone(),
748      #[cfg(feature = "matrix1")]
749      Matrix::Matrix1(x) => (*x.borrow().index((row-1,col-1))).clone(),
750      #[cfg(feature = "matrix3x2")]
751      Matrix::Matrix3x2(x) => (*x.borrow().index((row-1,col-1))).clone(),
752      #[cfg(feature = "matrix2x3")]
753      Matrix::Matrix2x3(x) => (*x.borrow().index((row-1,col-1))).clone(),
754      Matrix::DMatrix(x) => (*x.borrow().index((row-1,col-1))).clone(),
755      _ => panic!("Unsupported matrix type for as_vec"),
756    }
757  }
758
759  pub fn as_vec(&self) -> Vec<T> {
760    match self {
761      #[cfg(feature = "row_vector4")]
762      Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(),
763      #[cfg(feature = "row_vector3")]
764      Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(),
765      #[cfg(feature = "row_vector2")]
766      Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(),
767      Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(),
768      #[cfg(feature = "vector4")]
769      Matrix::Vector4(x) => x.borrow().as_slice().to_vec(),
770      #[cfg(feature = "vector3")]
771      Matrix::Vector3(x) => x.borrow().as_slice().to_vec(),
772      #[cfg(feature = "vector2")]
773      Matrix::Vector2(x) => x.borrow().as_slice().to_vec(),
774      Matrix::DVector(x) => x.borrow().as_slice().to_vec(),
775      #[cfg(feature = "matrix4")]
776      Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(),
777      #[cfg(feature = "matrix3")]
778      Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(),
779      #[cfg(feature = "matrix2")]
780      Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(),
781      #[cfg(feature = "matrix1")]
782      Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(),
783      #[cfg(feature = "matrix3x2")]
784      Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(),
785      #[cfg(feature = "matrix2x3")]
786      Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(),
787      Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(),
788      _ => panic!("Unsupported matrix type for as_vec"),
789    }
790  }
791
792}
793
794macro_rules! impl_to_value_for_matrix {
795  ($t:ty, $variant:ident) => {
796    impl ToValue for Matrix<$t> {
797      fn to_value(&self) -> Value {
798        Value::$variant(self.clone())
799      }
800    }
801  };
802}
803
804impl_to_value_for_matrix!(Value, MatrixValue);
805#[cfg(feature = "f64")]
806impl_to_value_for_matrix!(F64, MatrixF64);
807#[cfg(feature = "f32")]
808impl_to_value_for_matrix!(F32, MatrixF32);
809#[cfg(feature = "i8")]
810impl_to_value_for_matrix!(i8, MatrixI8);
811#[cfg(feature = "i16")]
812impl_to_value_for_matrix!(i16, MatrixI16);
813#[cfg(feature = "i32")]
814impl_to_value_for_matrix!(i32, MatrixI32);
815#[cfg(feature = "i64")]
816impl_to_value_for_matrix!(i64, MatrixI64);
817#[cfg(feature = "i128")]
818impl_to_value_for_matrix!(i128, MatrixI128);
819#[cfg(feature = "u8")]
820impl_to_value_for_matrix!(u8, MatrixU8);
821#[cfg(feature = "u16")]
822impl_to_value_for_matrix!(u16, MatrixU16);
823#[cfg(feature = "u32")]
824impl_to_value_for_matrix!(u32, MatrixU32);
825#[cfg(feature = "u64")]
826impl_to_value_for_matrix!(u64, MatrixU64);
827#[cfg(feature = "u128")]
828impl_to_value_for_matrix!(u128, MatrixU128);
829#[cfg(feature = "bool")]
830impl_to_value_for_matrix!(bool, MatrixBool);
831#[cfg(feature = "string")]
832impl_to_value_for_matrix!(String, MatrixString);
833#[cfg(feature = "complex")]
834impl_to_value_for_matrix!(ComplexNumber, MatrixComplexNumber);
835#[cfg(feature = "rational")]
836impl_to_value_for_matrix!(RationalNumber, MatrixRationalNumber);
837
838
839macro_rules! to_value_ndmatrix {
840  ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty, $type_string:tt),+ $(,)?) => {
841    $(
842      #[cfg(all(feature = "matrix", feature = $type_string))]
843      impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
844        fn to_value(&self) -> Value {
845          Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
846        }
847      }
848    )+
849  };}
850
851macro_rules! impl_to_value_matrix {
852  ($matrix_kind:ident) => {
853    to_value_ndmatrix!(
854      $matrix_kind, MatrixIndex,  usize, "matrix",
855      $matrix_kind, MatrixBool,   bool, "bool",
856      $matrix_kind, MatrixI8,     i8, "i8",
857      $matrix_kind, MatrixI16,    i16, "i16",
858      $matrix_kind, MatrixI32,    i32, "i32",
859      $matrix_kind, MatrixI64,    i64, "i64",
860      $matrix_kind, MatrixI128,   i128, "i128",
861      $matrix_kind, MatrixU8,     u8, "u8",
862      $matrix_kind, MatrixU16,    u16, "u16",
863      $matrix_kind, MatrixU32,    u32, "u32",
864      $matrix_kind, MatrixU64,    u64, "u64",
865      $matrix_kind, MatrixU128,   u128, "u128",
866      $matrix_kind, MatrixF32,    F32, "f32",
867      $matrix_kind, MatrixF64,    F64, "f64",
868      $matrix_kind, MatrixString, String, "string",
869      $matrix_kind, MatrixRationalNumber, RationalNumber, "rational",
870      $matrix_kind, MatrixComplexNumber, ComplexNumber, "complex",
871    );
872  }
873}
874
875#[cfg(feature = "matrix2x3")]
876impl_to_value_matrix!(Matrix2x3);
877#[cfg(feature = "matrix3x2")]
878impl_to_value_matrix!(Matrix3x2);
879#[cfg(feature = "matrix1")]
880impl_to_value_matrix!(Matrix1);
881#[cfg(feature = "matrix2")]
882impl_to_value_matrix!(Matrix2);
883#[cfg(feature = "matrix3")]
884impl_to_value_matrix!(Matrix3);
885#[cfg(feature = "matrix4")]
886impl_to_value_matrix!(Matrix4);
887#[cfg(feature = "vector2")]
888impl_to_value_matrix!(Vector2);
889#[cfg(feature = "vector3")]
890impl_to_value_matrix!(Vector3);
891#[cfg(feature = "vector4")]
892impl_to_value_matrix!(Vector4);
893#[cfg(feature = "row_vector2")]
894impl_to_value_matrix!(RowVector2);
895#[cfg(feature = "row_vector3")]
896impl_to_value_matrix!(RowVector3);
897#[cfg(feature = "row_vector4")]
898impl_to_value_matrix!(RowVector4);
899#[cfg(feature = "row_vectord")]
900impl_to_value_matrix!(RowDVector);
901#[cfg(feature = "vectord")]
902impl_to_value_matrix!(DVector);
903#[cfg(feature = "matrixd")]
904impl_to_value_matrix!(DMatrix);