10#ifndef XTENSOR_TENSOR_HPP 
   11#define XTENSOR_TENSOR_HPP 
   19#include "../containers/xbuffer_adaptor.hpp" 
   20#include "../containers/xcontainer.hpp" 
   21#include "../core/xsemantic.hpp" 
   32        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
   35        template <
class EC, std::
size_t N, layout_type L>
 
   41        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
   45    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
   48        using storage_type = EC;
 
   49        using reference = inner_reference_t<storage_type>;
 
   50        using const_reference = 
typename storage_type::const_reference;
 
   51        using size_type = 
typename storage_type::size_type;
 
   52        using shape_type = std::array<typename storage_type::size_type, N>;
 
   53        using strides_type = get_strides_t<shape_type>;
 
   54        using backstrides_type = get_strides_t<shape_type>;
 
   55        using inner_shape_type = shape_type;
 
   56        using inner_strides_type = strides_type;
 
   57        using inner_backstrides_type = backstrides_type;
 
 
   62    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
   82    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
   84                              public xcontainer_semantic<xtensor_container<EC, N, L, Tag>>,
 
   85                              public extension::xtensor_container_base_t<EC, N, L, Tag>
 
   90        using base_type = xstrided_container<self_type>;
 
   91        using semantic_base = xcontainer_semantic<self_type>;
 
   92        using extension_base = extension::xtensor_container_base_t<EC, N, L, Tag>;
 
   93        using storage_type = 
typename base_type::storage_type;
 
   94        using allocator_type = 
typename base_type::allocator_type;
 
   95        using value_type = 
typename base_type::value_type;
 
   96        using reference = 
typename base_type::reference;
 
   97        using const_reference = 
typename base_type::const_reference;
 
   98        using pointer = 
typename base_type::pointer;
 
   99        using const_pointer = 
typename base_type::const_pointer;
 
  100        using shape_type = 
typename base_type::shape_type;
 
  101        using inner_shape_type = 
typename base_type::inner_shape_type;
 
  102        using strides_type = 
typename base_type::strides_type;
 
  103        using backstrides_type = 
typename base_type::backstrides_type;
 
  104        using inner_backstrides_type = 
typename base_type::inner_backstrides_type;
 
  105        using inner_strides_type = 
typename base_type::inner_strides_type;
 
  106        using temporary_type = 
typename semantic_base::temporary_type;
 
  107        using expression_tag = Tag;
 
  108        static constexpr std::size_t rank = N;
 
  118        template <
class S = shape_type>
 
  142        storage_type m_storage;
 
  144        storage_type& storage_impl() noexcept;
 
  145        const storage_type& storage_impl() const noexcept;
 
 
  156        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  159        template <
class EC, std::
size_t N, layout_type L>
 
  165        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  169    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  172        using storage_type = std::remove_reference_t<EC>;
 
  173        using reference = inner_reference_t<storage_type>;
 
  174        using const_reference = 
typename storage_type::const_reference;
 
  175        using size_type = 
typename storage_type::size_type;
 
  176        using shape_type = std::array<typename storage_type::size_type, N>;
 
  177        using strides_type = get_strides_t<shape_type>;
 
  178        using backstrides_type = get_strides_t<shape_type>;
 
  179        using inner_shape_type = shape_type;
 
  180        using inner_strides_type = strides_type;
 
  181        using inner_backstrides_type = backstrides_type;
 
 
  186    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  208    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  210                            public xcontainer_semantic<xtensor_adaptor<EC, N, L, Tag>>,
 
  211                            public extension::xtensor_adaptor_base_t<EC, N, L, Tag>
 
  215        using container_closure_type = EC;
 
  218        using base_type = xstrided_container<self_type>;
 
  219        using semantic_base = xcontainer_semantic<self_type>;
 
  220        using extension_base = extension::xtensor_adaptor_base_t<EC, N, L, Tag>;
 
  221        using storage_type = 
