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::ndarray<T,N> _transpose(types::ndarray<T,N> const & a, long const l[N]) { auto shape = a.shape; types::array<long, N> shp; for(unsigned long i=0; i<N; ++i) shp[i] = shape[l[i]]; types::ndarray<T,N> new_array(shp, __builtin__::None); types::array<long, N> new_strides; new_strides[N-1] = 1; std::transform(new_strides.rbegin(), new_strides.rend() -1, shp.rbegin(), new_strides.rbegin() + 1, std::multiplies<long>()); types::array<long, N> old_strides; old_strides[N-1] = 1; std::transform(old_strides.rbegin(), old_strides.rend() -1, shape.rbegin(), old_strides.rbegin() + 1, std::multiplies<long>()); auto iter = a.buffer, iter_end = a.buffer + a.size(); for(long i=0; iter!=iter_end; ++iter, ++i) { long offset = 0; for(unsigned long s=0; s<N; s++) offset += ((i/old_strides[l[s]]) % shape[l[s]])*new_strides[s]; new_array.buffer[offset] = *iter; } return new_array; }
types::ndarray<T, 1> flatten(types::ndarray<T,N> const& a) { long n = a.size(); T *buffer = new T[n]; std::copy(a.buffer, a.buffer + n, buffer); long shape[1] = {n}; return types::ndarray<T, 1>(buffer, shape); }
types::ndarray<T,2> diag(types::ndarray<T,1> const &a, long k=0) { long n = a.size() + std::abs(k); types::ndarray<T,2> out(types::make_tuple(n,n), 0); if(k>=0) for(long i=0,j =k ; i< n and j<n ;++i,++j) out[i][j] = a[i]; else for(long i=-k,j =0 ; i< n and j<n ;++i,++j) out[i][j] = a[j]; 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::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; }
T item(types::ndarray<T, N> const& expr, long i) { if(i<0) i += expr.size(); return *(expr.fbegin() + i); }
types::ndarray<typename types::numpy_type<dtype>::type,1> cumprod(types::ndarray<T,N> const& expr, dtype d = dtype()) { long count = expr.size(); types::ndarray<typename types::numpy_type<dtype>::type,1> cumprody(types::make_tuple(count), __builtin__::None); std::partial_sum(expr.buffer, expr.buffer + count, cumprody.buffer, std::multiplies<T>()); return cumprody; }