use crate::traits::{MatrixMut, MatrixRef, Scalar};
use crate::Matrix;
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
From<Matrix<T, M, N>> for nalgebra::SMatrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn from(m: Matrix<T, M, N>) -> Self {
nalgebra::SMatrix::from_column_slice(m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
From<&Matrix<T, M, N>> for nalgebra::SMatrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn from(m: &Matrix<T, M, N>) -> Self {
nalgebra::SMatrix::from_column_slice(m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
From<nalgebra::SMatrix<T, M, N>> for Matrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn from(m: nalgebra::SMatrix<T, M, N>) -> Self {
Matrix::from_slice(m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
From<&nalgebra::SMatrix<T, M, N>> for Matrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn from(m: &nalgebra::SMatrix<T, M, N>) -> Self {
Matrix::from_slice(m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
MatrixRef<T> for nalgebra::SMatrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn nrows(&self) -> usize {
M
}
#[inline]
fn ncols(&self) -> usize {
N
}
#[inline]
fn get(&self, row: usize, col: usize) -> &T {
&self[(row, col)]
}
#[inline]
fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
let start = col * M + row_start;
let end = (col + 1) * M;
&self.as_slice()[start..end]
}
}
impl<T: Scalar + nalgebra::Scalar, const M: usize, const N: usize>
MatrixMut<T> for nalgebra::SMatrix<T, M, N>
where
nalgebra::Const<M>: nalgebra::DimName,
nalgebra::Const<N>: nalgebra::DimName,
{
#[inline]
fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
&mut self[(row, col)]
}
#[inline]
fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
let start = col * M + row_start;
let end = (col + 1) * M;
&mut self.as_mut_slice()[start..end]
}
}
#[cfg(feature = "alloc")]
mod dyn_interop {
use crate::dynmatrix::{DynMatrix, DynVector};
use crate::traits::{MatrixMut, MatrixRef, Scalar};
impl<T: Scalar + nalgebra::Scalar> From<DynMatrix<T>> for nalgebra::DMatrix<T> {
#[inline]
fn from(m: DynMatrix<T>) -> Self {
nalgebra::DMatrix::from_column_slice(m.nrows(), m.ncols(), m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<&DynMatrix<T>> for nalgebra::DMatrix<T> {
#[inline]
fn from(m: &DynMatrix<T>) -> Self {
nalgebra::DMatrix::from_column_slice(m.nrows(), m.ncols(), m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<nalgebra::DMatrix<T>> for DynMatrix<T> {
#[inline]
fn from(m: nalgebra::DMatrix<T>) -> Self {
DynMatrix::from_slice(m.nrows(), m.ncols(), m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<&nalgebra::DMatrix<T>> for DynMatrix<T> {
#[inline]
fn from(m: &nalgebra::DMatrix<T>) -> Self {
DynMatrix::from_slice(m.nrows(), m.ncols(), m.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<DynVector<T>> for nalgebra::DVector<T> {
#[inline]
fn from(v: DynVector<T>) -> Self {
nalgebra::DVector::from_column_slice(v.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<&DynVector<T>> for nalgebra::DVector<T> {
#[inline]
fn from(v: &DynVector<T>) -> Self {
nalgebra::DVector::from_column_slice(v.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<nalgebra::DVector<T>> for DynVector<T> {
#[inline]
fn from(v: nalgebra::DVector<T>) -> Self {
DynVector::from_slice(v.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> From<&nalgebra::DVector<T>> for DynVector<T> {
#[inline]
fn from(v: &nalgebra::DVector<T>) -> Self {
DynVector::from_slice(v.as_slice())
}
}
impl<T: Scalar + nalgebra::Scalar> MatrixRef<T> for nalgebra::DMatrix<T> {
#[inline]
fn nrows(&self) -> usize {
self.nrows()
}
#[inline]
fn ncols(&self) -> usize {
self.ncols()
}
#[inline]
fn get(&self, row: usize, col: usize) -> &T {
&self[(row, col)]
}
#[inline]
fn col_as_slice(&self, col: usize, row_start: usize) -> &[T] {
let nrows = self.nrows();
let start = col * nrows + row_start;
let end = (col + 1) * nrows;
&self.as_slice()[start..end]
}
}
impl<T: Scalar + nalgebra::Scalar> MatrixMut<T> for nalgebra::DMatrix<T> {
#[inline]
fn get_mut(&mut self, row: usize, col: usize) -> &mut T {
&mut self[(row, col)]
}
#[inline]
fn col_as_mut_slice(&mut self, col: usize, row_start: usize) -> &mut [T] {
let nrows = self.nrows();
let start = col * nrows + row_start;
let end = (col + 1) * nrows;
&mut self.as_mut_slice()[start..end]
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matrix_to_smatrix_roundtrip() {
let nm = Matrix::new([[1.0_f64, 2.0], [3.0, 4.0]]);
let na: nalgebra::SMatrix<f64, 2, 2> = nm.into();
assert_eq!(na[(0, 0)], 1.0);
assert_eq!(na[(0, 1)], 2.0);
assert_eq!(na[(1, 0)], 3.0);
assert_eq!(na[(1, 1)], 4.0);
let back: Matrix<f64, 2, 2> = na.into();
assert_eq!(back, nm);
}
#[test]
fn matrix_ref_roundtrip() {
let nm = Matrix::new([[1.0_f64, 2.0, 3.0], [4.0, 5.0, 6.0]]);
let na: nalgebra::SMatrix<f64, 2, 3> = (&nm).into();
let back: Matrix<f64, 2, 3> = (&na).into();
assert_eq!(back, nm);
}
#[test]
fn vector_to_svector_roundtrip() {
use crate::Vector;
let nv = Vector::from_array([1.0_f64, 2.0, 3.0]);
let na: nalgebra::SVector<f64, 3> = nv.into();
assert_eq!(na[0], 1.0);
assert_eq!(na[1], 2.0);
assert_eq!(na[2], 3.0);
assert_eq!(na.nrows(), 3);
assert_eq!(na.ncols(), 1);
let back: Vector<f64, 3> = na.into();
assert_eq!(back, nv);
}
#[test]
fn vector_ref_roundtrip() {
use crate::Vector;
let nv = Vector::from_array([10.0_f32, 20.0, 30.0, 40.0]);
let na: nalgebra::SMatrix<f32, 4, 1> = (&nv).into();
let back: Vector<f32, 4> = (&na).into();
assert_eq!(back, nv);
}
#[test]
fn smatrix_matrix_ref_trait() {
let na = nalgebra::SMatrix::<f64, 3, 3>::new(
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0,
);
assert_eq!(na.nrows(), 3);
assert_eq!(na.ncols(), 3);
assert_eq!(*MatrixRef::get(&na, 0, 0), 1.0);
assert_eq!(*MatrixRef::get(&na, 1, 0), 4.0);
assert_eq!(*MatrixRef::get(&na, 0, 1), 2.0);
let col1 = MatrixRef::col_as_slice(&na, 1, 0);
assert_eq!(col1, &[2.0, 5.0, 8.0]);
let col2_from1 = MatrixRef::col_as_slice(&na, 2, 1);
assert_eq!(col2_from1, &[6.0, 9.0]);
}
#[test]
fn smatrix_matrix_mut_trait() {
let mut na = nalgebra::SMatrix::<f64, 2, 2>::zeros();
*MatrixMut::get_mut(&mut na, 0, 1) = 42.0;
assert_eq!(na[(0, 1)], 42.0);
let col = MatrixMut::col_as_mut_slice(&mut na, 0, 0);
col[0] = 10.0;
col[1] = 20.0;
assert_eq!(na[(0, 0)], 10.0);
assert_eq!(na[(1, 0)], 20.0);
}
#[test]
fn lu_on_nalgebra_smatrix() {
use crate::linalg::lu::lu_in_place;
let mut na = nalgebra::SMatrix::<f64, 3, 3>::new(
2.0, 1.0, -1.0,
-3.0, -1.0, 2.0,
-2.0, 1.0, 2.0,
);
let mut perm = [0usize; 3];
let result = lu_in_place(&mut na, &mut perm);
assert!(result.is_ok());
}
#[test]
fn cholesky_on_nalgebra_smatrix() {
use crate::linalg::cholesky::cholesky_in_place;
let mut na = nalgebra::SMatrix::<f64, 2, 2>::new(4.0, 2.0, 2.0, 3.0);
let result = cholesky_in_place(&mut na);
assert!(result.is_ok());
}
#[test]
fn nonsquare_matrix_roundtrip() {
let nm = Matrix::new([[1.0_f64, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]]);
let na: nalgebra::SMatrix<f64, 3, 4> = nm.into();
let back: Matrix<f64, 3, 4> = na.into();
assert_eq!(back, nm);
}
#[test]
fn i32_matrix_roundtrip() {
let nm = Matrix::new([[1_i32, 2], [3, 4]]);
let na: nalgebra::SMatrix<i32, 2, 2> = nm.into();
let back: Matrix<i32, 2, 2> = na.into();
assert_eq!(back, nm);
}
#[cfg(feature = "alloc")]
mod dyn_tests {
use crate::dynmatrix::{DynMatrix, DynVector};
use crate::traits::{MatrixMut, MatrixRef};
#[test]
fn dynmatrix_to_dmatrix_roundtrip() {
let dm = DynMatrix::from_rows(2, 3, &[1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0]);
let na: nalgebra::DMatrix<f64> = (&dm).into();
assert_eq!(na.nrows(), 2);
assert_eq!(na.ncols(), 3);
assert_eq!(na[(0, 0)], 1.0);
assert_eq!(na[(0, 2)], 3.0);
assert_eq!(na[(1, 0)], 4.0);
let back: DynMatrix<f64> = na.into();
assert_eq!(back, dm);
}
#[test]
fn dynvector_to_dvector_roundtrip() {
let dv = DynVector::from_slice(&[1.0_f64, 2.0, 3.0]);
let na: nalgebra::DVector<f64> = (&dv).into();
assert_eq!(na.len(), 3);
assert_eq!(na[0], 1.0);
assert_eq!(na[2], 3.0);
let back: DynVector<f64> = na.into();
assert_eq!(back, dv);
}
#[test]
fn dmatrix_matrix_ref_trait() {
let na = nalgebra::DMatrix::from_row_slice(2, 3, &[
1.0_f64, 2.0, 3.0,
4.0, 5.0, 6.0,
]);
assert_eq!(MatrixRef::nrows(&na), 2);
assert_eq!(MatrixRef::ncols(&na), 3);
assert_eq!(*MatrixRef::get(&na, 0, 0), 1.0);
assert_eq!(*MatrixRef::get(&na, 1, 0), 4.0);
assert_eq!(*MatrixRef::get(&na, 0, 2), 3.0);
let col1 = MatrixRef::col_as_slice(&na, 1, 0);
assert_eq!(col1, &[2.0, 5.0]);
}
#[test]
fn dmatrix_matrix_mut_trait() {
let mut na = nalgebra::DMatrix::zeros(3, 3);
*MatrixMut::get_mut(&mut na, 1, 2) = 99.0;
assert_eq!(na[(1, 2)], 99.0);
let col = MatrixMut::col_as_mut_slice(&mut na, 0, 1);
col[0] = 10.0;
col[1] = 20.0;
assert_eq!(na[(1, 0)], 10.0);
assert_eq!(na[(2, 0)], 20.0);
}
#[test]
fn lu_on_nalgebra_dmatrix() {
use crate::linalg::lu::lu_in_place;
let mut na = nalgebra::DMatrix::from_row_slice(3, 3, &[
2.0_f64, 1.0, -1.0,
-3.0, -1.0, 2.0,
-2.0, 1.0, 2.0,
]);
let mut perm = [0usize; 3];
let result = lu_in_place(&mut na, &mut perm);
assert!(result.is_ok());
}
}
}