%PDF- %PDF-
| Direktori : /proc/thread-self/root/lib/python3/dist-packages/pythran/pythonic/numpy/ndarray/ |
| Current File : //proc/thread-self/root/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