-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
map_axis with FnMut(ArrayViewMut1<'a, A>) #452
Comments
map_axis
with FnMut(ArrayViewMut1<'a, A>)
Normally, I would use the However, I can't seem to get it to work with the |
You gave me an idea! I'll work on it tomorrow and then I'll report on the results.
with all the necessary adjustments in the signature to produce a |
Something like this should do what you want: #[macro_use]
extern crate ndarray;
use ndarray::prelude::*;
/// function that modifies the one-dimensional array in place to return a
/// single value for each lane
fn do_something(mut lane: ArrayViewMut1<i32>) -> i32 {
lane += 1;
lane[0] * 2
}
fn main() {
let mut arr = array![[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]];
let mut out = Array::zeros(arr.view().remove_axis(Axis(1)).raw_dim());
println!("arr =\n{}", arr);
println!("out =\n{}", out);
println!("==================");
azip!(mut lane (arr.lanes_mut(Axis(1))), mut out in {
println!("lane = {}", lane);
*out = do_something(lane);
});
println!("==================");
println!("arr =\n{}", arr);
println!("out =\n{}", out);
} Output:
We could add a |
Thanks a lot for the solution @jturner314! In most cases you'd want to keep an untouched copy of the original data, but it's nicer to be able to choose - if you only care about the output you don't want to pay the memory cost of allocating a copy of the original data. |
You're welcome. Thanks for the explanation. I'm not sure about @bluss, but I wouldn't object to adding a |
I have been trying to implement /// Reduce the values along an axis into just one value, producing a new
/// array with one less dimension.
///
/// Elements are visited in arbitrary order.
///
/// Return the result as an `Array`.
///
/// **Panics** if `axis` is out of bounds.
pub fn map_axis_mut<'a, B, F>(&'a mut self, axis: Axis, mut mapping: F)
-> Array<B, D::Smaller>
where D: RemoveAxis,
F: FnMut(ArrayViewMut1<'a, A>) -> B,
A: 'a + Clone,
S: DataMut,
{
let view_len = self.len_of(axis);
let view_stride = self.strides.axis(axis);
// use the 0th subview as a map to each 1d array view extended from
// the 0th element.
self.subview_mut(axis, 0).mapv(|mut first_elt: A| {
unsafe {
mapping(ArrayViewMut::new_(&mut first_elt, Ix1(view_len), Ix1(view_stride)))
}
})
} that triggers the following error from the compiler:
I have thus tried to follow its suggestion: pub fn map_axis_mut<'a, B, F>(&'a mut self, axis: Axis, mut mapping: F)
-> Array<B, D::Smaller>
where D: RemoveAxis,
F: FnMut(ArrayViewMut1<'a, A>) -> B,
A: 'a + Clone,
S: DataMut,
{
let view_len = self.len_of(axis);
let view_stride = self.strides.axis(axis);
// use the 0th subview as a map to each 1d array view extended from
// the 0th element.
self.subview_mut(axis, 0).map(|mut first_elt: &mut A| {
unsafe {
mapping(ArrayViewMut::new_(first_elt, Ix1(view_len), Ix1(view_stride)))
}
})
} but error[E0631]: type mismatch in closure arguments
--> src/impl_methods.rs:1842:35
|
1842 | self.subview_mut(axis, 0).map(|mut first_elt: &mut A| {
| ^^^ ----------------------- found signature of `for<'r> fn(&'r mut A) -> _`
| |
| expected signature of `fn(&A) -> _` Any idea on how to get out of this pinch? If you want I can polish your |
In the first example, the compiler is complaining about mutably borrowing It's possible to make the compiler happy in this case by changing the self.subview_mut(axis, 0).mapv(|mut first_elt: A| {
mapping(ArrayViewMut::new_(&mut first_elt, Ix1(view_len), Ix1(view_stride))) Here, In the second example, yeah the issue is that What I would suggest is to first add a method |
#460 got merged, so I can close this. |
Currently
map_axis
accepts only a mapping taking as argument a 1-dimensionalArrayView
(https://docs.rs/ndarray/0.11.2/ndarray/struct.ArrayBase.html#method.map_axis).What if I wanted to use a function that takes an
ArrayViewMut1
as argument?Is there another way to achieve the effect of
map_axis
using other iterators/Zip/etc.?I have tried to reason around that but I have not yet been able to come up with a solution...
The use-case I have in mind is a reducer that takes a lane in the array as argument and applies a function that modifies the one-dimensional array in place to return a single value for each lane.
The text was updated successfully, but these errors were encountered: