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 = "row_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,
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(lhs), Matrix::DVector(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(lhs), Matrix::RowDVector(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(MechError{
540          id: line!(),
541          file: file!().to_string(),
542          tokens: vec![],
543          msg: "".to_string(),
544          kind: MechErrorKind::None,
545        });
546      }    
547    }
548  }
549
550  pub fn push(&mut self, value: T) -> MResult<()> {
551    match self {
552      #[cfg(feature = "row_vectord")]
553      Matrix::RowDVector(vec) => {
554          let mut vec = vec.borrow_mut();
555          let new_len = vec.ncols() + 1;
556          vec.resize_horizontally_mut(new_len, value.clone()); // row vector: increase columns
557          Ok(())
558      }
559      #[cfg(feature = "vectord")]
560      Matrix::DVector(vec) => {
561          let mut vec = vec.borrow_mut();
562          let new_len = vec.nrows() + 1;
563          vec.resize_vertically_mut(new_len, value.clone()); // column vector: increase rows
564          Ok(())
565      }
566      _ => {
567        return Err(MechError{
568          id: line!(),
569          file: file!().to_string(),
570          tokens: vec![],
571          msg: "".to_string(),
572          kind: MechErrorKind::None,
573        });
574      }
575    }
576  }
577
578  pub fn rows(&self) -> usize {
579    let size = self.shape();
580    size[0]
581  }
582
583  pub fn cols(&self) -> usize {
584    let size = self.shape();
585    size[1]
586  }
587
588  pub fn size_of(&self) -> usize {
589    let vec = self.as_vec();
590    vec.capacity() * size_of::<T>()
591  }       
592
593  pub fn resize_vertically(&mut self, new_size: usize, fill_value: T) -> MResult<()> {
594    match self {
595      #[cfg(feature = "row_vectord")]
596      Matrix::RowDVector(vec) => {
597        let mut vec = vec.borrow_mut();
598        vec.resize_horizontally_mut(new_size, fill_value);
599        Ok(())
600      }
601      #[cfg(feature = "vectord")]
602      Matrix::DVector(vec) => {
603        let mut vec = vec.borrow_mut();
604        vec.resize_vertically_mut(new_size, fill_value);
605        Ok(())
606      }
607      _ => {
608        return Err(MechError{
609          id: line!(),
610          file: file!().to_string(),
611          tokens: vec![],
612          msg: "".to_string(),
613          kind: MechErrorKind::None,
614        });
615      }
616    }
617  }
618
619  pub fn shape(&self) -> Vec<usize> {
620    let shape = match self {
621      #[cfg(feature = "row_vector4")]
622      Matrix::RowVector4(x) => x.borrow().shape(),
623      #[cfg(feature = "row_vector3")]
624      Matrix::RowVector3(x) => x.borrow().shape(),
625      #[cfg(feature = "row_vector2")]
626      Matrix::RowVector2(x) => x.borrow().shape(),
627      #[cfg(feature = "row_vectord")]
628      Matrix::RowDVector(x) => x.borrow().shape(),
629      #[cfg(feature = "vector4")]
630      Matrix::Vector4(x) => x.borrow().shape(),
631      #[cfg(feature = "vector3")]
632      Matrix::Vector3(x) => x.borrow().shape(),
633      #[cfg(feature = "vector2")]
634      Matrix::Vector2(x) => x.borrow().shape(),
635      #[cfg(feature = "vectord")]
636      Matrix::DVector(x) => x.borrow().shape(),
637      #[cfg(feature = "matrix4")]
638      Matrix::Matrix4(x) => x.borrow().shape(),
639      #[cfg(feature = "matrix3")]
640      Matrix::Matrix3(x) => x.borrow().shape(),
641      #[cfg(feature = "matrix2")]
642      Matrix::Matrix2(x) => x.borrow().shape(),
643      #[cfg(feature = "matrix1")]
644      Matrix::Matrix1(x) => x.borrow().shape(),
645      #[cfg(feature = "matrix3x2")]
646      Matrix::Matrix3x2(x) => x.borrow().shape(),
647      #[cfg(feature = "matrix2x3")]
648      Matrix::Matrix2x3(x) => x.borrow().shape(),
649      #[cfg(feature = "matrixd")]
650      Matrix::DMatrix(x) => x.borrow().shape(),
651      _ => panic!("Unsupported matrix size"),
652    };
653    vec![shape.0, shape.1]
654  }
655
656  pub fn index1d(&self, ix: usize) -> T {
657    match self {
658      #[cfg(feature = "row_vector4")]
659      Matrix::RowVector4(x) => (*x.borrow().index(ix-1)).clone(),
660      #[cfg(feature = "row_vector3")]
661      Matrix::RowVector3(x) => (*x.borrow().index(ix-1)).clone(),
662      #[cfg(feature = "row_vector2")]
663      Matrix::RowVector2(x) => (*x.borrow().index(ix-1)).clone(),
664      #[cfg(feature = "row_vectord")]
665      Matrix::RowDVector(x) => (*x.borrow().index(ix-1)).clone(),
666      #[cfg(feature = "vector4")]
667      Matrix::Vector4(x) => (*x.borrow().index(ix-1)).clone(),
668      #[cfg(feature = "vector3")]
669      Matrix::Vector3(x) => (*x.borrow().index(ix-1)).clone(),
670      #[cfg(feature = "vector2")]
671      Matrix::Vector2(x) => (*x.borrow().index(ix-1)).clone(),
672      #[cfg(feature = "vectord")]
673      Matrix::DVector(x) => (*x.borrow().index(ix-1)).clone(),
674      #[cfg(feature = "matrix4")]
675      Matrix::Matrix4(x) => (*x.borrow().index(ix-1)).clone(),
676      #[cfg(feature = "matrix3")]
677      Matrix::Matrix3(x) => (*x.borrow().index(ix-1)).clone(),
678      #[cfg(feature = "matrix2")]
679      Matrix::Matrix2(x) => (*x.borrow().index(ix-1)).clone(),
680      #[cfg(feature = "matrix1")]
681      Matrix::Matrix1(x) => (*x.borrow().index(ix-1)).clone(),
682      #[cfg(feature = "matrix3x2")]
683      Matrix::Matrix3x2(x) => (*x.borrow().index(ix-1)).clone(),
684      #[cfg(feature = "matrix2x3")]
685      Matrix::Matrix2x3(x) => (*x.borrow().index(ix-1)).clone(),
686      #[cfg(feature = "matrixd")]
687      Matrix::DMatrix(x) => (*x.borrow().index(ix-1)).clone(),
688      _ => panic!("Unsupported matrix size"),
689    }
690  }
691
692  pub fn set_index1d(&self, index: usize, value: T) {
693    match self {
694      #[cfg(feature = "row_vector4")]
695      Matrix::RowVector4(v) => v.borrow_mut()[index] = value,
696      #[cfg(feature = "row_vector3")]
697      Matrix::RowVector3(v) => v.borrow_mut()[index] = value,
698      #[cfg(feature = "row_vector2")]
699      Matrix::RowVector2(v) => v.borrow_mut()[index] = value,
700      #[cfg(feature = "row_vectord")]
701      Matrix::RowDVector(v) => v.borrow_mut()[index] = value,
702      #[cfg(feature = "vector4")]
703      Matrix::Vector4(v) => v.borrow_mut()[index] = value,
704      #[cfg(feature = "vector3")]
705      Matrix::Vector3(v) => v.borrow_mut()[index] = value,
706      #[cfg(feature = "vector2")]
707      Matrix::Vector2(v) => v.borrow_mut()[index] = value,
708      #[cfg(feature = "vectord")]
709      Matrix::DVector(v) => v.borrow_mut()[index] = value,
710      #[cfg(feature = "matrix1")]
711      Matrix::Matrix1(m) => m.borrow_mut()[index] = value,
712      #[cfg(feature = "matrix2")]
713      Matrix::Matrix2(m) => m.borrow_mut()[index] = value,
714      #[cfg(feature = "matrix3")]
715      Matrix::Matrix3(m) => m.borrow_mut()[index] = value,
716      #[cfg(feature = "matrix4")]
717      Matrix::Matrix4(m) => m.borrow_mut()[index] = value,
718      #[cfg(feature = "matrix2x3")]
719      Matrix::Matrix2x3(m) => m.borrow_mut()[index] = value,
720      #[cfg(feature = "matrix3x2")]
721      Matrix::Matrix3x2(m) => m.borrow_mut()[index] = value,
722      #[cfg(feature = "matrixd")]
723      Matrix::DMatrix(m) => m.borrow_mut()[index] = value,
724      _ => panic!("Unsupported matrix size"),
725    }
726  }
727
728  pub fn from_element(rows: usize, cols: usize, element: T) -> Matrix<T> {
729    match (rows,cols) {
730      #[cfg(feature = "matrix1")]
731      (1,1) => Matrix::Matrix1(Ref::new(Matrix1::from_element(element.clone()))),
732      #[cfg(all(feature = "matrixd", not(feature = "matrix1")))]
733      (1,1) => Matrix::DMatrix(Ref::new(DMatrix::from_element(1,1,element.clone()))),
734      #[cfg(feature = "matrix2")]
735      (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_element(element.clone()))),
736      #[cfg(feature = "matrix3")]
737      (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_element(element.clone()))),
738      #[cfg(feature = "matrix4")]
739      (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_element(element.clone()))),
740      #[cfg(feature = "matrix2x3")]
741      (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_element(element.clone()))),
742      #[cfg(feature = "matrix3x2")]
743      (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_element(element.clone()))),
744      #[cfg(feature = "vector4")]
745      (4,1) => Matrix::Vector4(Ref::new(Vector4::from_element(element.clone()))),
746      #[cfg(feature = "vector3")]
747      (3,1) => Matrix::Vector3(Ref::new(Vector3::from_element(element.clone()))),
748      #[cfg(feature = "vector2")]
749      (2,1) => Matrix::Vector2(Ref::new(Vector2::from_element(element.clone()))),
750      #[cfg(feature = "row_vector4")]
751      (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_element(element.clone()))),
752      #[cfg(feature = "row_vector3")]
753      (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_element(element.clone()))),
754      #[cfg(feature = "row_vector2")]
755      (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_element(element.clone()))),
756      #[cfg(feature = "row_vectord")]
757      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_element(n,element.clone()))),
758      #[cfg(feature = "vectord")]
759      (m,1) => Matrix::DVector(Ref::new(DVector::from_element(m,element.clone()))),
760      #[cfg(feature = "matrixd")]
761      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_element(m,n,element.clone()))),
762      _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
763    }
764  }
765
766  pub fn from_vec(vec: Vec<T>, rows: usize, cols: usize) -> Matrix<T> {
767    match (rows,cols) {
768      #[cfg(feature = "matrix1")]
769      (1,1) => Matrix::Matrix1(Ref::new(Matrix1::from_vec(vec.clone()))),
770      #[cfg(all(feature = "matrixd", not(feature = "matrix1")))]
771      (1,1) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(1,1,vec.clone()))),
772      #[cfg(feature = "matrix2")]
773      (2,2) => Matrix::Matrix2(Ref::new(Matrix2::from_vec(vec.clone()))),
774      #[cfg(feature = "matrix3")]
775      (3,3) => Matrix::Matrix3(Ref::new(Matrix3::from_vec(vec.clone()))),
776      #[cfg(feature = "matrix4")]
777      (4,4) => Matrix::Matrix4(Ref::new(Matrix4::from_vec(vec.clone()))),
778      #[cfg(feature = "matrix2x3")]
779      (2,3) => Matrix::Matrix2x3(Ref::new(Matrix2x3::from_vec(vec.clone()))),
780      #[cfg(feature = "matrix3x2")]
781      (3,2) => Matrix::Matrix3x2(Ref::new(Matrix3x2::from_vec(vec.clone()))),
782      #[cfg(feature = "vector4")]
783      (4,1) => Matrix::Vector4(Ref::new(Vector4::from_vec(vec.clone()))),
784      #[cfg(feature = "vector3")]
785      (3,1) => Matrix::Vector3(Ref::new(Vector3::from_vec(vec.clone()))),
786      #[cfg(feature = "vector2")]
787      (2,1) => Matrix::Vector2(Ref::new(Vector2::from_vec(vec.clone()))),
788      #[cfg(feature = "row_vector4")]
789      (1,4) => Matrix::RowVector4(Ref::new(RowVector4::from_vec(vec.clone()))),
790      #[cfg(feature = "row_vector3")]
791      (1,3) => Matrix::RowVector3(Ref::new(RowVector3::from_vec(vec.clone()))),
792      #[cfg(feature = "row_vector2")]
793      (1,2) => Matrix::RowVector2(Ref::new(RowVector2::from_vec(vec.clone()))),
794      #[cfg(feature = "row_vectord")]
795      (1,n) => Matrix::RowDVector(Ref::new(RowDVector::from_vec(vec.clone()))),
796      #[cfg(feature = "vectord")]
797      (m,1) => Matrix::DVector(Ref::new(DVector::from_vec(vec.clone()))),
798      #[cfg(feature = "matrixd")]
799      (m,n) => Matrix::DMatrix(Ref::new(DMatrix::from_vec(m,n,vec.clone()))),
800      _ => panic!("Cannot convert to matrix with rows: {rows} and cols: {cols}"),
801    }
802  }
803
804  pub fn set(&self, elements: Vec<T>) {
805    match self {
806      #[cfg(feature = "row_vector4")]
807      Matrix::RowVector4(x) => {
808        let mut x = x.borrow_mut();
809        x[0] = elements[0].clone();
810        x[1] = elements[1].clone();
811        x[2] = elements[2].clone();
812        x[3] = elements[3].clone();
813      }
814      #[cfg(feature = "row_vector3")]
815      Matrix::RowVector3(x) => {
816        let mut x = x.borrow_mut();
817        x[0] = elements[0].clone();
818        x[1] = elements[1].clone();
819        x[2] = elements[2].clone();
820      }
821      #[cfg(feature = "row_vector2")]
822      Matrix::RowVector2(x) => {
823        let mut x = x.borrow_mut();
824        x[0] = elements[0].clone();
825        x[1] = elements[1].clone();
826      }
827      #[cfg(feature = "row_vectord")]
828      Matrix::RowDVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
829      #[cfg(feature = "vector4")]
830      Matrix::Vector4(x) => {
831        let mut x = x.borrow_mut();
832        x[0] = elements[0].clone();
833        x[1] = elements[1].clone();
834        x[2] = elements[2].clone();
835        x[3] = elements[3].clone();
836      }
837      #[cfg(feature = "vector3")]
838      Matrix::Vector3(x) => {
839        let mut x = x.borrow_mut();
840        x[0] = elements[0].clone();
841        x[1] = elements[1].clone();
842        x[2] = elements[2].clone();
843      }
844      #[cfg(feature = "vector2")]
845      Matrix::Vector2(x) => {
846        let mut x = x.borrow_mut();
847        x[0] = elements[0].clone();
848        x[1] = elements[1].clone();
849      }
850      #[cfg(feature = "vectord")]
851      Matrix::DVector(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
852      #[cfg(feature = "matrix4")]
853      Matrix::Matrix4(x) => {
854        let mut x = x.borrow_mut();
855        x[0] = elements[0].clone();
856        x[1] = elements[1].clone();
857        x[2] = elements[2].clone();
858        x[3] = elements[3].clone();
859        x[4] = elements[4].clone();
860        x[5] = elements[5].clone();
861        x[6] = elements[6].clone();
862        x[7] = elements[7].clone();
863        x[8] = elements[8].clone();
864        x[9] = elements[9].clone();
865        x[10] = elements[10].clone();
866        x[11] = elements[11].clone();
867        x[12] = elements[12].clone();
868        x[13] = elements[13].clone();
869        x[14] = elements[14].clone();
870        x[15] = elements[15].clone();
871      }
872      #[cfg(feature = "matrix3")]
873      Matrix::Matrix3(x) => {
874        let mut x = x.borrow_mut();
875        x[0] = elements[0].clone();
876        x[1] = elements[1].clone();
877        x[2] = elements[2].clone();
878        x[3] = elements[3].clone();
879        x[4] = elements[4].clone();
880        x[5] = elements[5].clone();
881        x[6] = elements[6].clone();
882        x[7] = elements[7].clone();
883        x[8] = elements[8].clone();
884      }
885      #[cfg(feature = "matrix2")]
886      Matrix::Matrix2(x) => {
887        let mut x = x.borrow_mut();
888        x[0] = elements[0].clone();
889        x[1] = elements[1].clone();
890        x[2] = elements[2].clone();
891        x[3] = elements[3].clone();
892      }
893      #[cfg(feature = "matrix1")]
894      Matrix::Matrix1(x) => {let mut x = x.borrow_mut();x[0] = elements[0].clone();},
895      #[cfg(feature = "matrix3x2")]
896      Matrix::Matrix3x2(x) => {
897        let mut x = x.borrow_mut();
898        x[0] = elements[0].clone();
899        x[1] = elements[1].clone();
900        x[2] = elements[2].clone();
901        x[3] = elements[3].clone();
902        x[4] = elements[4].clone();
903        x[5] = elements[5].clone();
904      }
905      #[cfg(feature = "matrix2x3")]
906      Matrix::Matrix2x3(x) => {
907        let mut x = x.borrow_mut();
908        x[0] = elements[0].clone();
909        x[1] = elements[1].clone();
910        x[2] = elements[2].clone();
911        x[3] = elements[3].clone();
912        x[4] = elements[4].clone();
913        x[5] = elements[5].clone();
914      }
915      #[cfg(feature = "matrixd")]
916      Matrix::DMatrix(x) => {let mut x = x.borrow_mut();for i in 0..elements.len() {x[i] = elements[i].clone()}},
917      _ => panic!("Unsupported matrix size"),
918    }
919  }
920
921  pub fn index2d(&self, row: usize, col: usize) -> T {
922    match self {
923      #[cfg(feature = "row_vector4")]
924      Matrix::RowVector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
925      #[cfg(feature = "row_vector3")]
926      Matrix::RowVector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
927      #[cfg(feature = "row_vector2")]
928      Matrix::RowVector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
929      #[cfg(feature = "row_vectord")]
930      Matrix::RowDVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
931      #[cfg(feature = "vector4")]
932      Matrix::Vector4(x) => (*x.borrow().index((row-1,col-1))).clone(),
933      #[cfg(feature = "vector3")]
934      Matrix::Vector3(x) => (*x.borrow().index((row-1,col-1))).clone(),
935      #[cfg(feature = "vector2")]
936      Matrix::Vector2(x) => (*x.borrow().index((row-1,col-1))).clone(),
937      #[cfg(feature = "vectord")]
938      Matrix::DVector(x) => (*x.borrow().index((row-1,col-1))).clone(),
939      #[cfg(feature = "matrix4")]
940      Matrix::Matrix4(x) => (*x.borrow().index((row-1,col-1))).clone(),
941      #[cfg(feature = "matrix3")]
942      Matrix::Matrix3(x) => (*x.borrow().index((row-1,col-1))).clone(),
943      #[cfg(feature = "matrix2")]
944      Matrix::Matrix2(x) => (*x.borrow().index((row-1,col-1))).clone(),
945      #[cfg(feature = "matrix1")]
946      Matrix::Matrix1(x) => (*x.borrow().index((row-1,col-1))).clone(),
947      #[cfg(feature = "matrix3x2")]
948      Matrix::Matrix3x2(x) => (*x.borrow().index((row-1,col-1))).clone(),
949      #[cfg(feature = "matrix2x3")]
950      Matrix::Matrix2x3(x) => (*x.borrow().index((row-1,col-1))).clone(),
951      #[cfg(feature = "matrixd")]
952      Matrix::DMatrix(x) => (*x.borrow().index((row-1,col-1))).clone(),
953      _ => panic!("Unsupported matrix type for as_vec"),
954    }
955  }
956
957  pub fn as_vec(&self) -> Vec<T> {
958    match self {
959      #[cfg(feature = "row_vector4")]
960      Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(),
961      #[cfg(feature = "row_vector3")]
962      Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(),
963      #[cfg(feature = "row_vector2")]
964      Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(),
965      #[cfg(feature = "row_vectord")]
966      Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(),
967      #[cfg(feature = "vector4")]
968      Matrix::Vector4(x) => x.borrow().as_slice().to_vec(),
969      #[cfg(feature = "vector3")]
970      Matrix::Vector3(x) => x.borrow().as_slice().to_vec(),
971      #[cfg(feature = "vector2")]
972      Matrix::Vector2(x) => x.borrow().as_slice().to_vec(),
973      #[cfg(feature = "vectord")]
974      Matrix::DVector(x) => x.borrow().as_slice().to_vec(),
975      #[cfg(feature = "matrix4")]
976      Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(),
977      #[cfg(feature = "matrix3")]
978      Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(),
979      #[cfg(feature = "matrix2")]
980      Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(),
981      #[cfg(feature = "matrix1")]
982      Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(),
983      #[cfg(feature = "matrix3x2")]
984      Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(),
985      #[cfg(feature = "matrix2x3")]
986      Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(),
987      #[cfg(feature = "matrixd")]
988      Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(),
989      _ => panic!("Unsupported matrix type for as_vec"),
990    }
991  }
992
993}
994
995macro_rules! impl_to_value_for_matrix {
996  ($t:ty, $variant:ident) => {
997    impl ToValue for Matrix<$t> {
998      fn to_value(&self) -> Value {
999        Value::$variant(self.clone())
1000      }
1001    }
1002  };
1003}
1004
1005impl_to_value_for_matrix!(Value, MatrixValue);
1006#[cfg(feature = "f64")]
1007impl_to_value_for_matrix!(F64, MatrixF64);
1008#[cfg(feature = "f32")]
1009impl_to_value_for_matrix!(F32, MatrixF32);
1010#[cfg(feature = "i8")]
1011impl_to_value_for_matrix!(i8, MatrixI8);
1012#[cfg(feature = "i16")]
1013impl_to_value_for_matrix!(i16, MatrixI16);
1014#[cfg(feature = "i32")]
1015impl_to_value_for_matrix!(i32, MatrixI32);
1016#[cfg(feature = "i64")]
1017impl_to_value_for_matrix!(i64, MatrixI64);
1018#[cfg(feature = "i128")]
1019impl_to_value_for_matrix!(i128, MatrixI128);
1020#[cfg(feature = "u8")]
1021impl_to_value_for_matrix!(u8, MatrixU8);
1022#[cfg(feature = "u16")]
1023impl_to_value_for_matrix!(u16, MatrixU16);
1024#[cfg(feature = "u32")]
1025impl_to_value_for_matrix!(u32, MatrixU32);
1026#[cfg(feature = "u64")]
1027impl_to_value_for_matrix!(u64, MatrixU64);
1028#[cfg(feature = "u128")]
1029impl_to_value_for_matrix!(u128, MatrixU128);
1030#[cfg(feature = "bool")]
1031impl_to_value_for_matrix!(bool, MatrixBool);
1032#[cfg(feature = "string")]
1033impl_to_value_for_matrix!(String, MatrixString);
1034#[cfg(feature = "complex")]
1035impl_to_value_for_matrix!(C64, MatrixC64);
1036#[cfg(feature = "rational")]
1037impl_to_value_for_matrix!(R64, MatrixR64);
1038
1039
1040macro_rules! to_value_ndmatrix {
1041  ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty, $type_string:tt),+ $(,)?) => {
1042    $(
1043      #[cfg(all(feature = "matrix", feature = $type_string))]
1044      impl ToValue for Ref<$nd_matrix_kind<$base_type>> {
1045        fn to_value(&self) -> Value {
1046          Value::$matrix_kind(Matrix::<$base_type>::$nd_matrix_kind(self.clone()))
1047        }
1048      }
1049    )+
1050  };}
1051
1052macro_rules! impl_to_value_matrix {
1053  ($matrix_kind:ident) => {
1054    to_value_ndmatrix!(
1055      $matrix_kind, MatrixIndex,  usize, "matrix",
1056      $matrix_kind, MatrixBool,   bool, "bool",
1057      $matrix_kind, MatrixI8,     i8, "i8",
1058      $matrix_kind, MatrixI16,    i16, "i16",
1059      $matrix_kind, MatrixI32,    i32, "i32",
1060      $matrix_kind, MatrixI64,    i64, "i64",
1061      $matrix_kind, MatrixI128,   i128, "i128",
1062      $matrix_kind, MatrixU8,     u8, "u8",
1063      $matrix_kind, MatrixU16,    u16, "u16",
1064      $matrix_kind, MatrixU32,    u32, "u32",
1065      $matrix_kind, MatrixU64,    u64, "u64",
1066      $matrix_kind, MatrixU128,   u128, "u128",
1067      $matrix_kind, MatrixF32,    F32, "f32",
1068      $matrix_kind, MatrixF64,    F64, "f64",
1069      $matrix_kind, MatrixString, String, "string",
1070      $matrix_kind, MatrixR64, R64, "rational",
1071      $matrix_kind, MatrixC64, C64, "complex",
1072    );
1073  }
1074}
1075
1076#[cfg(feature = "matrix2x3")]
1077impl_to_value_matrix!(Matrix2x3);
1078#[cfg(feature = "matrix3x2")]
1079impl_to_value_matrix!(Matrix3x2);
1080#[cfg(feature = "matrix1")]
1081impl_to_value_matrix!(Matrix1);
1082#[cfg(feature = "matrix2")]
1083impl_to_value_matrix!(Matrix2);
1084#[cfg(feature = "matrix3")]
1085impl_to_value_matrix!(Matrix3);
1086#[cfg(feature = "matrix4")]
1087impl_to_value_matrix!(Matrix4);
1088#[cfg(feature = "vector2")]
1089impl_to_value_matrix!(Vector2);
1090#[cfg(feature = "vector3")]
1091impl_to_value_matrix!(Vector3);
1092#[cfg(feature = "vector4")]
1093impl_to_value_matrix!(Vector4);
1094#[cfg(feature = "row_vector2")]
1095impl_to_value_matrix!(RowVector2);
1096#[cfg(feature = "row_vector3")]
1097impl_to_value_matrix!(RowVector3);
1098#[cfg(feature = "row_vector4")]
1099impl_to_value_matrix!(RowVector4);
1100#[cfg(feature = "row_vectord")]
1101impl_to_value_matrix!(RowDVector);
1102#[cfg(feature = "vectord")]
1103impl_to_value_matrix!(DVector);
1104#[cfg(feature = "matrixd")]
1105impl_to_value_matrix!(DMatrix);