#ifndef PYTHONIC_NUMPY_TILE_HPP #define PYTHONIC_NUMPY_TILE_HPP #include "pythonic/include/numpy/tile.hpp" #include "pythonic/utils/functor.hpp" #include "pythonic/types/ndarray.hpp" PYTHONIC_NS_BEGIN namespace numpy { namespace { template void _tile(I begin, I end, O &out, long rep, utils::int_<1>) { for (long i = 0; i < rep; ++i) out = std::copy(begin, end, out); } template void _tile(I begin, I end, O &out, long rep, utils::int_) { for (; begin != end; ++begin) _tile((*begin).begin(), (*begin).end(), out, rep, utils::int_()); } } template types::ndarray> tile(E const &expr, long reps) { size_t n = expr.flat_size(); types::ndarray> out( types::array{{long(n * reps)}}, builtins::None); auto out_iter = out.fbegin(); _tile(expr.begin(), expr.end(), out_iter, 1, utils::int_()); for (long i = 1; i < reps; ++i) out_iter = std::copy(out.fbegin(), out.fbegin() + n, out_iter); return out; } template types::array tile_init_shape(R const &reps, S const &expr_shape, utils::index_sequence) { constexpr size_t M = S::value; return { {(reps[Is] * ((Is < Shift) ? 1 : expr_shape.template shape < (Is < M) ? Is : 0 > ()))...}}; } template types::ndarray> tile(E const &expr, types::array const &reps) { size_t n = expr.flat_size(); types::array shape = tile_init_shape( reps, expr, utils::make_index_sequence()); long last_rep = (E::value == N) ? std::get(reps) : 1; types::ndarray> out( shape, builtins::None); auto out_iter = out.fbegin(); _tile(expr.begin(), expr.end(), out_iter, last_rep, utils::int_()); size_t nreps = out.flat_size() / (n * last_rep); for (size_t i = 1; i < nreps; ++i) out_iter = std::copy(out.fbegin(), out.fbegin() + n, out_iter); return out; } } PYTHONIC_NS_END #endif