View of view in ndarray

Hi!

I have a wrapper class around some ndarray data with some convenience functions for getting certain slices, such as

struct DataClass {
    points: Array2<f64>
}

impl DataClass {
   fn x(&self) -> ArrayView1<f64> {
       self.points.slice(s![.., 0])
   }
   fn y(&self) -> ArrayView1<f64> {
       self.points.slice(s![.., 1])
   }
}

My issue is that these slices are not so convenient to use if I take further views, such as:

let d = DataClass{ ... };
// cannot define use segment_x later since d.x() is temporary and goes out of scope...
// let segment_x = d.x().slice(s![0..5]);

// instead, I have to write it like this:
let xs = d.x();
let segment_x = xs.slice(s![0..5]);

It would be nice if I could write a function which accepts slice information for a subview, but I do not know how to do it since s! macro inputs cannot be combined. It would look something like:

impl DataClass {
   fn x(&self, slice_info) -> ArrayView1<f64> {
       self.points.slice(s![slice_info, 0])
   }
}
// to be used as data_class.x(s![0..5]);

Is it possible to somehow have this or a similar ease of use, or is the first version the rust way to go? I also don't understand why a view of a view links to the first view, and not directly to the original array, in which case there wouldn't be a lifetime issue.

Thanks for any help!

You could define new declarative macros that wrap s!

#[macro_export]
macro_rules! x {
    (  $self:ident, $slice_range:expr  ) => {
        {
            $self.points.slice(s![$slice_range, 0])
        }
    };
}

#[macro_export]
macro_rules! y {
    (  $self:ident, $slice_range:expr  ) => {
        {
            $self.points.slice(s![$slice_range, 1])
        }
    };
}

// no need to impl x and y for DataClass
// do stuff with
// x!(data_class, 0..5)
// y!(data_class, 0..5)
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.