typename base_type::storage_type;
 
  222        using allocator_type = 
typename base_type::allocator_type;
 
  223        using shape_type = 
typename base_type::shape_type;
 
  224        using strides_type = 
typename base_type::strides_type;
 
  225        using backstrides_type = 
typename base_type::backstrides_type;
 
  226        using temporary_type = 
typename semantic_base::temporary_type;
 
  227        using expression_tag = Tag;
 
  228        static constexpr std::size_t rank = N;
 
  251        template <
class P, 
class S>
 
  252        void reset_buffer(P&& pointer, S&& 
size);
 
  256        container_closure_type m_storage;
 
  258        storage_type& storage_impl() noexcept;
 
  259        const storage_type& storage_impl() const noexcept;
 
 
  268    template <class EC, std::
size_t N, 
layout_type L, class Tag>
 
  273        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  276        template <
class EC, std::
size_t N, layout_type L>
 
  282        template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  286    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  289        using storage_type = std::remove_reference_t<EC>;
 
  290        using reference = inner_reference_t<storage_type>;
 
  291        using const_reference = 
typename storage_type::const_reference;
 
  292        using size_type = 
typename storage_type::size_type;
 
  293        using shape_type = std::array<typename storage_type::size_type, N>;
 
  294        using strides_type = get_strides_t<shape_type>;
 
  295        using backstrides_type = get_strides_t<shape_type>;
 
  296        using inner_shape_type = shape_type;
 
  297        using inner_strides_type = strides_type;
 
  298        using inner_backstrides_type = backstrides_type;
 
 
  303    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  325    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  326    class xtensor_view : 
public xstrided_container<xtensor_view<EC, N, L, Tag>>,
 
  327                         public xview_semantic<xtensor_view<EC, N, L, Tag>>,
 
  328                         public extension::xtensor_view_base_t<EC, N, L, Tag>
 
  332        using container_closure_type = EC;
 
  335        using base_type = xstrided_container<self_type>;
 
  336        using semantic_base = xview_semantic<self_type>;
 
  337        using extension_base = extension::xtensor_adaptor_base_t<EC, N, L, Tag>;
 
  338        using storage_type = 
typename base_type::storage_type;
 
  339        using allocator_type = 
typename base_type::allocator_type;
 
  340        using shape_type = 
typename base_type::shape_type;
 
  341        using strides_type = 
typename base_type::strides_type;
 
  342        using backstrides_type = 
typename base_type::backstrides_type;
 
  343        using temporary_type = 
typename semantic_base::temporary_type;
 
  344        using expression_tag = Tag;
 
  367        disable_xexpression<E, self_type>& operator=(
const E& e);
 
  371        container_closure_type m_storage;
 
  373        storage_type& storage_impl() noexcept;
 
  374        const storage_type& storage_impl() const noexcept;
 
  376        void assign_temporary_impl(temporary_type&& tmp);
 
  379        friend class xview_semantic<
xtensor_view<EC, N, L, Tag>>;
 
 
  385        struct tensor_view_simd_helper
 
  387            using valid_return_type = detail::has_simd_interface_impl<V, typename V::value_type>;
 
  388            using valid_reference = std::is_lvalue_reference<typename V::reference>;
 
  389            static constexpr bool value = valid_return_type::value && valid_reference::value;
 
  390            using type = std::integral_constant<bool, value>;
 
  398    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  400        : detail::tensor_view_simd_helper<xtensor_view<EC, N, L, Tag>>::type
 
 
  415    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  418        , m_storage(N == 0 ? 1 : 0, value_type())
 
 
  425    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  431        L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->
