rustnalgebra

nalgebra type annotations for converting Matrix to DMatrix


I'm trying to convert a static matrix into a dynamic matrix using a function. Reason being is that I'm comparing two matrices for unit-testing. Thus the test_value from the test, and the benchmark matrices have to be the same element wise. They will only compare though if they're the same type and sometimes the test_value is a static matrix. I'd like a function that takes in a static matrix type and converts it into a dynamic matrix. So far using the vscode refactor tool I've managed this:

    fn matrix_to_dynamic_matrix(matrix: Matrix<f64, Const, Const, ArrayStorage<f64>>) -> Matrix<f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>> {
        let matrix_vector:Vec<f64> = matrix.iter().map(|x| x.to_owned()).collect();
        let (rows, columns) = matrix.shape();
        let matrix_dynamic:DMatrix<f64> = DMatrix::from_vec(rows, columns, matrix_vector);
        matrix_dynamic
    }

The compiler won't get past the Matrix<f64, Const, Const, ArrayStorage<f64>>. What the right way to take in the statically sized matrix into the function?


Solution

  • Since you don't know size of static matrix use generic size type for your function:

    use nalgebra;
    use nalgebra::allocator::Allocator;
    use nalgebra::DefaultAllocator;
    use nalgebra::DimMinimum;
    
    // rust nalgebra convert static matrix to dynamic matrix
    fn static_to_dynamic_matrix<R, C>(matrix: nalgebra::OMatrix<f64, R, C>) -> nalgebra::OMatrix<f64, nalgebra::Dynamic, nalgebra::Dynamic>
        where
        R: nalgebra::Dim + nalgebra::DimMin<C>,
        C: nalgebra::Dim,
        DefaultAllocator: Allocator<f64, R, C>
    {
        let mut dynamic_matrix = nalgebra::OMatrix::<f64, nalgebra::Dynamic, nalgebra::Dynamic>::zeros(matrix.nrows(), matrix.ncols());
        for i in 0..matrix.nrows() {
            for j in 0..matrix.ncols() {
                dynamic_matrix[(i, j)] = matrix[(i, j)];
            }
        }
        dynamic_matrix
    }
    
    mod tests {
        use super::*;
    
        #[test]
        fn test_static_to_dynamic_matrix() {
            let matrix = nalgebra::OMatrix::<f64, nalgebra::U3, nalgebra::U3>::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
            let dynamic_matrix = static_to_dynamic_matrix(matrix);
            assert_eq!(dynamic_matrix.nrows(), 3);
            assert_eq!(dynamic_matrix.ncols(), 3);
            assert_eq!(dynamic_matrix[(0, 0)], 1.0);
            assert_eq!(dynamic_matrix[(0, 1)], 2.0);
    
        }
    }