| Server IP : 217.160.0.135 / Your IP : 216.73.217.25 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /lib/python3/dist-packages/pythran/pythonic/types/ |
Upload File : |
#ifndef PYTHONIC_TYPES_NUMPY_TEXPR_HPP
#define PYTHONIC_TYPES_NUMPY_TEXPR_HPP
#include "pythonic/include/types/numpy_texpr.hpp"
#include "pythonic/types/ndarray.hpp"
#include "pythonic/numpy/array.hpp"
#include "pythonic/numpy/transpose.hpp"
#include "pythonic/operator_/iadd.hpp"
#include "pythonic/operator_/iand.hpp"
#include "pythonic/operator_/idiv.hpp"
#include "pythonic/operator_/imul.hpp"
#include "pythonic/operator_/ior.hpp"
#include "pythonic/operator_/ixor.hpp"
#include "pythonic/operator_/isub.hpp"
PYTHONIC_NS_BEGIN
namespace types
{
template <class E>
numpy_texpr_2<E>::numpy_texpr_2()
{
}
template <class E>
numpy_texpr_2<E>::numpy_texpr_2(Arg const &arg)
: arg(arg)
{
}
template <class E>
typename numpy_texpr_2<E>::const_iterator numpy_texpr_2<E>::begin() const
{
return {*this, 0};
}
template <class E>
typename numpy_texpr_2<E>::const_iterator numpy_texpr_2<E>::end() const
{
return {*this, size()};
}
template <class E>
typename numpy_texpr_2<E>::iterator numpy_texpr_2<E>::begin()
{
return {*this, 0};
}
template <class E>
typename numpy_texpr_2<E>::iterator numpy_texpr_2<E>::end()
{
return {*this, size()};
}
template <class E>
auto numpy_texpr_2<E>::fast(long i) const
-> decltype(this->arg(fast_contiguous_slice(pythonic::builtins::None,
pythonic::builtins::None),
i))
{
return arg(
contiguous_slice(pythonic::builtins::None, pythonic::builtins::None),
i);
}
template <class E>
auto numpy_texpr_2<E>::fast(long i)
-> decltype(this->arg(fast_contiguous_slice(pythonic::builtins::None,
pythonic::builtins::None),
i))
{
return arg(
contiguous_slice(pythonic::builtins::None, pythonic::builtins::None),
i);
}
#ifdef USE_XSIMD
template <class E>
template <class vectorizer>
typename numpy_texpr_2<E>::simd_iterator
numpy_texpr_2<E>::vbegin(vectorizer) const
{
return {*this};
}
template <class E>
template <class vectorizer>
typename numpy_texpr_2<E>::simd_iterator
numpy_texpr_2<E>::vend(vectorizer) const
{
return {*this}; // ! vectorizable anyway
}
#endif
template <class E>
auto numpy_texpr_2<E>::operator[](long i) const -> decltype(this->fast(i))
{
if (i < 0)
i += size();
return fast(i);
}
template <class E>
auto numpy_texpr_2<E>::operator[](long i) -> decltype(this->fast(i))
{
if (i < 0)
i += size();
return fast(i);
}
template <class E>
template <class S>
auto numpy_texpr_2<E>::
operator[](S const &s0) const -> numpy_texpr<decltype(this->arg(
fast_contiguous_slice(pythonic::builtins::None, pythonic::builtins::None),
(s0.step, s0)))>
{
return {arg(fast_contiguous_slice(pythonic::builtins::None,
pythonic::builtins::None),
s0)};
}
template <class E>
template <class S>
auto numpy_texpr_2<E>::
operator[](S const &s0) -> numpy_texpr<decltype(this->arg(
fast_contiguous_slice(pythonic::builtins::None, pythonic::builtins::None),
(s0.step, s0)))>
{
return {arg(fast_contiguous_slice(pythonic::builtins::None,
pythonic::builtins::None),
s0)};
}
/* element filtering */
template <class E>
template <class F> // indexing through an array of boolean -- a mask
typename std::enable_if<
is_numexpr_arg<F>::value &&
std::is_same<bool, typename F::dtype>::value && F::value == 1 &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_texpr_2<E>, ndarray<long, pshape<long>>>>::type
numpy_texpr_2<E>::fast(F const &filter) const
{
long sz = filter.template shape<0>();
long *raw = (long *)malloc(sz * sizeof(long));
long n = 0;
for (long i = 0; i < sz; ++i)
if (filter.fast(i))
raw[n++] = i;
// realloc(raw, n * sizeof(long));
return this->fast(ndarray<long, pshape<long>>(raw, pshape<long>(n),
types::ownership::owned));
}
template <class E>
template <class F> // indexing through an array of boolean -- a mask
typename std::enable_if<
is_numexpr_arg<F>::value &&
std::is_same<bool, typename F::dtype>::value && F::value != 1 &&
!is_pod_array<F>::value,
numpy_vexpr<ndarray<typename numpy_texpr_2<E>::dtype, pshape<long>>,
ndarray<long, pshape<long>>>>::type
numpy_texpr_2<E>::fast(F const &filter) const
{
return numpy::functor::array{}(*this)
.flat()[ndarray<typename F::dtype, typename F::shape_t>(filter).flat()];
}
template <class E>
template <class F> // indexing through an array of boolean -- a mask
typename std::enable_if<
is_numexpr_arg<F>::value &&
std::is_same<bool, typename F::dtype>::value && F::value == 1 &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_texpr_2<E>, ndarray<long, pshape<long>>>>::type
numpy_texpr_2<E>::
operator[](F const &filter) const
{
return fast(filter);
}
template <class E>
template <class F> // indexing through an array of boolean -- a mask
typename std::enable_if<
is_numexpr_arg<F>::value &&
std::is_same<bool, typename F::dtype>::value && F::value != 1 &&
!is_pod_array<F>::value,
numpy_vexpr<ndarray<typename numpy_texpr_2<E>::dtype, pshape<long>>,
ndarray<long, pshape<long>>>>::type numpy_texpr_2<E>::
operator[](F const &filter) const
{
return fast(filter);
}
template <class E>
template <class F> // indexing through an array of indices -- a view
typename std::enable_if<
is_numexpr_arg<F>::value &&
!std::is_same<bool, typename F::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_texpr_2<E>, ndarray<long, pshape<long>>>>::type
numpy_texpr_2<E>::
operator[](F const &filter) const
{
static_assert(F::value == 1,
"advanced indexing only supporint with 1D index");
return {*this, filter};
}
template <class E>
template <class F> // indexing through an array of indices -- a view
typename std::enable_if<
is_numexpr_arg<F>::value &&
!std::is_same<bool, typename F::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_texpr_2<E>, ndarray<long, pshape<long>>>>::type
numpy_texpr_2<E>::fast(F const &filter) const
{
static_assert(F::value == 1,
"advanced indexing only supported with 1D index");
return {*this, filter};
}
template <class E>
template <class S0, class... S>
auto numpy_texpr_2<E>::operator()(S0 const &s0, S const &... s) const ->
typename std::enable_if<
!is_numexpr_arg<S0>::value,
decltype(this->_reverse_index(
std::tuple<S0 const &, S const &...>{s0, s...},
utils::make_reversed_index_sequence<1 + sizeof...(S)>()))>::type
{
return _reverse_index(
std::tuple<S0 const &, S const &...>{s0, s...},
utils::make_reversed_index_sequence<1 + sizeof...(S)>());
}
template <class E>
template <class S0, class... S>
auto numpy_texpr_2<E>::operator()(S0 const &s0, S const &... s) const ->
typename std::enable_if<is_numexpr_arg<S0>::value,
decltype(this->copy()(s0, s...))>::type
{
return copy()(s0, s...);
}
template <class E>
numpy_texpr_2<E>::operator bool() const
{
return (bool)arg;
}
template <class E>
long numpy_texpr_2<E>::flat_size() const
{
return arg.flat_size();
}
template <class E>
intptr_t numpy_texpr_2<E>::id() const
{
return arg.id();
}
template <class Arg>
template <class Expr>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator=(Expr const &expr)
{
return utils::broadcast_copy < numpy_texpr_2 &, Expr, value,
value - utils::dim_of<Expr>::value,
is_vectorizable &&
std::is_same<dtype, typename dtype_of<Expr>::type>::value &&
types::is_vectorizable<Expr>::value > (*this, expr);
}
template <class Arg>
template <class Expr>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::
operator=(numpy_texpr<Expr> const &expr)
{
arg = expr.arg;
return *this;
}
template <class Arg>
template <class Op, class Expr>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::update_(Expr const &expr)
{
using BExpr =
typename std::conditional<std::is_scalar<Expr>::value,
broadcast<Expr, dtype>, Expr const &>::type;
BExpr bexpr = expr;
utils::broadcast_update<
Op, numpy_texpr_2 &, BExpr, value,
value - (std::is_scalar<Expr>::value + utils::dim_of<Expr>::value),
is_vectorizable &&
types::is_vectorizable<typename std::remove_cv<
typename std::remove_reference<BExpr>::type>::type>::value &&
std::is_same<dtype, typename dtype_of<typename std::decay<
BExpr>::type>::type>::value>(*this, bexpr);
return *this;
}
template <class Arg>
template <class Expr>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator+=(Expr const &expr)
{
return update_<pythonic::operator_::functor::iadd>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator-=(E const &expr)
{
return update_<pythonic::operator_::functor::isub>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator*=(E const &expr)
{
return update_<pythonic::operator_::functor::imul>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator/=(E const &expr)
{
return update_<pythonic::operator_::functor::idiv>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator&=(E const &expr)
{
return update_<pythonic::operator_::functor::iand>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator|=(E const &expr)
{
return update_<pythonic::operator_::functor::ior>(expr);
}
template <class Arg>
template <class E>
numpy_texpr_2<Arg> &numpy_texpr_2<Arg>::operator^=(E const &expr)
{
return update_<pythonic::operator_::functor::ixor>(expr);
}
// only implemented for N = 2
template <class T, class S0, class S1>
numpy_texpr<ndarray<T, pshape<S0, S1>>>::numpy_texpr(
ndarray<T, pshape<S0, S1>> const &arg)
: numpy_texpr_2<ndarray<T, pshape<S0, S1>>>{arg}
{
}
template <class T>
numpy_texpr<ndarray<T, array<long, 2>>>::numpy_texpr(
ndarray<T, array<long, 2>> const &arg)
: numpy_texpr_2<ndarray<T, array<long, 2>>>{arg}
{
}
template <class E, class... S>
numpy_texpr<numpy_gexpr<E, S...>>::numpy_texpr(
numpy_gexpr<E, S...> const &arg)
: numpy_texpr_2<numpy_gexpr<E, S...>>{arg}
{
}
}
PYTHONIC_NS_END
#endif