template begin<tmp>(), t);
 
 
  440    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  454    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  456        const shape_type& shape,
 
  457        const_reference value,
 
  463        std::fill(m_storage.begin(), m_storage.end(), value);
 
 
  471    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  485    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  487        const shape_type& shape,
 
  489        const_reference value
 
  494        std::fill(m_storage.begin(), m_storage.end(), value);
 
 
  504    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  507        inner_shape_type&& shape,
 
  510        : base_type(std::move(shape), std::move(
strides))
 
  511        , m_storage(std::move(
storage))
 
 
  515    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  519            xtl::forward_sequence<inner_shape_type, decltype(rhs.shape())>(rhs.shape()),
 
  520            xtl::forward_sequence<inner_strides_type, decltype(rhs.
strides())>(rhs.
strides()),
 
  521            xtl::forward_sequence<inner_backstrides_type, decltype(rhs.backstrides())>(rhs.backstrides()),
 
  522            std::move(rhs.layout())
 
  524        , m_storage(std::move(rhs.storage()))
 
  528    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  530    inline xtensor_container<EC, N, L, Tag>&
 
  531    xtensor_container<EC, N, L, Tag>::operator=(xarray_container<EC, L, SC, Tag>&& rhs)
 
  533        XTENSOR_ASSERT_MSG(N == rhs.dimension(), 
"Cannot change dimension of xtensor.");
 
  534        std::copy(rhs.shape().begin(), rhs.shape().end(), this->shape_impl().begin());
 
  535        std::copy(rhs.strides().cbegin(), rhs.strides().cend(), this->strides_impl().begin());
 
  536        std::copy(rhs.backstrides().cbegin(), rhs.backstrides().cend(), this->backstrides_impl().begin());
 
  537        this->mutable_layout() = std::move(rhs.layout());
 
  538        m_storage = std::move(std::move(rhs.storage()));
 
  542    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  546        XTENSOR_ASSERT_MSG(s.size() == N, 
"Cannot change dimension of xtensor.");
 
  547        shape_type shape = xtl::forward_sequence<shape_type, S>(s);
 
  548        return self_type(shape);
 
  560    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  570            detail::resize_data_container(m_storage, std::size_t(1));
 
  572        semantic_base::assign(e);
 
 
  578    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  580    inline auto xtensor_container<EC, N, L, Tag>::operator=(
const xexpression<E>& e) -> self_type&
 
  582        return semantic_base::operator=(e);
 
 
  587    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  588    inline auto xtensor_container<EC, N, L, Tag>::storage_impl() noexcept -> storage_type&
 
  593    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  594    inline auto xtensor_container<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
 
  611    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  614        , m_storage(std::move(
storage))
 
 
  622    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  636    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  640        , m_storage(std::forward<D>(
storage))
 
 
  652    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  656        const shape_type& shape,
 
  660        , m_storage(std::forward<D>(
storage))
 
 
  667    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  668    inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(
const xtensor_adaptor& rhs) -> self_type&
 
  670        base_type::operator=(rhs);
 
  671        m_storage = rhs.m_storage;
 
  675    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  676    inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(xtensor_adaptor&& rhs) -> self_type&
 
  678        base_type::operator=(std::move(rhs));
 
  679        m_storage = rhs.m_storage;
 
  683    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  684    inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(
temporary_type&& rhs) -> self_type&
 
  686        base_type::shape_impl() = std::move(
const_cast<shape_type&
>(rhs.shape()));
 
  687        base_type::strides_impl() = std::move(
const_cast<strides_type&
>(rhs.strides()));
 
  688        base_type::backstrides_impl() = std::move(
const_cast<backstrides_type&
>(rhs.backstrides()));
 
  689        m_storage = std::move(rhs.storage());
 
  700    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  702    inline auto xtensor_adaptor<EC, N, L, Tag>::operator=(
const xexpression<E>& e) -> self_type&
 
  704        return semantic_base::operator=(e);
 
 
  709    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  710    inline auto xtensor_adaptor<EC, N, L, Tag>::storage_impl() noexcept -> storage_type&
 
  715    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  716    inline auto xtensor_adaptor<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
 
  721    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  722    template <
class P, 
class S>
 
  723    inline void xtensor_adaptor<EC, N, L, Tag>::reset_buffer(P&& pointer, S&& size)
 
  725        return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
 
  740    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  743        , m_storage(std::move(
storage))
 
 
  751    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  765    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  769        , m_storage(std::forward<D>(
storage))
 
 
  781    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  785        , m_storage(std::forward<D>(
storage))
 
 
  792    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  793    inline auto xtensor_view<EC, N, L, Tag>::operator=(
const xtensor_view& rhs) -> self_type&
 
  795        base_type::operator=(rhs);
 
  796        m_storage = rhs.m_storage;
 
  800    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  801    inline auto xtensor_view<EC, N, L, Tag>::operator=(xtensor_view&& rhs) -> self_type&
 
  803        base_type::operator=(std::move(rhs));
 
  804        m_storage = rhs.m_storage;
 
  815    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  817    inline auto xtensor_view<EC, N, L, Tag>::operator=(
const xexpression<E>& e) -> self_type&
 
  819        return semantic_base::operator=(e);
 
 
  824    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  826    inline auto xtensor_view<EC, N, L, Tag>::operator=(
const E& e) -> disable_xexpression<E, self_type>&
 
  828        std::fill(m_storage.begin(), m_storage.end(), e);
 
  832    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  833    inline auto xtensor_view<EC, N, L, Tag>::storage_impl() noexcept -> storage_type&
 
  838    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  839    inline auto xtensor_view<EC, N, L, Tag>::storage_impl() const noexcept -> const storage_type&
 
  844    template <
class EC, std::
size_t N, layout_type L, 
class Tag>
 
  845    inline void xtensor_view<EC, N, L, Tag>::assign_temporary_impl(
temporary_type&& tmp)
 
  847        std::copy(tmp.cbegin(), tmp.cend(), m_storage.begin());
 
  861        using size_type = 
typename return_type::size_type;
 
  865            return return_type::from_shape({size_type(0), size_type(0)});
 
  868        return_type out = return_type::from_shape({idx.size(), idx[0].size()});
 
  870        for (size_type i = 0; i < out.shape()[0]; ++i)
 
  872            for (size_type j = 0; j < out.shape()[1]; ++j)
 
  874                out(i, j) = idx[i][j];
 
 
  899        return_type out = return_type::from_shape({n});
 
  900        auto iter = out.begin();
 
  904            [&iter](
const auto& t)
 
  906                iter = std::copy(t.cbegin(), t.cend(), iter);
 
 
  913    struct ravel_vector_tag;
 
  914    struct ravel_tensor_tag;
 
  918        template <
class C, 
class Tag>
 
  919        struct ravel_return_type;
 
  922        struct ravel_return_type<C, ravel_vector_tag>
 
  924            using index_type = 
typename C::value_type;
 
  925            using value_type = 
typename index_type::value_type;
 
  926            using type = std::vector<value_type>;
 
  929            static std::vector<value_type> init(T n)
 
  931                return std::vector<value_type>(n);
 
  936        struct ravel_return_type<C, ravel_tensor_tag>
 
  938            using index_type = 
typename C::value_type;
 
  939            using value_type = 
typename index_type::value_type;
 
  945                return xtensor<value_type, 1>::from_shape({n});
 
  950    template <
class C, 
class Tag>
 
  951    using ravel_return_type_t = 
typename detail::ravel_return_type<C, Tag>::type;
 
  963    template <
class Tag = ravel_tensor_tag, 
class C, 
class S>
 
  964    ravel_return_type_t<C, Tag>
 
  967        using return_type = 
typename detail::ravel_return_type<C, Tag>::type;
 
  968        using value_type = 
typename detail::ravel_return_type<C, Tag>::value_type;
 
  969        using strides_type = get_strides_t<S>;
 
  970        strides_type 
strides = xtl::make_sequence<strides_type>(shape.size(), 0);
 
  972        return_type out = detail::ravel_return_type<C, Tag>::init(idx.size());
 
  973        auto out_iter = out.begin();
 
  974        auto idx_iter = idx.begin();
 
  975        for (; out_iter != out.end(); ++out_iter, ++idx_iter)
 
  977            *out_iter = element_offset<value_type>(
strides, (*idx_iter).cbegin(), (*idx_iter).cend());
 
 
Dense multidimensional container with tensor semantic.
Base class for dense multidimensional containers.
storage_type & storage() noexcept
Returns a reference to the buffer containing the elements of the container.
size_type size() const noexcept
Returns the number of element in the container.
constexpr size_type dimension() const noexcept
Returns the number of dimensions of the container.
constexpr const inner_strides_type & strides() const noexcept
Returns the strides of the container.
constexpr const inner_shape_type & shape() const noexcept
Returns the shape of the container.
auto begin() noexcept -> select_iterator< L >
Base class for xexpressions.
derived_type & derived_cast() &noexcept
Returns a reference to the actual derived type of the xexpression.
void resize(S &&shape, bool force=false)
Dense multidimensional container adaptor with tensor semantics and fixed dimension.
xtensor_adaptor(D &&storage, const shape_type &shape, layout_type l=L)
Constructs an xtensor_adaptor of the given stl-like container, with the specified shape and layout_ty...
xtensor_adaptor(const storage_type &storage)
Constructs an xtensor_adaptor of the given stl-like container.
xtensor_adaptor(D &&storage, const shape_type &shape, const strides_type &strides)
Constructs an xtensor_adaptor of the given stl-like container, with the specified shape and strides.
xtensor_adaptor(storage_type &&storage)
Constructs an xtensor_adaptor of the given stl-like container.
Dense multidimensional container with tensor semantic and fixed dimension.
xtensor_container(const shape_type &shape, const strides_type &strides)
Allocates an uninitialized xtensor_container with the specified shape and strides.
xtensor_container(const shape_type &shape, const_reference value, layout_type l=L)
Allocates an xtensor_container with the specified shape and layout_type.
xtensor_container(nested_initializer_list_t< value_type, N > t)
Allocates an xtensor_container with nested initializer lists.
xtensor_container(const xexpression< E > &e)
The extended copy constructor.
xtensor_container()
Allocates an uninitialized xtensor_container that holds 0 elements.
xtensor_container(const shape_type &shape, const strides_type &strides, const_reference value)
Allocates an uninitialized xtensor_container with the specified shape and strides.
xtensor_container(storage_type &&storage, inner_shape_type &&shape, inner_strides_type &&strides)
Allocates an xtensor_container by moving specified data, shape and strides.
xtensor_container(const shape_type &shape, layout_type l=L)
Allocates an uninitialized xtensor_container with the specified shape and layout_type.
Dense multidimensional container adaptor with view semantics and fixed dimension.
xtensor_view(storage_type &&storage)
Constructs an xtensor_view of the given stl-like container.
xtensor_view(D &&storage, const shape_type &shape, layout_type l=L)
Constructs an xtensor_view of the given stl-like container, with the specified shape and layout_type.
xtensor_view(const storage_type &storage)
Constructs an xtensor_view of the given stl-like container.
xtensor_view(D &&storage, const shape_type &shape, const strides_type &strides)
Constructs an xtensor_view of the given stl-like container, with the specified shape and strides.
std::size_t compute_strides(const shape_type &shape, layout_type l, strides_type &strides)
Compute the strides given the shape and the layout of an array.
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
standard mathematical functions for xexpressions
auto flatten_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.
xtensor_container< uvector< T, A >, N, L > xtensor
Alias template on xtensor_container with default parameters for data container type.
ravel_return_type_t< C, Tag > ravel_indices(const C &idx, const S &shape, layout_type l=layout_type::row_major)
Converts std::vector<index_type> (returned e.g.
auto from_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.