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(all(feature = "matrixd", not(feature = "matrix1")))]
25          (1,1) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(1,1,elements))),
26          #[cfg(feature = "matrix2")]
27          (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_vec(elements))),
28          #[cfg(feature = "matrix3")]
29          (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_vec(elements))),
30          #[cfg(feature = "matrix4")]
31          (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_vec(elements))),
32          #[cfg(feature = "matrix2x3")]
33          (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_vec(elements))),
34          #[cfg(feature = "matrix3x2")]
35          (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_vec(elements))),
36          #[cfg(feature = "row_vector2")]
37          (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_vec(elements))),
38          #[cfg(feature = "row_vector3")]
39          (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_vec(elements))),
40          #[cfg(feature = "row_vector4")]
41          (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_vec(elements))),
42          #[cfg(feature = "vector2")]
43          (2,1) => Matrix::Vector2(Ref::new(Vector2::from_vec(elements))),
44          #[cfg(feature = "vector3")]
45          (3,1) => Matrix::Vector3(Ref::new(Vector3::from_vec(elements))),
46          #[cfg(feature = "vector4")]
47          (4,1) => Matrix::Vector4(Ref::new(Vector4::from_vec(elements))),
48          #[cfg(feature = "row_vectord")]
49          (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
50          #[cfg(feature = "vectord")]
51          (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
52          #[cfg(feature = "matrixd")]
53          (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
54          _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
55        }
56      }
57      fn to_matrixd(elements: Vec<Self>, rows: usize, cols: usize) -> Matrix<Self> {
58        match (rows,cols) {
59          #[cfg(feature = "row_vectord")]
60          (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(elements))),
61          #[cfg(feature = "vectord")]
62          (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(elements))),
63          #[cfg(feature = "matrixd")]
64          (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,elements))),
65          _ => panic!("Cannot convert to matrixd with rows: {rows} and cols: {cols}"),
66        }
67      }
68    }
69  };    
70}
71
72impl_to_matrix!(usize);
73
74impl_to_matrix!(Value);
75#[cfg(feature = "bool")]
76impl_to_matrix!(bool);
77#[cfg(feature = "u8")]
78impl_to_matrix!(u8);
79#[cfg(feature = "u16")]
80impl_to_matrix!(u16);
81#[cfg(feature = "u32")]
82impl_to_matrix!(u32);
83#[cfg(feature = "u64")]
84impl_to_matrix!(u64);
85#[cfg(feature = "u128")]
86impl_to_matrix!(u128);
87#[cfg(feature = "i8")]
88impl_to_matrix!(i8);
89#[cfg(feature = "i16")]
90impl_to_matrix!(i16);
91#[cfg(feature = "i32")]
92impl_to_matrix!(i32);
93#[cfg(feature = "i64")]
94impl_to_matrix!(i64);
95#[cfg(feature = "i128")]
96impl_to_matrix!(i128);
97#[cfg(feature = "f32")]
98impl_to_matrix!(f32);
99#[cfg(feature = "f64")]
100impl_to_matrix!(f64);
101#[cfg(feature = "string")]
102impl_to_matrix!(String);
103#[cfg(feature = "complex")]
104impl_to_matrix!(C64);
105#[cfg(feature = "rational")]
106impl_to_matrix!(R64);
107
108pub trait ToIndex: Clone {
109  fn to_index(elements: Vec<Self>) -> Matrix<Self>;
110}
111
112#[derive(Clone, Debug, PartialEq, Eq)]
113pub enum Matrix<T> {
114  #[cfg(feature = "row_vector4")]
115  RowVector4(Ref<RowVector4<T>>),
116  #[cfg(feature = "row_vector3")]
117  RowVector3(Ref<RowVector3<T>>),
118  #[cfg(feature = "row_vector2")]
119  RowVector2(Ref<RowVector2<T>>),
120  #[cfg(feature = "vector4")]
121  Vector4(Ref<Vector4<T>>),  
122  #[cfg(feature = "vector3")]
123  Vector3(Ref<Vector3<T>>),
124  #[cfg(feature = "vector2")]
125  Vector2(Ref<Vector2<T>>),
126  #[cfg(feature = "matrix4")]
127  Matrix4(Ref<Matrix4<T>>),
128  #[cfg(feature = "matrix3")]
129  Matrix3(Ref<Matrix3<T>>),
130  #[cfg(feature = "matrix2")]
131  Matrix2(Ref<Matrix2<T>>),
132  #[cfg(feature = "matrix1")]
133  Matrix1(Ref<Matrix1<T>>),
134  #[cfg(feature = "matrix3x2")]
135  Matrix3x2(Ref<Matrix3x2<T>>),
136  #[cfg(feature = "matrix2x3")]
137  Matrix2x3(Ref<Matrix2x3<T>>),
138  #[cfg(feature = "vectord")]
139  DVector(Ref<DVector<T>>),
140  #[cfg(feature = "row_vectord")]
141  RowDVector(Ref<RowDVector<T>>),
142  #[cfg(feature = "matrixd")]
143  DMatrix(Ref<DMatrix<T>>),
144}
145
146pub trait CopyMat<T> {
147  #[cfg(feature = "matrixd")]
148  fn copy_into(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize;
149  #[cfg(feature = "vectord")]
150  fn copy_into_v(&self, dst: &Ref<DVector<T>>, offset: usize) -> usize;
151  #[cfg(feature = "row_vectord")]
152  fn copy_into_r(&self, dst: &Ref<RowDVector<T>>, offset: usize) -> usize;
153  #[cfg(feature = "matrixd")]
154  fn copy_into_row_major(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize;
155  fn addr(&self) -> usize;
156  fn compile_const_mat(&self, ctx: &mut CompileCtx) -> MResult<u32>;
157}
158
159macro_rules! copy_mat {
160  ($matsize:ident) => {
161    impl<T> CopyMat<T> for Ref<$matsize<T>>
162    where 
163      T: Clone + CompileConst + ConstElem,
164      $matsize<T>: CompileConst + ConstElem,
165    {
166      #[cfg(feature = "matrixd")]
167      fn copy_into(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize {
168        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
169        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
170        for i in 0..src_ptr.len() {
171          dst_ptr[i + offset] = src_ptr[i].clone();
172        }
173        src_ptr.len()
174      }
175      #[cfg(feature = "vectord")]
176      fn copy_into_v(&self, dst: &Ref<DVector<T>>, offset: usize) -> usize {
177        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
178        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
179        for i in 0..src_ptr.len() {
180          dst_ptr[i + offset] = src_ptr[i].clone();
181        }
182        src_ptr.len()
183      }
184      #[cfg(feature = "row_vectord")]
185      fn copy_into_r(&self, dst: &Ref<RowDVector<T>>, offset: usize) -> usize {
186        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
187        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
188        for i in 0..src_ptr.len() {
189          dst_ptr[i + offset] = src_ptr[i].clone();
190        }
191        src_ptr.len()
192      }
193      #[cfg(feature = "matrixd")]
194      fn copy_into_row_major(&self, dst: &Ref<DMatrix<T>>, offset: usize) -> usize {
195        let src_ptr = unsafe { (*(self.as_ptr())).clone() };
196        let mut dst_ptr = unsafe { &mut *(dst.as_mut_ptr()) };
197        let src_rows = src_ptr.nrows();
198        let dest_rows = dst_ptr.nrows();
199
200        let stride = dest_rows - src_rows;
201        let mut offset = offset;
202        for ix in 0..src_ptr.len() {
203          dst_ptr[offset] = src_ptr[ix].clone();
204          offset += ((ix + 1) % src_rows == 0) as usize * stride + 1;
205        }
206        src_rows
207      }
208      fn addr(&self) -> usize { self.addr() }
209      fn compile_const_mat(&self, ctx: &mut CompileCtx) -> MResult<u32> {
210        self.borrow().compile_const(ctx)
211      }
212    }};}
213      
214#[cfg(feature = "matrix1")]
215copy_mat!(Matrix1);
216#[cfg(feature = "matrix2")]
217copy_mat!(Matrix2);
218#[cfg(feature = "matrix3")]
219copy_mat!(Matrix3);
220#[cfg(feature = "matrix4")]
221copy_mat!(Matrix4);
222#[cfg(feature = "matrix2x3")]
223copy_mat!(Matrix2x3);
224#[cfg(feature = "matrix3x2")]
225copy_mat!(Matrix3x2);
226#[cfg(feature = "vector2")]
227copy_mat!(Vector2);
228#[cfg(feature = "vector3")]
229copy_mat!(Vector3);
230#[cfg(feature = "vector4")]
231copy_mat!(Vector4);
232#[cfg(feature = "row_vector2")]
233copy_mat!(RowVector2);
234#[cfg(feature = "row_vector3")]
235copy_mat!(RowVector3);
236#[cfg(feature = "row_vector4")]
237copy_mat!(RowVector4);
238#[cfg(feature = "vectord")]
239copy_mat!(DVector);
240#[cfg(feature = "matrixd")]
241copy_mat!(DMatrix);
242#[cfg(feature = "row_vectord")]
243copy_mat!(RowDVector);
244
245impl<T> Hash for Matrix<T> 
246where T: Hash + nalgebra::Scalar
247{
248  fn hash<H: Hasher>(&self, state: &mut H) {
249    match self {
250      #[cfg(feature = "row_vector4")]
251      Matrix::RowVector4(x) => x.borrow().hash(state),
252      #[cfg(feature = "row_vector3")]
253      Matrix::RowVector3(x) => x.borrow().hash(state),
254      #[cfg(feature = "row_vector2")]
255      Matrix::RowVector2(x) => x.borrow().hash(state),
256      #[cfg(feature = "vector4")]
257      Matrix::Vector4(x) => x.borrow().hash(state),
258      #[cfg(feature = "vector3")]
259      Matrix::Vector3(x) => x.borrow().hash(state),
260      #[cfg(feature = "vector2")]
261      Matrix::Vector2(x) => x.borrow().hash(state),
262
263      #[cfg(feature = "matrix4")]
264      Matrix::Matrix4(x) => x.borrow().hash(state),
265      #[cfg(feature = "matrix3")]
266      Matrix::Matrix3(x) => x.borrow().hash(state),
267      #[cfg(feature = "matrix2")]
268      Matrix::Matrix2(x) => x.borrow().hash(state),
269      #[cfg(feature = "matrix1")]
270      Matrix::Matrix1(x) => x.borrow().hash(state),
271      #[cfg(feature = "matrix3x2")]
272      Matrix::Matrix3x2(x) => x.borrow().hash(state),
273      #[cfg(feature = "matrix2x3")]
274      Matrix::Matrix2x3(x) => x.borrow().hash(state),
275      #[cfg(feature = "vectord")]
276      Matrix::DVector(x) => x.borrow().hash(state),
277      #[cfg(feature = "row_vectord")]
278      Matrix::RowDVector(x) => x.borrow().hash(state),
279      #[cfg(feature = "matrixd")]
280      Matrix::DMatrix(x) => x.borrow().hash(state),
281      _ => panic!("Hashing not implemented for this matrix type"),
282    }
283  }
284}
285
286#[cfg(feature = "pretty_print")]
287impl<T> PrettyPrint for Matrix<T>
288where T: Debug + Display + Clone + PartialEq + 'static + PrettyPrint
289{
290  fn pretty_print(&self) -> String {
291    let mut builder = Builder::default();
292    match self {
293      #[cfg(feature = "row_vector4")]
294      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<_>>()));}
295      #[cfg(feature = "row_vector3")]
296      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<_>>()));}
297      #[cfg(feature = "row_vector2")]
298      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<_>>()));}
299      #[cfg(feature = "row_vectord")]
300      Matrix::RowDVector(vec) => {
301        let vec_brrw = vec.borrow();
302        let vec_str = if vec_brrw.ncols() > 20 {
303          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<_>>();
304          vec_str.insert(10,"...".to_string());
305          vec_str
306        } else {
307          vec_brrw.row(0).iter().map(|x| format!("{:?}", x)).collect::<Vec<_>>()
308        };
309        builder.push_record(vec_str);
310      }
311      #[cfg(feature = "vector4")]
312      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<_>>()));}
313      #[cfg(feature = "vector3")]
314      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<_>>()));}
315      #[cfg(feature = "vector2")]
316      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<_>>()));}
317      #[cfg(feature = "vectord")]
318      Matrix::DVector(vec) => {
319        let vec_brrw = vec.borrow();
320        let vec_str = if vec_brrw.nrows() > 20 {
321          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<_>>();
322          vec_str.insert(10,"...".to_string());
323          vec_str
324        } else {
325          vec_brrw.column(0).iter().map(|x| x.pretty_print()).collect::<Vec<_>>()
326        };
327        for r in vec_str {
328          builder.push_record(vec![r]);
329        }
330      }
331      #[cfg(feature = "matrix4")]
332      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<_>>()));}
333      #[cfg(feature = "matrix3")]
334      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<_>>()));}
335      #[cfg(feature = "matrix2")]
336      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<_>>()));}
337      #[cfg(feature = "matrix1")]
338      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<_>>()));}
339      #[cfg(feature = "matrix3x2")]
340      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<_>>()));}
341      #[cfg(feature = "matrix2x3")]
342      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<_>>()));}
343      #[cfg(feature = "matrixd")]
344      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<_>>()));}
345      _ => todo!(),
346    };
347    let matrix_style = Style::empty()
348      .top(' ')
349      .left('┃')
350      .right('┃')
351      .bottom(' ')
352      .vertical(' ')
353      .intersection_bottom(' ')
354      .corner_top_left('┏')
355      .corner_top_right('┓')
356      .corner_bottom_left('┗')
357      .corner_bottom_right('┛');
358    let mut table = builder.build();
359    table.with(matrix_style);
360    format!("{table}")
361  }
362}
363
364fn quoted<T: Display + Any>(val: &T) -> String {
365  if let Some(s) = (val as &dyn Any).downcast_ref::<String>() {
366    format!("<div class='mech-string'>\"{}\"</div>", s)
367  } else if let Some(s) = (val as &dyn Any).downcast_ref::<bool>() {
368    format!("<div class='mech-boolean'>{}</div<", s)
369  } else {
370    format!("<div class='mech-number'>{}</div>", val)
371  }
372}
373
374impl<T> Matrix<T> 
375where T: Debug + Display + Clone + PartialEq + 'static + PrettyPrint
376{
377
378  pub fn to_html(&self) -> String {
379    let size = self.shape();
380    let mut html = String::new();
381    html.push_str("<table class='mech-matrix'>");
382    for i in 0..size[0] {
383      html.push_str("<tr>");
384      for j in 0..size[1] {
385        let value = self.index2d(i+1, j+1);
386        html.push_str(&format!("<td>{}</td>", quoted(&value)));
387      }
388      html.push_str("</tr>");
389    }
390    format!("<div class='mech-matrix-outer'><div class='mech-matrix-inner'></div>{}</div>", html)
391  }
392
393}
394
395impl<T> Matrix<T> 
396where
397  T:  CompileConst + ConstElem + Clone + 'static + Debug + PartialEq + AsValueKind,
398{
399  pub fn get_copyable_matrix(&self) -> Box<dyn CopyMat<T>> {
400    match self {
401      #[cfg(feature = "row_vector4")]
402      Matrix::RowVector4(ref x) => Box::new(x.clone()),
403      #[cfg(feature = "row_vector3")]
404      Matrix::RowVector3(ref x) => Box::new(x.clone()),
405      #[cfg(feature = "row_vector2")]
406      Matrix::RowVector2(ref x) => Box::new(x.clone()),
407      #[cfg(feature = "row_vectord")]
408      Matrix::RowDVector(ref x) => Box::new(x.clone()),
409      #[cfg(feature = "vector4")]
410      Matrix::Vector4(ref x) => Box::new(x.clone()),
411      #[cfg(feature = "vector3")]
412      Matrix::Vector3(ref x) => Box::new(x.clone()),
413      #[cfg(feature = "vector2")]
414      Matrix::Vector2(ref x) => Box::new(x.clone()),
415      #[cfg(feature = "vectord")]
416      Matrix::DVector(ref x) => Box::new(x.clone()),
417      #[cfg(feature = "matrix4")]
418      Matrix::Matrix4(ref x) => Box::new(x.clone()),
419      #[cfg(feature = "matrix3")]
420      Matrix::Matrix3(ref x) => Box::new(x.clone()),
421      #[cfg(feature = "matrix2")]
422      Matrix::Matrix2(ref x) => Box::new(x.clone()),
423      #[cfg(feature = "matrix1")]
424      Matrix::Matrix1(ref x) => Box::new(x.clone()),
425      #[cfg(feature = "matrix3x2")]
426      Matrix::Matrix3x2(ref x) => Box::new(x.clone()),
427      #[cfg(feature = "matrix2x3")]
428      Matrix::Matrix2x3(ref x) => Box::new(x.clone()),
429      #[cfg(feature = "matrixd")]
430      Matrix::DMatrix(ref x) => Box::new(x.clone()),
431      _ => panic!("Unsupported matrix size"),
432    }
433  }
434}
435
436impl<T> Matrix<T> {
437
438  pub unsafe fn as_unchecked<R>(&self) -> &Ref<R> {
439    match self {
440      #[cfg(feature = "row_vector4")]
441      Matrix::RowVector4(x) => &*(x as *const Ref<RowVector4<T>> as *const Ref<R>),
442      #[cfg(feature = "row_vector3")]
443      Matrix::RowVector3(x) => &*(x as *const Ref<RowVector3<T>> as *const Ref<R>),
444      #[cfg(feature = "row_vector2")]
445      Matrix::RowVector2(x) => &*(x as *const Ref<RowVector2<T>> as *const Ref<R>),
446      #[cfg(feature = "vector4")]
447      Matrix::Vector4(x) => &*(x as *const Ref<Vector4<T>> as *const Ref<R>),
448      #[cfg(feature = "vector3")]
449      Matrix::Vector3(x) => &*(x as *const Ref<Vector3<T>> as *const Ref<R>),
450      #[cfg(feature = "vector2")]
451      Matrix::Vector2(x) => &*(x as *const Ref<Vector2<T>> as *const Ref<R>),
452      #[cfg(feature = "matrix4")]
453      Matrix::Matrix4(x) => &*(x as *const Ref<Matrix4<T>> as *const Ref<R>),
454      #[cfg(feature = "matrix3")]
455      Matrix::Matrix3(x) => &*(x as *const Ref<Matrix3<T>> as *const Ref<R>),
456      #[cfg(feature = "matrix2")]
457      Matrix::Matrix2(x) => &*(x as *const Ref<Matrix2<T>> as *const Ref<R>),
458      #[cfg(feature = "matrix1")]
459      Matrix::Matrix1(x) => &*(x as *const Ref<Matrix1<T>> as *const Ref<R>),
460      #[cfg(feature = "matrix3x2")]
461      Matrix::Matrix3x2(x) => &*(x as *const Ref<Matrix3x2<T>> as *const Ref<R>),
462      #[cfg(feature = "matrix2x3")]
463      Matrix::Matrix2x3(x) => &*(x as *const Ref<Matrix2x3<T>> as *const Ref<R>),
464      #[cfg(feature = "vectord")]
465      Matrix::DVector(x) => &*(x as *const Ref<DVector<T>> as *const Ref<R>),
466      #[cfg(feature = "row_vectord")]
467      Matrix::RowDVector(x) => &*(x as *const Ref<RowDVector<T>> as *const Ref<R>),
468      #[cfg(feature = "matrixd")]
469      Matrix::DMatrix(x) => &*(x as *const Ref<DMatrix<T>> as *const Ref<R>),
470      _ => panic!("Unsupported type for as_unchecked"),
471    }
472  }
473
474  pub fn addr(&self) -> usize {
475    match self {
476      #[cfg(feature = "matrix1")]
477      Matrix::Matrix1(x) => x.addr(),
478      #[cfg(feature = "matrix2")]
479      Matrix::Matrix2(x) => x.addr(),
480      #[cfg(feature = "matrix3")]
481      Matrix::Matrix3(x) => x.addr(),
482      #[cfg(feature = "matrix4")]
483      Matrix::Matrix4(x) => x.addr(),
484      #[cfg(feature = "matrix2x3")]
485      Matrix::Matrix2x3(x) => x.addr(),
486      #[cfg(feature = "matrix3x2")]
487      Matrix::Matrix3x2(x) => x.addr(),
488      #[cfg(feature = "vector2")]
489      Matrix::Vector2(x) => x.addr(),
490      #[cfg(feature = "vector3")]
491      Matrix::Vector3(x) => x.addr(),
492      #[cfg(feature = "vector4")]
493      Matrix::Vector4(x) => x.addr(),
494      #[cfg(feature = "row_vector2")]
495      Matrix::RowVector2(x) => x.addr(),
496      #[cfg(feature = "row_vector3")]
497      Matrix::RowVector3(x) => x.addr(),
498      #[cfg(feature = "row_vector4")]
499      Matrix::RowVector4(x) => x.addr(),
500      #[cfg(feature = "vectord")]
501      Matrix::DVector(x) => x.addr(),
502      #[cfg(feature = "row_vectord")]
503      Matrix::RowDVector(x) => x.addr(),
504      #[cfg(feature = "matrixd")]
505      Matrix::DMatrix(x) => x.addr(),
506    }
507  }
508}
509
510impl<T> Matrix<T> 
511where T: Debug + Clone + PartialEq + 'static
512{
513
514  pub fn append(&mut self, other: &Matrix<T>) -> MResult<()> {
515    match (&self, &other) {
516      #[cfg(feature = "vectord")]
517      (Matrix::DVector(ref lhs), Matrix::DVector(ref rhs)) => {
518        let mut lhs = lhs.borrow_mut();
519        let rhs = rhs.borrow();
520        let old_len = lhs.len();
521        lhs.resize_vertically_mut(old_len + rhs.len(), rhs[0].clone());
522        for (i, val) in rhs.iter().enumerate() {
523          lhs[old_len + i] = val.clone();
524        }
525        Ok(())
526      }
527      #[cfg(feature = "row_vectord")]
528      (Matrix::RowDVector(ref lhs), Matrix::RowDVector(ref rhs)) => {
529        let mut lhs = lhs.borrow_mut();
530        let rhs = rhs.borrow();
531        let old_len = lhs.len();
532        lhs.resize_horizontally_mut(old_len + rhs.len(), rhs[0].clone());
533        for (i, val) in rhs.iter().enumerate() {
534          lhs[old_len + i] = val.clone();
535        }
536        Ok(())
537      }
538      _ => {
539        return Err(
540          MechError2::new(
541            IncompatibleMatrixAppendToTableError {
542              lhs_rows: self.rows(),
543              lhs_cols: self.cols(),
544              rhs_rows: other.rows(),
545              rhs_cols: other.cols(),
546            },
547            None,
548          )
549          .with_compiler_loc()
550        );
551      }
552    }
553  }
554
555  pub fn push(&mut self, value: T) -> MResult<()> {
556    match self {
557      #[cfg(feature = "row_vectord")]
558      Matrix::RowDVector(vec) => {
559          let mut vec = vec.borrow_mut();
560          let new_len = vec.ncols() + 1;
561          vec.resize_horizontally_mut(new_len, value.clone()); // row vector: increase columns
562          Ok(())
563      }
564      #[cfg(feature = "vectord")]
565      Matrix::DVector(vec) => {
566          let mut vec = vec.borrow_mut();
567          let new_len = vec.nrows() + 1;
568          vec.resize_vertically_mut(new_len, value.clone()); // column vector: increase rows
569          Ok(())
570      }
571      _ => {
572        return Err(
573          MechError2::new(
574            PushIntoStaticMatrixError,
575            None,
576          )
577          .with_compiler_loc()
578        );
579      }
580    }
581  }
582
583  pub fn rows(&self) -> usize {
584    let size = self.shape();
585    size[0]
586  }
587
588  pub fn cols(&self) -> usize {
589    let size = self.shape();
590    size[1]
591  }
592
593  pub fn size_of(&self) -> usize {
594    let vec = self.as_vec();
595    vec.capacity() * size_of::<T>()
596  }       
597
598  pub fn resize_vertically(&mut self, new_size: usize, fill_value: T) -> MResult<()> {
599    match self {
600      #[cfg(feature = "row_vectord")]
601      Matrix::RowDVector(vec) => {
602        let mut vec = vec.borrow_mut();
603        vec.resize_horizontally_mut(new_size, fill_value);
604        Ok(())
605      }
606      #[cfg(feature = "vectord")]
607      Matrix::DVector(vec) => {
608        let mut vec = vec.borrow_mut();
609        vec.resize_vertically_mut(new_size, fill_value);
610        Ok(())
611      }
612      _ => {
613        return Err(
614          MechError2::new(
615            ResizeStaticMatrixError,
616            None,
617          )
618          .with_compiler_loc()
619        );
620      }
621    }
622  }
623
624  pub fn shape(&self) -> Vec<usize> {
625    let shape = match self {
626      #[cfg(feature = "row_vector4")]
627      Matrix::RowVector4(x) => x.borrow().shape(),
628      #[cfg(feature = "row_vector3")]
629      Matrix::RowVector3(x) => x.borrow().shape(),
630      #[cfg(feature = "row_vector2")]
631      Matrix::RowVector2(x) => x.borrow().shape(),
632      #[cfg(feature = "row_vectord")]
633      Matrix::RowDVector(x) => x.borrow().shape(),
634      #[cfg(feature = "vector4")]
635      Matrix::Vector4(x) => x.borrow().shape(),
636      #[cfg(feature = "vector3")]
637      Matrix::Vector3(x) => x.borrow().shape(),
638      #[cfg(feature = "vector2")]
639      Matrix::Vector2(x) => x.borrow().shape(),
640      #[cfg(feature = "vectord")]
641      Matrix::DVector(x) => x.borrow().shape(),
642      #[cfg(feature = "matrix4")]
643      Matrix::Matrix4(x) => x.borrow().shape(),
644      #[cfg(feature = "matrix3")]
645      Matrix::Matrix3(x) => x.borrow().shape(),
646      #[cfg(feature = "matrix2")]
647      Matrix::Matrix2(x) => x.borrow().shape(),
648      #[cfg(feature = "matrix1")]
649      Matrix::Matrix1(x) => x.borrow().shape(),
650      #[cfg(feature = "matrix3x2")]
651      Matrix::Matrix3x2(x) => x.borrow().shape(),
652      #[cfg(feature = "matrix2x3")]
653      Matrix::Matrix2x3(x) => x.borrow().shape(),
654      #[cfg(feature = "matrixd")]
655      Matrix::DMatrix(x) => x.borrow().shape(),
656      _ => panic!("Unsupported matrix size"),
657    };
658    vec![shape.0, shape.1]
659  }
660
661  pub fn index1d(&self, ix: usize) -> T {
662    match self {
663      #[cfg(feature = "row_vector4")]
664      Matrix::RowVector4(x) => (*x.borrow().index(ix-1)).clone(),
665      #[cfg(feature = "row_vector3")]
666      Matrix::RowVector3(x) => (*x.borrow().index(ix-1)).clone(),
667      #[cfg(feature = "row_vector2")]
668      Matrix::RowVector2(x) => (*x.borrow().index(ix-1)).clone(),
669      #[cfg(feature = "row_vectord")]
670      Matrix::RowDVector(x) => (*x.borrow().index(ix-1)).clone(),
671      #[cfg(feature = "vector4")]
672      Matrix::Vector4(x) => (*x.borrow().index(ix-1)).clone(),
673      #[cfg(feature = "vector3")]
674      Matrix::Vector3(x) => (*x.borrow().index(ix-1)).clone(),
675      #[cfg(feature = "vector2")]
676      Matrix::Vector2(x) => (*x.borrow().index(ix-1)).clone(),
677      #[cfg(feature = "vectord")]
678      Matrix::DVector(x) => (*x.borrow().index(ix-1)).clone(),
679      #[cfg(feature = "matrix4")]
680      Matrix::Matrix4(x) => (*x.borrow().index(ix-1)).clone(),
681      #[cfg(feature = "matrix3")]
682      Matrix::Matrix3(x) => (*x.borrow().index(ix-1)).clone(),
683      #[cfg(feature = "matrix2")]
684      Matrix::Matrix2(x) => (*x.borrow().index(ix-1)).clone(),
685      #[cfg(feature = "matrix1")]
686      Matrix::Matrix1(x) => (*x.borrow().index(ix-1)).clone(),
687      #[cfg(feature = "matrix3x2")]
688      Matrix::Matrix3x2(x) => (*x.borrow().index(ix-1)).clone(),
689      #[cfg(feature = "matrix2x3")]
690      Matrix::Matrix2x3(x) => (*x.borrow().index(ix-1)).clone(),
691      #[cfg(feature = "matrixd")]
692      Matrix::DMatrix(x) => (*x.borrow().index(ix-1)).clone(),
693      _ => panic!("Unsupported matrix size"),
694    }
695  }
696
697  pub fn set_index1d(&self, index: usize, value: T) {
698    match self {
699      #[cfg(feature = "row_vector4")]
700      Matrix::RowVector4(v) => v.borrow_mut()[index] = value,
701      #[cfg(feature = "row_vector3")]
702      Matrix::RowVector3(v) => v.borrow_mut()[index] = value,
703      #[cfg(feature = "row_vector2")]
704      Matrix::RowVector2(v) => v.borrow_mut()[index] = value,
705      #[cfg(feature = "row_vectord")]
706      Matrix::RowDVector(v) => v.borrow_mut()[index] = value,
707      #[cfg(feature = "vector4")]
708      Matrix::Vector4(v) => v.borrow_mut()[index] = value,
709      #[cfg(feature = "vector3")]
710      Matrix::Vector3(v) => v.borrow_mut()[index] = value,
711      #[cfg(feature = "vector2")]
712      Matrix::Vector2(v) => v.borrow_mut()[index] = value,
713      #[cfg(feature = "vectord")]
714      Matrix::DVector(v) => v.borrow_mut()[index] = value,
715      #[cfg(feature = "matrix1")]
716      Matrix::Matrix1(m) => m.borrow_mut()[index] = value,
717      #[cfg(feature = "matrix2")]
718      Matrix::Matrix2(m) => m.borrow_mut()[index] = value,
719      #[cfg(feature = "matrix3")]
720      Matrix::Matrix3(m) => m.borrow_mut()[index] = value,
721      #[cfg(feature = "matrix4")]
722      Matrix::Matrix4(m) => m.borrow_mut()[index] = value,
723      #[cfg(feature = "matrix2x3")]
724      Matrix::Matrix2x3(m) => m.borrow_mut()[index] = value,
725      #[cfg(feature = "matrix3x2")]
726      Matrix::Matrix3x2(m) => m.borrow_mut()[index] = value,
727      #[cfg(feature = "matrixd")]
728      Matrix::DMatrix(m) => m.borrow_mut()[index] = value,
729      _ => panic!("Unsupported matrix size"),
730    }
731  }
732
733  pub fn from_element(rows: usize, cols: usize, element: T) -> Matrix<T> {
734    match (rows,cols) {
735      #[cfg(feature = "matrix1")]
736      (1,1) => Matrix::Matrix1(Ref::new(Matrix1::from_element(element.clone()))),
737      #[cfg(all(feature = "matrixd", not(feature = "matrix1")))]
738      (1,1) => Matrix::DMatrix(Ref::new(DMatrix::from_element(1,1,element.clone()))),
739      #[cfg(feature = "matrix2")]
740      (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_element(element.clone()))),
741      #[cfg(feature = "matrix3")]
742      (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_element(element.clone()))),
743      #[cfg(feature = "matrix4")]
744      (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_element(element.clone()))),
745      #[cfg(feature = "matrix2x3")]
746      (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_element(element.clone()))),
747      #[cfg(feature = "matrix3x2")]
748      (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_element(element.clone()))),
749      #[cfg(feature = "vector4")]
750      (4,1) => Matrix::Vector4(Ref::new(Vector4::from_element(element.clone()))),
751      #[cfg(feature = "vector3")]
752      (3,1) => Matrix::Vector3(Ref::new(Vector3::from_element(element.clone()))),
753      #[cfg(feature = "vector2")]
754      (2,1) => Matrix::Vector2(Ref::new(Vector2::from_element(element.clone()))),
755      #[cfg(feature = "row_vector4")]
756      (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_element(element.clone()))),
757      #[cfg(feature = "row_vector3")]
758      (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_element(element.clone()))),
759      #[cfg(feature = "row_vector2")]
760      (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_element(element.clone()))),
761      #[cfg(feature = "row_vectord")]
762      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_element(n,element.clone()))),
763      #[cfg(feature = "vectord")]
764      (m,1) => Matrix::DVector(Ref::new(DVector::from_element(m,element.clone()))),
765      #[cfg(feature = "matrixd")]
766      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_element(m,n,element.clone()))),
767      _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
768    }
769  }
770
771  pub fn from_vec(vec: Vec<T>, rows: usize, cols: usize) -> Matrix<T> {
772    match (rows,cols) {
773      #[cfg(feature = "matrix1")]
774      (1,1) => Matrix::Matrix1(Ref::new(Matrix1::from_vec(vec.clone()))),
775      #[cfg(all(feature = "matrixd", not(feature = "matrix1")))]
776      (1,1) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(1,1,vec.clone()))),
777      #[cfg(feature = "matrix2")]
778      (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_vec(vec.clone()))),
779      #[cfg(feature = "matrix3")]
780      (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_vec(vec.clone()))),
781      #[cfg(feature = "matrix4")]
782      (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_vec(vec.clone()))),
783      #[cfg(feature = "matrix2x3")]
784      (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_vec(vec.clone()))),
785      #[cfg(feature = "matrix3x2")]
786      (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_vec(vec.clone()))),
787      #[cfg(feature = "vector4")]
788      (4,1) => Matrix::Vector4(Ref::new(Vector4::from_vec(vec.clone()))),
789      #[cfg(feature = "vector3")]
790      (3,1) => Matrix::Vector3(Ref::new(Vector3::from_vec(vec.clone()))),
791      #[cfg(feature = "vector2")]
792      (2,1) => Matrix::Vector2(Ref::new(Vector2::from_vec(vec.clone()))),
793      #[cfg(feature = "row_vector4")]
794      (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_vec(vec.clone()))),
795      #[cfg(feature = "row_vector3")]
796      (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_vec(vec.clone()))),
797      #[cfg(feature = "row_vector2")]
798      (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_vec(vec.clone()))),
799      #[cfg(feature = "row_vectord")]
800      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(vec.clone()))),
801      #[cfg(feature = "vectord")]
802      (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(vec.clone()))),
803      #[cfg(feature = "matrixd")]
804      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,vec.clone()))),
805      _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
806    }
807  }
808
809  pub fn set(&self, elements: Vec<T>) {
810    match self {
811      #[cfg(feature = "row_vector4")]
812      Matrix::RowVector4(x) => {
813        let mut x = x.borrow_mut();
814        x[0] = elements[0].clone();
815        x[1] = elements[1].clone();
816        x[2] = elements[2].clone();
817        x[3] = elements[3].clone();
818      }
819      #[cfg(feature = "row_vector3")]
820      Matrix::RowVector3(x) => {
821        let mut x = x.borrow_mut();
822        x[0] = elements[0].clone();
823        x[1] = elements[1].clone();
824        x[2] = elements[2].clone();
825      }
826      #[cfg(feature = "row_vector2")]
827      Matrix::RowVector2(x) => {
828        let mut x = x.borrow_mut();
829        x[0] = elements[0].clone();
830        x[1] = elements[1].clone();
831      }
832      #[cfg(feature = "row_vectord")]
833      Matrix::RowDVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
834      #[cfg(feature = "vector4")]
835      Matrix::Vector4(x) => {
836        let mut x = x.borrow_mut();
837        x[0] = elements[0].clone();
838        x[1] = elements[1].clone();
839        x[2] = elements[2].clone();
840        x[3] = elements[3].clone();
841      }
842      #[cfg(feature = "vector3")]
843      Matrix::Vector3(x) => {
844        let mut x = x.borrow_mut();
845        x[0] = elements[0].clone();
846        x[1] = elements[1].clone();
847        x[2] = elements[2].clone();
848      }
849      #[cfg(feature = "vector2")]
850      Matrix::Vector2(x) => {
851        let mut x = x.borrow_mut();
852        x[0] = elements[0].clone();
853        x[1] = elements[1].clone();
854      }
855      #[cfg(feature = "vectord")]
856      Matrix::DVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
857      #[cfg(feature = "matrix4")]
858      Matrix::Matrix4(x) => {
859        let mut x = x.borrow_mut();
860        x[0] = elements[0].clone();
861        x[1] = elements[1].clone();
862        x[2] = elements[2].clone();
863        x[3] = elements[3].clone();
864        x[4] = elements[4].clone();
865        x[5] = elements[5].clone();
866        x[6] = elements[6].clone();
867        x[7] = elements[7].clone();
868        x[8] = elements[8].clone();
869        x[9] = elements[9].clone();
870        x[10] = elements[10].clone();
871        x[11] = elements[11].clone();
872        x[12] = elements[12].clone();
873        x[13] = elements[13].clone();
874        x[14] = elements[14].clone();
875        x[15] = elements[15].clone();
876      }
877      #[cfg(feature = "matrix3")]
878      Matrix::Matrix3(x) => {
879        let mut x = x.borrow_mut();
880        x[0] = elements[0].clone();
881        x[1] = elements[1].clone();
882        x[2] = elements[2].clone();
883        x[3] = elements[3].clone();
884        x[4] = elements[4].clone();
885        x[5] = elements[5].clone();
886        x[6] = elements[6].clone();
887        x[7] = elements[7].clone();
888        x[8] = elements[8].clone();
889      }
890      #[cfg(feature = "matrix2")]
891      Matrix::Matrix2(x) => {
892        let mut x = x.borrow_mut();
893        x[0] = elements[0].clone();
894        x[1] = elements[1].clone();
895        x[2] = elements[2].clone();
896        x[3] = elements[3].clone();
897      }
898      #[cfg(feature = "matrix1")]
899      Matrix::Matrix1(x) => {let mut x = x.borrow_mut();x[0] = elements[0].clone();},
900      #[cfg(feature = "matrix3x2")]
901      Matrix::Matrix3x2(x) => {
902        let mut x = x.borrow_mut();
903        x[0] = elements[0].clone();
904        x[1] = elements[1].clone();
905        x[2] = elements[2].clone();
906        x[3] = elements[3].clone();
907        x[4] = elements[4].clone();
908        x[5] = elements[5].clone();
909      }
910      #[cfg(feature = "matrix2x3")]
911      Matrix::Matrix2x3(x) => {
912        let mut x = x.borrow_mut();
913        x[0] = elements[0].clone();
914        x[1] = elements[1].clone();
915        x[2] = elements[2].clone();
916        x[3] = elements[3].clone();
917        x[4] = elements[4].clone();
918        x[5] = elements[5].clone();
919      }
920      #[cfg(feature = "matrixd")]
921      Matrix::DMatrix(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
922      _ => panic!("Unsupported matrix size"),
923    }
924  }
925
926  pub fn index2d(&self, row: usize, col: usize) -> T {
927    match self {
928      #[cfg(feature = "row_vector4")]
929      Matrix::RowVector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
930      #[cfg(feature = "row_vector3")]
931      Matrix::RowVector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
932      #[cfg(feature = "row_vector2")]
933      Matrix::RowVector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
934      #[cfg(feature = "row_vectord")]
935      Matrix::RowDVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
936      #[cfg(feature = "vector4")]
937      Matrix::Vector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
938      #[cfg(feature = "vector3")]
939      Matrix::Vector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
940      #[cfg(feature = "vector2")]
941      Matrix::Vector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
942      #[cfg(feature = "vectord")]
943      Matrix::DVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
944      #[cfg(feature = "matrix4")]
945      Matrix::Matrix4(x) => (*x.borrow().index((row-1,col-1))).clone(),
946      #[cfg(feature = "matrix3")]
947      Matrix::Matrix3(x) => (*x.borrow().index((row-1,col-1))).clone(),
948      #[cfg(feature = "matrix2")]
949      Matrix::Matrix2(x) => (*x.borrow().index((row-1,col-1))).clone(),
950      #[cfg(feature = "matrix1")]
951      Matrix::Matrix1(x) => (*x.borrow().index((row-1,col-1))).clone(),
952      #[cfg(feature = "matrix3x2")]
953      Matrix::Matrix3x2(x) => (*x.borrow().index((row-1,col-1))).clone(),
954      #[cfg(feature = "matrix2x3")]
955      Matrix::Matrix2x3(x) => (*x.borrow().index((row-1,col-1))).clone(),
956      #[cfg(feature = "matrixd")]
957      Matrix::DMatrix(x) => (*x.borrow().index((row-1,col-1))).clone(),
958      _ => panic!("Unsupported matrix type for as_vec"),
959    }
960  }
961
962  pub fn as_vec(&self) -> Vec<T> {
963    match self {
964      #[cfg(feature = "row_vector4")]
965      Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(),
966      #[cfg(feature = "row_vector3")]
967      Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(),
968      #[cfg(feature = "row_vector2")]
969      Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(),
970      #[cfg(feature = "row_vectord")]
971      Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(),
972      #[cfg(feature = "vector4")]
973      Matrix::Vector4(x) => x.borrow().as_slice().to_vec(),
974      #[cfg(feature = "vector3")]
975      Matrix::Vector3(x) => x.borrow().as_slice().to_vec(),
976      #[cfg(feature = "vector2")]
977      Matrix::Vector2(x) => x.borrow().as_slice().to_vec(),
978      #[cfg(feature = "vectord")]
979      Matrix::DVector(x) => x.borrow().as_slice().to_vec(),
980      #[cfg(feature = "matrix4")]
981      Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(),
982      #[cfg(feature = "matrix3")]
983      Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(),
984      #[cfg(feature = "matrix2")]
985      Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(),
986      #[cfg(feature = "matrix1")]
987      Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(),
988      #[cfg(feature = "matrix3x2")]
989      Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(),
990      #[cfg(feature = "matrix2x3")]
991      Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(),
992      #[cfg(feature = "matrixd")]
993      Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(),
994      _ => panic!("Unsupported matrix type for as_vec"),
995    }
996  }
997
998}
999
1000macro_rules! impl_to_value_for_matrix {
1001  ($t:ty, $variant:ident) => {
1002    impl ToValue for Matrix<$t> {
1003      fn to_value(&self) -> Value {
1004        Value::$variant(self.clone())
1005      }
1006    }
1007  };
1008}
1009
1010impl_to_value_for_matrix!(Value, MatrixValue);
1011#[cfg(feature = "f64")]
1012impl_to_value_for_matrix!(f64, MatrixF64);
1013#[cfg(feature = "f32")]
1014impl_to_value_for_matrix!(f32, MatrixF32);
1015#[cfg(feature = "i8")]
1016impl_to_value_for_matrix!(i8, MatrixI8);
1017#[cfg(feature = "i16")]
1018impl_to_value_for_matrix!(i16, MatrixI16);
1019#[cfg(feature = "i32")]
1020impl_to_value_for_matrix!(i32, MatrixI32);
1021#[cfg(feature = "i64")]
1022impl_to_value_for_matrix!(i64, MatrixI64);
1023#[cfg(feature = "i128")]
1024impl_to_value_for_matrix!(i128, MatrixI128);
1025#[cfg(feature = "u8")]
1026impl_to_value_for_matrix!(u8, MatrixU8);
1027#[cfg(feature = "u16")]
1028impl_to_value_for_matrix!(u16, MatrixU16);
1029#[cfg(feature = "u32")]
1030impl_to_value_for_matrix!(u32, MatrixU32);
1031#[cfg(feature = "u64")]
1032impl_to_value_for_matrix!(u64, MatrixU64);
1033#[cfg(feature = "u128")]
1034impl_to_value_for_matrix!(u128, MatrixU128);
1035#[cfg(feature = "bool")]
1036impl_to_value_for_matrix!(bool, MatrixBool);
1037#[cfg(feature = "string")]
1038impl_to_value_for_matrix!(String, MatrixString);
1039#[cfg(feature = "complex")]
1040impl_to_value_for_matrix!(C64, MatrixC64);
1041#[cfg(feature = "rational")]
1042impl_to_value_for_matrix!(R64, MatrixR64);
1043
1044
1045macro_rules! to_value_ndmatrix {
1046  ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty, $type_string:tt),+ $(,)?) => {
1047    $(
1048      #[cfg(all(feature = "matrix", feature = $type_string))]
1049      impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
1050        fn to_value(&self) -> Value {
1051          Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
1052        }
1053      }
1054    )+
1055  };}
1056
1057macro_rules! impl_to_value_matrix {
1058  ($matrix_kind:ident) => {
1059    to_value_ndmatrix!(
1060      $matrix_kind, MatrixIndex,  usize, "matrix",
1061      $matrix_kind, MatrixBool,   bool, "bool",
1062      $matrix_kind, MatrixI8,     i8, "i8",
1063      $matrix_kind, MatrixI16,    i16, "i16",
1064      $matrix_kind, MatrixI32,    i32, "i32",
1065      $matrix_kind, MatrixI64,    i64, "i64",
1066      $matrix_kind, MatrixI128,   i128, "i128",
1067      $matrix_kind, MatrixU8,     u8, "u8",
1068      $matrix_kind, MatrixU16,    u16, "u16",
1069      $matrix_kind, MatrixU32,    u32, "u32",
1070      $matrix_kind, MatrixU64,    u64, "u64",
1071      $matrix_kind, MatrixU128,   u128, "u128",
1072      $matrix_kind, MatrixF32,    f32, "f32",
1073      $matrix_kind, MatrixF64,    f64, "f64",
1074      $matrix_kind, MatrixString, String, "string",
1075      $matrix_kind, MatrixR64, R64, "rational",
1076      $matrix_kind, MatrixC64, C64, "complex",
1077    );
1078  }
1079}
1080
1081#[cfg(feature = "matrix2x3")]
1082impl_to_value_matrix!(Matrix2x3);
1083#[cfg(feature = "matrix3x2")]
1084impl_to_value_matrix!(Matrix3x2);
1085#[cfg(feature = "matrix1")]
1086impl_to_value_matrix!(Matrix1);
1087#[cfg(feature = "matrix2")]
1088impl_to_value_matrix!(Matrix2);
1089#[cfg(feature = "matrix3")]
1090impl_to_value_matrix!(Matrix3);
1091#[cfg(feature = "matrix4")]
1092impl_to_value_matrix!(Matrix4);
1093#[cfg(feature = "vector2")]
1094impl_to_value_matrix!(Vector2);
1095#[cfg(feature = "vector3")]
1096impl_to_value_matrix!(Vector3);
1097#[cfg(feature = "vector4")]
1098impl_to_value_matrix!(Vector4);
1099#[cfg(feature = "row_vector2")]
1100impl_to_value_matrix!(RowVector2);
1101#[cfg(feature = "row_vector3")]
1102impl_to_value_matrix!(RowVector3);
1103#[cfg(feature = "row_vector4")]
1104impl_to_value_matrix!(RowVector4);
1105#[cfg(feature = "row_vectord")]
1106impl_to_value_matrix!(RowDVector);
1107#[cfg(feature = "vectord")]
1108impl_to_value_matrix!(DVector);
1109#[cfg(feature = "matrixd")]
1110impl_to_value_matrix!(DMatrix);
1111
1112// Errors
1113
1114#[derive(Debug, Clone)]
1115pub struct IncompatibleMatrixAppendToTableError {
1116  pub lhs_rows: usize,
1117  pub lhs_cols: usize,
1118  pub rhs_rows: usize,
1119  pub rhs_cols: usize,
1120}
1121impl MechErrorKind2 for IncompatibleMatrixAppendToTableError {
1122  fn name(&self) -> &str {
1123    "IncompatibleMatrixAppend"
1124  }
1125
1126  fn message(&self) -> String {
1127    format!(
1128      "Cannot append matrix {}x{} to matrix {}x{}.",
1129      self.lhs_rows, self.lhs_cols,
1130      self.rhs_rows, self.rhs_cols
1131    )
1132  }
1133}
1134
1135#[derive(Debug, Clone)]
1136pub struct ResizeStaticMatrixError;
1137
1138impl MechErrorKind2 for ResizeStaticMatrixError {
1139  fn name(&self) -> &str {
1140    "ResizeStaticMatrixError"
1141  }
1142  fn message(&self) -> String {
1143    format!("Cannot resize a static matrix.")
1144  }
1145}
1146
1147#[derive(Debug, Clone)]
1148pub struct PushIntoStaticMatrixError;
1149
1150impl MechErrorKind2 for PushIntoStaticMatrixError {
1151  fn name(&self) -> &str {
1152    "PushIntoStaticMatrix"
1153  }
1154
1155  fn message(&self) -> String {
1156    "Cannot push into a static matrix.".to_string()
1157  }
1158}