#ifndef PYTHONIC_NUMPY_STACK_HPP #define PYTHONIC_NUMPY_STACK_HPP #include "pythonic/builtins/len.hpp" #include "pythonic/builtins/ValueError.hpp" #include #include PYTHONIC_NS_BEGIN namespace numpy { template types::ndarray> stack(ArraySequence const &args, long axis) { if (builtins::len(args) == 0) throw pythonic::types::ValueError("need at least one array to stack"); auto shape = sutils::getshape(args[0]); constexpr long N = std::tuple_size::value; // The length of the shape array. auto values = sutils::array( shape); // You can't do shape[i] but you can do shape.array()[i] types::array new_shape; // A new array that's 1 element longer than shape. // Insert a "0" at the position indicated by axis. for (long i = 0; i < N + 1; i++) { if (i < axis) new_shape[i] = values[i]; if (i == axis) new_shape[i] = 1; if (i > axis) new_shape[i] = values[i - 1]; } // Create a new empty list. types::list>> bi(0); // Push the resized arrays into the list. for (auto &&arg : args) { bi.push_back(arg.reshape(new_shape)); } // Call concatenate on this list. return concatenate(bi, axis); } template types::ndarray::dtype, types::array::value + 1>> stack(std::tuple const &args, long axis, utils::index_sequence) { types::array< types::ndarray< typename details::stack_helper_t::dtype, types::array::value>>, sizeof...(Tys)> vargs{{std::get(args)...}}; return stack(vargs, axis); } template types::ndarray::dtype, types::array::value + 1>> stack(std::tuple const &args, long axis) { return stack(args, axis, utils::make_index_sequence()); } } PYTHONIC_NS_END #endif