Skip to content

Number of elements when slicing by axis #578

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

Closed
LukeMathWalker opened this issue Jan 5, 2019 · 3 comments
Closed

Number of elements when slicing by axis #578

LukeMathWalker opened this issue Jan 5, 2019 · 3 comments
Labels

Comments

@LukeMathWalker
Copy link
Member

LukeMathWalker commented Jan 5, 2019

I am trying to understand what is the correct way to understand when map_axis will be operating on empty arrays.

The minimal example that is giving me problems is the following:

use ndarray::{Array2, Axis};

let a: Array2 = array![[]];
let axis = Axis(0);

The array is empty, hence all slices (both wrt the first and the second axis) don't contain any element.
But if I ask for

a.len_of(axis)

I get 1 as answer because the shape of the array is [1, 0]. Should I combine the output len_of with the product of the other entries in the shape (excluding the one I am to slice the array)?

@LukeMathWalker LukeMathWalker changed the title Length of axis Number of elements when slicing by axis Jan 5, 2019
@jturner314
Copy link
Member

jturner314 commented Jan 6, 2019

Edit: My original answer was incorrect because I mixed up the semantics of map_axis and fold_axis.

For .map_axis(), to determine if the views will be empty or not, all you need to check is .len_of(the_axis). In the example you've provided, all the views have shape [1] if you call a.map_axis(Axis(0), mapping). (.map_axis() applies mapping to 1-D views along that axis, and that axis has length 1.) It just so happens that the other axis has length 0, so there aren't any shape [1] views for .map_axis() to apply mapping to.

Both of the following statements are true:

  • the shape of the views that a.map_axis(axis, mapping) applies mapping to is always [a.len_of(axis)]

  • if a.len_of(axis) != 0, then all views that a.map_axis(axis, mapping) applies mapping to are non-empty

Maybe I'm misunderstanding the question?

@LukeMathWalker
Copy link
Member Author

I actually think that the previous answer was correct for what I was asking 😛

if a.len_of(axis) != 0, then all views that a.map_axis(axis, mapping) applies mapping to are non-empty

But they are empty if at least one of other axes has length 0. So checking if the whole array is empty will basically tell me if there is any non-trivial reduction to be performed using mapping - am I misunderstanding how this works somehow?

@jturner314
Copy link
Member

Let's look at some examples:

Shape Mapping axis Axis length Shape of views Number of views
[2, 3] Axis(0) 2 [2] 3
[2, 3] Axis(1) 3 [3] 2
[0, 2] Axis(0) 0 [0] (once #579 is fixed) 2 (once #579 is fixed)
[0, 2] Axis(1) 2 [2] 0

if a.len_of(axis) != 0, then all views that a.map_axis(axis, mapping) applies mapping to are non-empty

But they are empty if at least one of other axes has length 0.

If one of the other axes has length 0, then there are 0 views for map_axis to apply mapping to. (This corresponds to the last row in the table above.) I suppose you could say all 0 views are empty, but I think it makes more sense to say that their shape corresponds to the axis length (which would mean they'd be non-empty), as shown in the table. Really, though, you could say anything about the views and have it be true for all of them, because there are zero of them.

So checking if the whole array is empty will basically tell me if there is any non-trivial reduction to be performed using mapping

That depends on how "non-trivial" is defined. If the whole array is empty, then there are two possibilities:

  1. The axis is zero-length. This currently panics (Support zero-length axis in .map_axis/_mut() #579), but let's consider the behavior once Support zero-length axis in .map_axis/_mut() #579 is fixed:

    • If any of the other axes are zero-length, there are zero views, so the reduction is trivial. (The shape of the result of map_axis is different from the shape of the input, but mapping is not called.)

    • If all the other axes are non-zero-length, mapping is called on at least one view of shape [0]. Since the views are empty, this could be considered trivial, but mapping could perform some non-trivial operation even for empty views. Additionally, the shape of the result of map_axis is different from the shape of the input.

  2. The axis is not zero-length, then at least one of the other axes must be zero-length, which means there are zero views and the reduction is trivial. (The shape of the result of map_axis may be different from the shape of the input, but mapping is not called.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants