3

I am working on some software where I am managing a buffer of floats in a Vec<T> where T is either an f32 or f64. I sometimes need to interpret this buffer, or sections of it, as a mathematical vector. To this end, I am taking advantage of MatrixSlice and friends in nalgebra.

I can create a DVectorSliceMut, for example, the following way

fn as_vector<'a>(slice: &'a mut [f64]) -> DVectorSliceMut<'a, f64> {
    DVectorSliceMut::from(slice)
}

However, sometimes I need to later extract the original slice from the DVectorSliceMut with the original lifetime 'a. Is there a way to do this?

The StorageMut trait has a as_mut_slice member function, but the lifetime of the returned slice is the lifetime of the reference to the Storage implementor, not the original slice. I am okay with a solution which consumes the DVectorSliceMut if necessary.

Update: Methods into_slice and into_slice_mut have been respectively added to the SliceStorage and SliceStorageMut traits as of nalgebra v0.28.0.

Wil
  • 115
  • 6
  • Have you tried `Into::<&mut [f64]>::into`? – Kitsu Jun 17 '21 at 20:31
  • Yep. It's not currently implemented. – Wil Jun 17 '21 at 21:09
  • What do you mean "not implemented"? Works fine in [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bd885d02843dadb3abeb86ead48a1aba) – Kitsu Jun 18 '21 at 08:11
  • Instead of editing the question, please add the update as an answer, since it solves the original problem. You can accept your own answer (although you don't get rep for it) and it will help other people with similar issues to find the best solution. – trent Oct 01 '21 at 16:54

2 Answers2

2

Given the current API of nalgebra (v0.27.1) there isn't much that you can do, except:

  • life with the shorter life-time of StorageMut::as_mut_slice
  • make a feature request for such a function at nalgebra (which seems you already did)
  • employ your own unsafe code to make StorageMut::ptr_mut into a &'a mut

You could go with the third option until nalgebra gets update and implement something like this in your own code:

use nalgebra::base::dimension::Dim;
use nalgebra::base::storage::Storage;
use nalgebra::base::storage::StorageMut;

fn into_slice<'a>(vec: DVectorSliceMut<'a, f64>) -> &'a mut [f64] {
    let mut inner = vec.data;
    // from nalgebra
    // https://docs.rs/nalgebra/0.27.1/src/nalgebra/base/matrix_slice.rs.html#190
    let (nrows, ncols) = inner.shape();
    if nrows.value() != 0 && ncols.value() != 0 {
        let sz = inner.linear_index(nrows.value() - 1, ncols.value() - 1);
        unsafe { core::slice::from_raw_parts_mut(inner.ptr_mut(), sz + 1) }
    } else {
        unsafe { core::slice::from_raw_parts_mut(inner.ptr_mut(), 0) }
    }
}
Cryptjar
  • 1,079
  • 8
  • 13
0

Methods into_slice and into_slice_mut which return the original slice have been respectively added to the SliceStorage and SliceStorageMut traits as of nalgebra v0.28.0.

Wil
  • 115
  • 6