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.flat_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, types::array<long, std::tuple_size<pS>::value>> rot90(types::ndarray<T, pS> const &expr, int k) { auto constexpr N = std::tuple_size<pS>::value; if (k % 4 == 0) return copy(expr); types::array<long, N> shape = sutils::array(expr.shape()); if (k % 4 != 2) std::swap(shape[0], shape[1]); types::ndarray<T, types::array<long, N>> out(shape, __builtin__::None); if (k % 4 == 1) { for (int i = 0; i < shape[1]; ++i) for (int j = 0; j < shape[0]; ++j) out[shape[0] - 1 - j][i] = expr[i][j]; } else if (k % 4 == 2) { for (int i = 0; i < shape[1]; ++i) for (int j = 0; j < shape[0]; ++j) out[shape[0] - 1 - j][shape[1] - 1 - i] = expr[j][i]; } else { for (int i = 0; i < shape[1]; ++i) for (int j = 0; j < shape[0]; ++j) out[j][shape[1] - 1 - i] = expr[i][j]; } return out; }
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<T,N> roll(types::ndarray<T,N> const& expr, long shift, long axis) { auto&& expr_shape = expr.shape(); while(shift<0) shift+=expr_shape[axis]; types::ndarray<T,N> out(expr_shape, __builtin__::None); _roll(out.fbegin(), expr.fbegin(), shift, axis, expr_shape, utils::int_<N>()); return out; }
types::ndarray<T,2> tril(types::ndarray<T,2> const& expr, int k = 0) { auto&& expr_shape = expr.shape(); types::ndarray<T,2> out(expr_shape, __builtin__::None); for(int i=0; i<expr_shape[0]; ++i) { auto out_i = out[i]; auto expr_i = expr[i]; for(long j=0 ; j<expr_shape[1]; ++j) if( j - i <= k) out_i[j] = expr_i[j]; else out_i[j] = 0; } return out; }