xtensor icon indicating copy to clipboard operation
xtensor copied to clipboard

`any()` and `all()` should support `axis` and `keep_dims`

Open DavisVaughan opened this issue 6 years ago • 6 comments

To match numpy, xt::any() and xt::all() should have an axis argument allowing for multiple axes (it should probably be called axes). Maybe it can be implemented with the reduction framework that already exists?

https://docs.scipy.org/doc/numpy/reference/generated/numpy.any.html https://docs.scipy.org/doc/numpy/reference/generated/numpy.all.html

The only trouble is making sure you can early exit with things like xt::any(). If you see any true values along the way, exit immediately for performance.

It actually doesn't look like numpy has optimized for the case I mention above, unless _wrapreduction() does something clever that I'm not aware of https://github.com/numpy/numpy/blob/v1.16.1/numpy/core/fromnumeric.py#L2164

DavisVaughan avatar Apr 30 '19 14:04 DavisVaughan

we should move any and all to the reducer framework.

wolfv avatar Jun 05 '19 15:06 wolfv

i agree!

DavisVaughan avatar Jun 05 '19 15:06 DavisVaughan

It's actually a "simple" fix - just need to pass a correct reducing lambda or struct to the make reducer macro.

btw. where was your issue with the cum* functions? I was looking for that :)

wolfv avatar Jun 05 '19 15:06 wolfv

ah yeah, except for the fast exit ...

wolfv avatar Jun 05 '19 15:06 wolfv

i believe its this one https://github.com/QuantStack/xtensor/issues/1334

linked them all from https://github.com/DavisVaughan/rray/issues/30

DavisVaughan avatar Jun 05 '19 15:06 DavisVaughan

I was able to get axis support for any / all pretty easily using the reduction macros:

using namespace xt;
XTENSOR_REDUCER_FUNCTION(va_any, xt::detail::logical_or, bool, true)
XTENSOR_REDUCER_FUNCTION(va_all, xt::detail::logical_and, bool, false)

To make use of the optimized implementation with no axes provided, I currently use:

#define ReducerAnyAll(Name, fun_name_axes, fun_name_no_axes)\
	template <typename GivenAxes, typename A>\
	auto operator()(GivenAxes&& axes, A&& a) const {\
		return fun_name_axes(std::forward<A>(a), std::forward<GivenAxes>(axes), std::tuple<xt::evaluation_strategy::lazy_type>());\
	}\
\
	template <typename A>\
	auto operator()(A&& a) const {\
		return xt::xtensor_fixed<bool, xshape<>>(fun_name_no_axes(std::forward<A>(a)));\
	}

struct All { ReducerAnyAll(All, va_all, xt::all) };
struct Any { ReducerAnyAll(Any, va_any, xt::any) };

It would be nice if the implementations were unified so this workaround can be dropped.

Ivorforce avatar Sep 19 '24 13:09 Ivorforce