types::ndarray<T,N> roll(types::ndarray<T,N> const& expr, long shift) { while(shift<0) shift+=expr.flat_size(); shift %=expr.flat_size(); types::ndarray<T,N> out(expr.shape(), __builtin__::None); std::copy(expr.fbegin(), expr.fend() - shift, std::copy(expr.fend() - shift, expr.fend(), out.fbegin())); return out; }
types::ndarray<decltype(std::declval<T0>() + std::declval<T1>()), 2> outer(types::ndarray<T0, N0> const& a, types::ndarray<T1, N1> const& b) { types::ndarray<decltype(std::declval<T0>() + std::declval<T1>()), 2> out(types::array<long, 2>{{a.flat_size(), b.flat_size()}}, __builtin__::None); auto iter = out.fbegin(); for(auto iter_a = a.fbegin(), end_a = a.fend(); iter_a != end_a; ++iter_a) { auto val_a = *iter_a; iter = std::transform(b.fbegin(), b.fend(), iter, [=](T1 val) { return val_a * val; }); } return out; }
types::ndarray< typename std::remove_cv< typename std::remove_reference< decltype( std::declval<T>() + std::declval<typename utils::nested_container_value_type<F>::type>()) >::type >::type, 1> append(types::ndarray<T,N> const& nto, F const& data) { typename types::numpy_expr_to_ndarray<F>::type ndata(data); long nsize = nto.size() + ndata.size(); types::ndarray< typename std::remove_cv< typename std::remove_reference< decltype( std::declval<T>() + std::declval<typename utils::nested_container_value_type<F>::type>()) >::type >::type, 1> out(types::make_tuple(nsize), __builtin__::None); size_t i=0; auto out_back = std::copy(nto.fbegin(), nto.fend(), out.fbegin()); std::copy(ndata.fbegin(), ndata.fend(), out_back); return out; }
types::none_type place(types::ndarray<T, N> &expr, types::ndarray<Tp, Np> const &mask, F const &values) { auto first = expr.fend(); auto viter = values.begin(), vend = values.end(); auto miter = mask.fbegin(); for (auto iter = expr.fbegin(), end = expr.fend(); iter != end; ++iter, ++miter) { if (*miter) { if (first == expr.fend()) first = iter; if (viter != vend) { *iter = *viter; ++viter; } else *iter = *first; } } return __builtin__::None; }
types::ndarray<T, 1> repeat(types::ndarray<T, N> const &expr, int repeats) { types::ndarray<T, 1> out( types::array<long, 1>{{expr.flat_size() * repeats}}, __builtin__::None); auto out_iter = out.fbegin(); for (auto iter = expr.fbegin(), end = expr.fend(); iter != end; ++iter) for (int i = 0; i < repeats; ++i) *out_iter++ = *iter; return out; }
types::ndarray<T,1> resize(types::ndarray<T,N> const& expr, int new_shape) { types::ndarray<T,1> out(types::array<long, N> {{new_shape}}, __builtin__::None); auto n = expr.size(); if(n < new_shape) { auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin()); for(size_t 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); } else std::copy(expr.fbegin(), expr.fbegin() + new_shape, out.fbegin()); return out; }
types::ndarray<T,M> resize(types::ndarray<T,N> const& expr, types::array<long, M> const& new_shape) { auto where = std::find(new_shape.begin(), new_shape.end(), -1); if(where != new_shape.end()) { types::array<long, M> auto_shape(new_shape); auto_shape[where - new_shape.begin()] = expr.size() / std::accumulate(new_shape.begin(), new_shape.end(), -1L, std::multiplies<long>()); return resize(expr, auto_shape); } types::ndarray<T,M> out(new_shape, __builtin__::None); auto nshape = out.size(); auto n = expr.size(); if(n < nshape) { auto iter = std::copy(expr.fbegin(), expr.fend(), out.fbegin()); for(size_t i = 1; i < nshape / n; ++i) { iter = std::copy(out.fbegin(), out.fbegin() + n, iter); } std::copy(out.fbegin(), out.fbegin() + nshape % n, iter); } else std::copy(expr.fbegin(), expr.fbegin() + nshape, out.fbegin()); return out; }
types::none_type fill(types::ndarray<T, N> &e, F f) { std::fill(e.fbegin(), e.fend(), f); return __builtin__::None; }