#ifndef PYTHONIC_NUMPY_SELECT_HPP #define PYTHONIC_NUMPY_SELECT_HPP #include "pythonic/include/numpy/select.hpp" #include "pythonic/utils/functor.hpp" #include "pythonic/utils/int_.hpp" PYTHONIC_NS_BEGIN namespace numpy { namespace { // TODO It could certainly be represent as a numpy_***_expr as each // elements // is computed without information from neighbor. // template long _select(Ichoice ibegin, Ichoice iend, Iout obegin, Isel sbegin, Icond cbegin, long size, utils::int_<1>) { static_assert(std::is_same::value, ""); for (; ibegin != iend && size != 0; ++ibegin, ++obegin, ++sbegin, ++cbegin) { // If elements it not already selected && condition match, copy it! if (!*sbegin && *cbegin) { *obegin = *ibegin; *sbegin = true; size--; } } return size; } template long _select(Ichoice ibegin, Ichoice iend, Iout obegin, Isel sbegin, Icond cbegin, long size, utils::int_) { for (; ibegin != iend && size != 0; ++ibegin, ++obegin, ++sbegin, ++cbegin) size = _select((*ibegin).begin(), (*ibegin).end(), (*obegin).begin(), (*sbegin).begin(), (*cbegin).begin(), size, utils::int_()); return size; } } template types::ndarray> select(C const &condlist, L const &choicelist, typename L::dtype _default) { constexpr size_t N = L::value - 1; auto &&choicelist0_shape = sutils::getshape(choicelist[0]); types::ndarray> out( choicelist0_shape, _default); types::ndarray> selected( choicelist0_shape, false); long size = selected.flat_size(); for (long i = 0; i < condlist.size() && size != 0; i++) size = _select(choicelist[i].begin(), choicelist[i].end(), out.begin(), selected.begin(), condlist.begin(), size, utils::int_()); return out; } template types::ndarray> select_helper(C const &condlist, L const &choicelist, T _default) { types::ndarray> out(sutils::getshape(choicelist[0]), _default); for (long i = 0; i < out.flat_size(); ++i) for (long j = 0; j < (long)condlist.size(); ++j) if (condlist[j].buffer[i]) { out.buffer[i] = choicelist[j].buffer[i]; break; } return out; } template typename std::enable_if::value == std::tuple_size::value, types::ndarray>::type select(types::list> const &condlist, types::list> const &choicelist, T _default) { return select_helper(condlist, choicelist, _default); } template typename std::enable_if::value == std::tuple_size::value, types::ndarray>::type select(types::static_list, M> const &condlist, types::static_list, M> const &choicelist, T _default) { return select_helper(condlist, choicelist, _default); } template typename std::enable_if::value == std::tuple_size::value, types::ndarray>::type select(types::static_list, M> const &condlist, types::list> const &choicelist, T _default) { return select_helper(condlist, choicelist, _default); } template typename std::enable_if::value == std::tuple_size::value, types::ndarray>::type select(types::list> const &condlist, types::static_list, M> const &choicelist, T _default) { return select_helper(condlist, choicelist, _default); } } PYTHONIC_NS_END #endif