%PDF- %PDF-
Direktori : /lib/python3/dist-packages/pythran/pythonic/numpy/ndarray/ |
Current File : //lib/python3/dist-packages/pythran/pythonic/numpy/ndarray/reshape.hpp |
#ifndef PYTHONIC_NUMPY_NDARRAY_RESHAPE_HPP #define PYTHONIC_NUMPY_NDARRAY_RESHAPE_HPP #include "pythonic/include/numpy/ndarray/reshape.hpp" #include "pythonic/utils/functor.hpp" #include "pythonic/utils/numpy_conversion.hpp" #include "pythonic/types/ndarray.hpp" #include "pythonic/builtins/ValueError.hpp" PYTHONIC_NS_BEGIN namespace numpy { namespace ndarray { namespace misc { template <class P, size_t... Is> void set(P &p, long i, long v, utils::index_sequence<Is...>) { (void)std::initializer_list<bool>{ (i == Is && (sutils::assign(std::get<Is>(p), v), true))...}; } } template <class T, class pS, class NpS> typename std::enable_if<!std::is_integral<NpS>::value, types::ndarray<T, NpS>>::type reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape) { long where = sutils::sfind( new_shape, -1, std::integral_constant<size_t, std::tuple_size<NpS>::value>(), [](long a, long b) { return a <= b; }); long next = sutils::sfind(new_shape, -1, where, [](long a, long b) { return a <= b; }); if (next >= 0) { throw pythonic::types::ValueError( "Reshape: can only specify one unknown dimension"); } if (where >= 0) { auto auto_shape = new_shape; misc::set(auto_shape, where, expr.flat_size() / -sutils::sprod(new_shape), utils::make_index_sequence<std::tuple_size<NpS>::value>()); return expr.reshape(auto_shape); } else { auto nshape = sutils::sprod(new_shape); auto n = expr.flat_size(); if (n < nshape) { types::ndarray<T, NpS> out(new_shape, builtins::None); auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin()); for (long i = 1; i < nshape / n; ++i) iter = std::copy(out.fbegin(), out.fbegin() + n, iter); std::copy(out.fbegin(), out.fbegin() + nshape % n, iter); return out; } else { return expr.reshape(new_shape); } } } template <class T, class pS, class NpS> typename std::enable_if<std::is_integral<NpS>::value, types::ndarray<T, types::pshape<long>>>::type reshape(types::ndarray<T, pS> const &expr, NpS const &new_shape) { auto n = expr.flat_size(); if (new_shape <= -1) { return expr.reshape(types::pshape<long>(n)); } if (n < new_shape) { types::ndarray<T, types::pshape<long>> out( types::pshape<long>{new_shape}, builtins::None); auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin()); for (long i = 1; i < new_shape / n; ++i) iter = std::copy(out.fbegin(), out.fbegin() + n, iter); std::copy(out.fbegin(), out.fbegin() + new_shape % n, iter); return out; } else { return expr.reshape(types::pshape<long>(new_shape)); } } template <class T, class pS, class S0, class S1, class... S> auto reshape(types::ndarray<T, pS> const &expr, S0 i0, S1 i1, S const &... indices) -> decltype(reshape(expr, types::pshape<S0, S1, S...>{i0, i1, indices...})) { return reshape(expr, types::pshape<S0, S1, S...>{i0, i1, indices...}); } NUMPY_EXPR_TO_NDARRAY0_IMPL(reshape); } } PYTHONIC_NS_END #endif