| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676 |
- /***************************************************************************
- * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
- * Copyright (c) QuantStack *
- * *
- * Distributed under the terms of the BSD 3-Clause License. *
- * *
- * The full license is in the file LICENSE, distributed with this software. *
- ****************************************************************************/
- #ifndef XTENSOR_XMASKED_VIEW_HPP
- #define XTENSOR_XMASKED_VIEW_HPP
- #include "xaccessible.hpp"
- #include "xexpression.hpp"
- #include "xiterable.hpp"
- #include "xsemantic.hpp"
- #include "xshape.hpp"
- #include "xtensor_forward.hpp"
- #include "xtl/xmasked_value.hpp"
- #include "xutils.hpp"
- namespace xt
- {
- /****************************
- * xmasked_view declaration *
- *****************************/
- template <class CTD, class CTM>
- class xmasked_view;
- template <class D, bool is_const>
- class xmasked_view_stepper;
- template <class T>
- struct xcontainer_inner_types;
- template <class CTD, class CTM>
- struct xcontainer_inner_types<xmasked_view<CTD, CTM>>
- {
- using data_type = std::decay_t<CTD>;
- using mask_type = std::decay_t<CTM>;
- using base_value_type = typename data_type::value_type;
- using flag_type = typename mask_type::value_type;
- using val_reference = inner_reference_t<CTD>;
- using mask_reference = inner_reference_t<CTM>;
- using value_type = xtl::xmasked_value<base_value_type, flag_type>;
- using reference = xtl::xmasked_value<val_reference, mask_reference>;
- using const_reference = xtl::xmasked_value<typename data_type::const_reference, typename mask_type::const_reference>;
- using size_type = typename data_type::size_type;
- using temporary_type = xarray<xtl::xmasked_value<base_value_type, flag_type>>;
- };
- template <class CTD, class CTM>
- struct xiterable_inner_types<xmasked_view<CTD, CTM>>
- {
- using masked_view_type = xmasked_view<CTD, CTM>;
- using inner_shape_type = typename std::decay_t<CTD>::inner_shape_type;
- using stepper = xmasked_view_stepper<masked_view_type, false>;
- using const_stepper = xmasked_view_stepper<masked_view_type, true>;
- };
- /**
- * @class xmasked_view
- * @brief View on an xoptional_assembly or xoptional_assembly_adaptor
- * hiding values depending on a given mask.
- *
- * The xmasked_view class implements a view on an xoptional_assembly or
- * xoptional_assembly_adaptor, it takes this xoptional_assembly and a
- * mask as input. The mask is an xexpression containing boolean values,
- * whenever the value of the mask is false, the optional value of
- * xmasked_view is considered missing, otherwise it depends on the
- * underlying xoptional_assembly.
- *
- * @tparam CTD The type of expression holding the values.
- * @tparam CTM The type of expression holding the mask.
- */
- template <class CTD, class CTM>
- class xmasked_view : public xview_semantic<xmasked_view<CTD, CTM>>,
- private xaccessible<xmasked_view<CTD, CTM>>,
- private xiterable<xmasked_view<CTD, CTM>>
- {
- public:
- using self_type = xmasked_view<CTD, CTM>;
- using semantic_base = xview_semantic<xmasked_view<CTD, CTM>>;
- using accessible_base = xaccessible<self_type>;
- using inner_types = xcontainer_inner_types<self_type>;
- using temporary_type = typename inner_types::temporary_type;
- using data_type = typename inner_types::data_type;
- using mask_type = typename inner_types::mask_type;
- using value_expression = CTD;
- using mask_expression = CTM;
- static constexpr bool is_data_const = std::is_const<std::remove_reference_t<value_expression>>::value;
- using base_value_type = typename inner_types::base_value_type;
- using base_reference = typename data_type::reference;
- using base_const_reference = typename data_type::const_reference;
- using flag_type = typename inner_types::flag_type;
- using flag_reference = typename mask_type::reference;
- using flag_const_reference = typename mask_type::const_reference;
- using val_reference = typename inner_types::val_reference;
- using mask_reference = typename inner_types::mask_reference;
- using value_type = typename inner_types::value_type;
- using reference = typename inner_types::reference;
- using const_reference = typename inner_types::const_reference;
- using pointer = xtl::xclosure_pointer<reference>;
- using const_pointer = xtl::xclosure_pointer<const_reference>;
- using size_type = typename inner_types::size_type;
- using difference_type = typename data_type::difference_type;
- using bool_load_type = xtl::xmasked_value<typename data_type::bool_load_type, mask_type>;
- using shape_type = typename data_type::shape_type;
- using strides_type = typename data_type::strides_type;
- static constexpr layout_type static_layout = data_type::static_layout;
- static constexpr bool contiguous_layout = false;
- using inner_shape_type = typename data_type::inner_shape_type;
- using inner_strides_type = typename data_type::inner_strides_type;
- using inner_backstrides_type = typename data_type::inner_backstrides_type;
- using expression_tag = xtensor_expression_tag;
- using iterable_base = xiterable<xmasked_view<CTD, CTM>>;
- using stepper = typename iterable_base::stepper;
- using const_stepper = typename iterable_base::const_stepper;
- template <layout_type L>
- using layout_iterator = typename iterable_base::template layout_iterator<L>;
- template <layout_type L>
- using const_layout_iterator = typename iterable_base::template const_layout_iterator<L>;
- template <layout_type L>
- using reverse_layout_iterator = typename iterable_base::template reverse_layout_iterator<L>;
- template <layout_type L>
- using const_reverse_layout_iterator = typename iterable_base::template const_reverse_layout_iterator<L>;
- template <class S, layout_type L>
- using broadcast_iterator = typename iterable_base::template broadcast_iterator<S, L>;
- template <class S, layout_type L>
- using const_broadcast_iterator = typename iterable_base::template const_broadcast_iterator<S, L>;
- template <class S, layout_type L>
- using reverse_broadcast_iterator = typename iterable_base::template reverse_broadcast_iterator<S, L>;
- template <class S, layout_type L>
- using const_reverse_broadcast_iterator = typename iterable_base::template const_reverse_broadcast_iterator<S, L>;
- using iterator = typename iterable_base::iterator;
- using const_iterator = typename iterable_base::const_iterator;
- using reverse_iterator = typename iterable_base::reverse_iterator;
- using const_reverse_iterator = typename iterable_base::const_reverse_iterator;
- template <class D, class M>
- xmasked_view(D&& data, M&& mask);
- xmasked_view(const xmasked_view&) = default;
- size_type size() const noexcept;
- const inner_shape_type& shape() const noexcept;
- const inner_strides_type& strides() const noexcept;
- const inner_backstrides_type& backstrides() const noexcept;
- using accessible_base::dimension;
- using accessible_base::shape;
- layout_type layout() const noexcept;
- bool is_contiguous() const noexcept;
- template <class T>
- void fill(const T& value);
- template <class... Args>
- reference operator()(Args... args);
- template <class... Args>
- const_reference operator()(Args... args) const;
- template <class... Args>
- reference unchecked(Args... args);
- template <class... Args>
- const_reference unchecked(Args... args) const;
- using accessible_base::at;
- using accessible_base::operator[];
- using accessible_base::back;
- using accessible_base::front;
- using accessible_base::in_bounds;
- using accessible_base::periodic;
- template <class It>
- reference element(It first, It last);
- template <class It>
- const_reference element(It first, It last) const;
- template <class S>
- bool has_linear_assign(const S& strides) const noexcept;
- data_type& value() noexcept;
- const data_type& value() const noexcept;
- mask_type& visible() noexcept;
- const mask_type& visible() const noexcept;
- using iterable_base::begin;
- using iterable_base::cbegin;
- using iterable_base::cend;
- using iterable_base::crbegin;
- using iterable_base::crend;
- using iterable_base::end;
- using iterable_base::rbegin;
- using iterable_base::rend;
- template <class S>
- stepper stepper_begin(const S& shape) noexcept;
- template <class S>
- stepper stepper_end(const S& shape, layout_type l) noexcept;
- template <class S>
- const_stepper stepper_begin(const S& shape) const noexcept;
- template <class S>
- const_stepper stepper_end(const S& shape, layout_type l) const noexcept;
- self_type& operator=(const self_type& rhs);
- template <class E>
- self_type& operator=(const xexpression<E>& e);
- template <class E>
- disable_xexpression<E, self_type>& operator=(const E& e);
- private:
- CTD m_data;
- CTM m_mask;
- void assign_temporary_impl(temporary_type&& tmp);
- friend class xiterable<self_type>;
- friend class xconst_iterable<self_type>;
- friend class xview_semantic<self_type>;
- friend class xaccessible<self_type>;
- friend class xconst_accessible<self_type>;
- };
- template <class D, bool is_const>
- class xmasked_view_stepper
- {
- public:
- using self_type = xmasked_view_stepper<D, is_const>;
- using masked_view_type = std::decay_t<D>;
- using value_type = typename masked_view_type::value_type;
- using reference = std::
- conditional_t<is_const, typename masked_view_type::const_reference, typename masked_view_type::reference>;
- using pointer = std::
- conditional_t<is_const, typename masked_view_type::const_pointer, typename masked_view_type::pointer>;
- using size_type = typename masked_view_type::size_type;
- using difference_type = typename masked_view_type::difference_type;
- using data_type = typename masked_view_type::data_type;
- using mask_type = typename masked_view_type::mask_type;
- using value_stepper = std::conditional_t<is_const, typename data_type::const_stepper, typename data_type::stepper>;
- using mask_stepper = std::conditional_t<is_const, typename mask_type::const_stepper, typename mask_type::stepper>;
- xmasked_view_stepper(value_stepper vs, mask_stepper fs) noexcept;
- void step(size_type dim);
- void step_back(size_type dim);
- void step(size_type dim, size_type n);
- void step_back(size_type dim, size_type n);
- void reset(size_type dim);
- void reset_back(size_type dim);
- void to_begin();
- void to_end(layout_type l);
- reference operator*() const;
- private:
- value_stepper m_vs;
- mask_stepper m_ms;
- };
- /*******************************
- * xmasked_view implementation *
- *******************************/
- /**
- * @name Constructors
- */
- //@{
- /**
- * Creates an xmasked_view, given the xoptional_assembly or
- * xoptional_assembly_adaptor and the mask
- *
- * @param data the underlying xoptional_assembly or xoptional_assembly_adaptor
- * @param mask the mask.
- */
- template <class CTD, class CTM>
- template <class D, class M>
- inline xmasked_view<CTD, CTM>::xmasked_view(D&& data, M&& mask)
- : m_data(std::forward<D>(data))
- , m_mask(std::forward<M>(mask))
- {
- }
- /**
- * @name Size and shape
- */
- //@{
- /**
- * Returns the number of elements in the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::size() const noexcept -> size_type
- {
- return m_data.size();
- }
- /**
- * Returns the shape of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::shape() const noexcept -> const inner_shape_type&
- {
- return m_data.shape();
- }
- /**
- * Returns the strides of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::strides() const noexcept -> const inner_strides_type&
- {
- return m_data.strides();
- }
- /**
- * Returns the backstrides of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::backstrides() const noexcept -> const inner_backstrides_type&
- {
- return m_data.backstrides();
- }
- //@}
- /**
- * Return the layout_type of the xmasked_view
- * @return layout_type of the xmasked_view
- */
- template <class CTD, class CTM>
- inline layout_type xmasked_view<CTD, CTM>::layout() const noexcept
- {
- return m_data.layout();
- }
- template <class CTD, class CTM>
- inline bool xmasked_view<CTD, CTM>::is_contiguous() const noexcept
- {
- return false;
- }
- /**
- * Fills the data with the given value.
- * @param value the value to fill the data with.
- */
- template <class CTD, class CTM>
- template <class T>
- inline void xmasked_view<CTD, CTM>::fill(const T& value)
- {
- std::fill(this->begin(), this->end(), value);
- }
- /**
- * @name Data
- */
- //@{
- /**
- * Returns a reference to the element at the specified position in the xmasked_view.
- * @param args a list of indices specifying the position in the xmasked_view. Indices
- * must be unsigned integers, the number of indices should be equal or greater than
- * the number of dimensions of the xmasked_view.
- */
- template <class CTD, class CTM>
- template <class... Args>
- inline auto xmasked_view<CTD, CTM>::operator()(Args... args) -> reference
- {
- return reference(m_data(args...), m_mask(args...));
- }
- /**
- * Returns a constant reference to the element at the specified position in the xmasked_view.
- * @param args a list of indices specifying the position in the xmasked_view. Indices
- * must be unsigned integers, the number of indices should be equal or greater than
- * the number of dimensions of the xmasked_view.
- */
- template <class CTD, class CTM>
- template <class... Args>
- inline auto xmasked_view<CTD, CTM>::operator()(Args... args) const -> const_reference
- {
- return const_reference(m_data(args...), m_mask(args...));
- }
- /**
- * Returns a reference to the element at the specified position in the xmasked_view.
- * @param args a list of indices specifying the position in the xmasked_view. Indices
- * must be unsigned integers, the number of indices must be equal to the number of
- * dimensions of the xmasked_view, else the behavior is undefined.
- *
- * @warning This method is meant for performance, for expressions with a dynamic
- * number of dimensions (i.e. not known at compile time). Since it may have
- * undefined behavior (see parameters), operator() should be preferred whenever
- * it is possible.
- * @warning This method is NOT compatible with broadcasting, meaning the following
- * code has undefined behavior:
- * @code{.cpp}
- * xt::xarray<double> a = {{0, 1}, {2, 3}};
- * xt::xarray<double> b = {0, 1};
- * auto fd = a + b;
- * double res = fd.uncheked(0, 1);
- * @endcode
- */
- template <class CTD, class CTM>
- template <class... Args>
- inline auto xmasked_view<CTD, CTM>::unchecked(Args... args) -> reference
- {
- return reference(m_data.unchecked(args...), m_mask.unchecked(args...));
- }
- /**
- * Returns a constant reference to the element at the specified position in the xmasked_view.
- * @param args a list of indices specifying the position in the xmasked_view. Indices
- * must be unsigned integers, the number of indices must be equal to the number of
- * dimensions of the xmasked_view, else the behavior is undefined.
- *
- * @warning This method is meant for performance, for expressions with a dynamic
- * number of dimensions (i.e. not known at compile time). Since it may have
- * undefined behavior (see parameters), operator() should be preferred whenever
- * it is possible.
- * @warning This method is NOT compatible with broadcasting, meaning the following
- * code has undefined behavior:
- * @code{.cpp}
- * xt::xarray<double> a = {{0, 1}, {2, 3}};
- * xt::xarray<double> b = {0, 1};
- * auto fd = a + b;
- * double res = fd.uncheked(0, 1);
- * @endcode
- */
- template <class CTD, class CTM>
- template <class... Args>
- inline auto xmasked_view<CTD, CTM>::unchecked(Args... args) const -> const_reference
- {
- return const_reference(m_data.unchecked(args...), m_mask.unchecked(args...));
- }
- /**
- * Returns a reference to the element at the specified position in the xmasked_view.
- * @param first iterator starting the sequence of indices
- * @param last iterator ending the sequence of indices
- * The number of indices in the sequence should be equal to or greater
- * than the number of dimensions of the xmasked_view.
- */
- template <class CTD, class CTM>
- template <class It>
- inline auto xmasked_view<CTD, CTM>::element(It first, It last) -> reference
- {
- return reference(m_data.element(first, last), m_mask.element(first, last));
- }
- /**
- * Returns a constant reference to the element at the specified position in the xmasked_view.
- * @param first iterator starting the sequence of indices
- * @param last iterator ending the sequence of indices
- * The number of indices in the sequence should be equal to or greater
- * than the number of dimensions of the xmasked_view.
- */
- template <class CTD, class CTM>
- template <class It>
- inline auto xmasked_view<CTD, CTM>::element(It first, It last) const -> const_reference
- {
- return const_reference(m_data.element(first, last), m_mask.element(first, last));
- }
- //@}
- template <class CTD, class CTM>
- template <class S>
- inline bool xmasked_view<CTD, CTM>::has_linear_assign(const S& strides) const noexcept
- {
- return m_data.has_linear_assign(strides) && m_mask.has_linear_assign(strides);
- }
- /**
- * Return an expression for the values of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::value() noexcept -> data_type&
- {
- return m_data;
- }
- /**
- * Return a constant expression for the values of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::value() const noexcept -> const data_type&
- {
- return m_data;
- }
- /**
- * Return an expression for the mask of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::visible() noexcept -> mask_type&
- {
- return m_mask;
- }
- /**
- * Return a constant expression for the mask of the xmasked_view.
- */
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::visible() const noexcept -> const mask_type&
- {
- return m_mask;
- }
- template <class CTD, class CTM>
- template <class S>
- inline auto xmasked_view<CTD, CTM>::stepper_begin(const S& shape) noexcept -> stepper
- {
- return stepper(value().stepper_begin(shape), visible().stepper_begin(shape));
- }
- template <class CTD, class CTM>
- template <class S>
- inline auto xmasked_view<CTD, CTM>::stepper_end(const S& shape, layout_type l) noexcept -> stepper
- {
- return stepper(value().stepper_end(shape, l), visible().stepper_end(shape, l));
- }
- template <class CTD, class CTM>
- template <class S>
- inline auto xmasked_view<CTD, CTM>::stepper_begin(const S& shape) const noexcept -> const_stepper
- {
- return const_stepper(value().stepper_begin(shape), visible().stepper_begin(shape));
- }
- template <class CTD, class CTM>
- template <class S>
- inline auto xmasked_view<CTD, CTM>::stepper_end(const S& shape, layout_type l) const noexcept
- -> const_stepper
- {
- return const_stepper(value().stepper_end(shape, l), visible().stepper_end(shape, l));
- }
- template <class CTD, class CTM>
- inline auto xmasked_view<CTD, CTM>::operator=(const self_type& rhs) -> self_type&
- {
- temporary_type tmp(rhs);
- return this->assign_temporary(std::move(tmp));
- }
- template <class CTD, class CTM>
- template <class E>
- inline auto xmasked_view<CTD, CTM>::operator=(const xexpression<E>& e) -> self_type&
- {
- return semantic_base::operator=(e);
- }
- template <class CTD, class CTM>
- template <class E>
- inline auto xmasked_view<CTD, CTM>::operator=(const E& e) -> disable_xexpression<E, self_type>&
- {
- std::fill(this->begin(), this->end(), e);
- return *this;
- }
- template <class CTD, class CTM>
- inline void xmasked_view<CTD, CTM>::assign_temporary_impl(temporary_type&& tmp)
- {
- std::copy(tmp.cbegin(), tmp.cend(), this->begin());
- }
- template <class CTD, class CTM>
- inline xmasked_view<CTD, CTM> masked_view(CTD&& data, CTM&& mask)
- {
- return xmasked_view<CTD, CTM>(std::forward<CTD>(data), std::forward<CTM>(mask));
- }
- /***************************************
- * xmasked_view_stepper implementation *
- ***************************************/
- template <class D, bool C>
- inline xmasked_view_stepper<D, C>::xmasked_view_stepper(value_stepper vs, mask_stepper ms) noexcept
- : m_vs(vs)
- , m_ms(ms)
- {
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::step(size_type dim)
- {
- m_vs.step(dim);
- m_ms.step(dim);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::step_back(size_type dim)
- {
- m_vs.step_back(dim);
- m_ms.step_back(dim);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::step(size_type dim, size_type n)
- {
- m_vs.step(dim, n);
- m_ms.step(dim, n);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::step_back(size_type dim, size_type n)
- {
- m_vs.step_back(dim, n);
- m_ms.step_back(dim, n);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::reset(size_type dim)
- {
- m_vs.reset(dim);
- m_ms.reset(dim);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::reset_back(size_type dim)
- {
- m_vs.reset_back(dim);
- m_ms.reset_back(dim);
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::to_begin()
- {
- m_vs.to_begin();
- m_ms.to_begin();
- }
- template <class D, bool C>
- inline void xmasked_view_stepper<D, C>::to_end(layout_type l)
- {
- m_vs.to_end(l);
- m_ms.to_end(l);
- }
- template <class D, bool C>
- inline auto xmasked_view_stepper<D, C>::operator*() const -> reference
- {
- return reference(*m_vs, *m_ms);
- }
- }
- #endif
|