xtensor-stack / xtensor

C++ tensors with broadcasting and lazy computing
BSD 3-Clause "New" or "Revised" License
3.33k stars 398 forks source link

Incomplete indexings append zeros #27

Closed anntzer closed 7 years ago

anntzer commented 7 years ago

I believe that "incomplete indexings" (e.g. indexing a 3d array/tensor with 2 indices) add as many zeros as needed to complete the multi-index. At least in the case of tensors (where the dimensionality is known at compile time), perhaps it may make more sense to return a view in such a case? This would mimic numpy's behavior.

JohanMabille commented 7 years ago

You're right about the behavior of "incomplete indexing". The problem with returning view in the case of xtensor is that xtensor and xarray APIs would become heterogeneous. Thus it would be much more complicated to write generic code that can work with both xtensor and xarray.

anntzer commented 7 years ago

Can you make indexing always return a view, and then make xview<xtensor<T, ...>, ...> be implicitly convertible to T iff the correct number of dimensions has been specified, whereas xview<xarray<T>, ...> would always be implicitly convertible to T (and let the user shoot himself in the foot in that case if the wrong number of dimensions has been passed)?

(note: my c++-foo is actually pretty weak so I have no idea whether that's possible)

JohanMabille commented 7 years ago

Not sure it is possible because the number of slices of a view is static, as the number of arguments you provide to operator(), whereas the number of dimensions of xarray is dynamic.

Besides, even if this was possible, that would be a huge performance issue, since you would allocate a view (with dynamic allocation of strides and shape) for each element access.

Is that, I mean returning a view for incomplete index access, something you absolutely need ? I can think of a solution with a proxy interface (at least for xtensor) but that would take some time to implement.

anntzer commented 7 years ago

I was hoping that the allocation of a view would be optimized away by the compiler. Basically something like double x = arr(1); would be understood as double x = double(make_xview(arr, 1)) = arr(1, 0, ...).

Given that I didn't know of the existence of xtensor a month ago it's difficult to claim that there's any feature I "absolutely" need.

JohanMabille commented 7 years ago

Except if you make xview<xtensor<T>, ...> always implicitly convertible to T, you'll have to check at runtime that the number of dimensions is correct in the conversion operator. Thus you'll have to allocate the shape and stride and the compiler won't optimize the call to the access operator.

So the solution would be to make xview always implicitly convertible to T. But that would be very confusing and would lead to vicious bugs (the user would be closer to blowing his leg than shooting in his foot:)). Implicit conversion must be reserved for classes that have the same semantic (a proxy reference on T and T for instance).

For me this kind of behavior must be explicit, either through dedicated functions or a through a specific class.

anntzer commented 7 years ago

I think you meant making xview<xarray<T>, ...> (not xtensor, for which everything is known at compile time) always implicitly convertible to T?

JohanMabille commented 7 years ago

Yes, sorry for the mistake.

JohanMabille commented 7 years ago

In order to keep consistency between xtensor and xarray we won't implement this.