xtensor
 
Loading...
Searching...
No Matches
xindex_view.hpp
1/***************************************************************************
2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3 * Copyright (c) QuantStack *
4 * *
5 * Distributed under the terms of the BSD 3-Clause License. *
6 * *
7 * The full license is in the file LICENSE, distributed with this software. *
8 ****************************************************************************/
9
10#ifndef XTENSOR_INDEX_VIEW_HPP
11#define XTENSOR_INDEX_VIEW_HPP
12
13#include <algorithm>
14#include <array>
15#include <cstddef>
16#include <type_traits>
17#include <utility>
18
19#include "../core/xexpression.hpp"
20#include "../core/xiterable.hpp"
21#include "../core/xoperation.hpp"
22#include "../core/xsemantic.hpp"
23#include "../core/xstrides.hpp"
24#include "../utils/xutils.hpp"
25
26namespace xt
27{
28
29 /*************************
30 * xindex_view extension *
31 *************************/
32
33 namespace extension
34 {
35 template <class Tag, class CT, class I>
37
38 template <class CT, class I>
40 {
41 using type = xtensor_empty_base;
42 };
43
44 template <class CT, class I>
45 struct xindex_view_base : xindex_view_base_impl<xexpression_tag_t<CT>, CT, I>
46 {
47 };
48
49 template <class CT, class I>
50 using xindex_view_base_t = typename xindex_view_base<CT, I>::type;
51 }
52
53 /***************
54 * xindex_view *
55 ***************/
56
57 template <class CT, class I>
58 class xindex_view;
59
60 template <class CT, class I>
62 {
63 using xexpression_type = std::decay_t<CT>;
65 };
66
67 template <class CT, class I>
69 {
70 using inner_shape_type = std::array<std::size_t, 1>;
71 using const_stepper = xindexed_stepper<xindex_view<CT, I>, true>;
72 using stepper = xindexed_stepper<xindex_view<CT, I>, false>;
73 };
74
89 template <class CT, class I>
90 class xindex_view : public xview_semantic<xindex_view<CT, I>>,
91 public xiterable<xindex_view<CT, I>>,
92 public extension::xindex_view_base_t<CT, I>
93 {
94 public:
95
96 using self_type = xindex_view<CT, I>;
97 using xexpression_type = std::decay_t<CT>;
98 using semantic_base = xview_semantic<self_type>;
99
100 using extension_base = extension::xindex_view_base_t<CT, I>;
101 using expression_tag = typename extension_base::expression_tag;
102
103 using value_type = typename xexpression_type::value_type;
104 using reference = inner_reference_t<CT>;
105 using const_reference = typename xexpression_type::const_reference;
106 using pointer = typename xexpression_type::pointer;
107 using const_pointer = typename xexpression_type::const_pointer;
108 using size_type = typename xexpression_type::size_type;
109 using difference_type = typename xexpression_type::difference_type;
110
111 using iterable_base = xiterable<self_type>;
112 using inner_shape_type = typename iterable_base::inner_shape_type;
113 using shape_type = inner_shape_type;
114
115 using indices_type = I;
116
117 using stepper = typename iterable_base::stepper;
118 using const_stepper = typename iterable_base::const_stepper;
119
120 using temporary_type = typename xcontainer_inner_types<self_type>::temporary_type;
121 using base_index_type = xindex_type_t<shape_type>;
122
123 using bool_load_type = typename xexpression_type::bool_load_type;
124
125 static constexpr layout_type static_layout = layout_type::dynamic;
126 static constexpr bool contiguous_layout = false;
127
128 template <class CTA, class I2>
129 xindex_view(CTA&& e, I2&& indices) noexcept;
130
131 template <class E>
132 self_type& operator=(const xexpression<E>& e);
133
134 template <class E>
135 disable_xexpression<E, self_type>& operator=(const E& e);
136
137 size_type size() const noexcept;
138 size_type dimension() const noexcept;
139 const inner_shape_type& shape() const noexcept;
140 size_type shape(size_type index) const;
141 layout_type layout() const noexcept;
142 bool is_contiguous() const noexcept;
143
144 template <class T>
145 void fill(const T& value);
146
147 reference operator()(size_type idx = size_type(0));
148 template <class... Args>
149 reference operator()(size_type idx0, size_type idx1, Args... args);
150 reference unchecked(size_type idx);
151 template <class S>
152 disable_integral_t<S, reference> operator[](const S& index);
153 template <class OI>
154 reference operator[](std::initializer_list<OI> index);
155 reference operator[](size_type i);
156
157 template <class It>
158 reference element(It first, It last);
159
160 const_reference operator()(size_type idx = size_type(0)) const;
161 template <class... Args>
162 const_reference operator()(size_type idx0, size_type idx1, Args... args) const;
163 const_reference unchecked(size_type idx) const;
164 template <class S>
165 disable_integral_t<S, const_reference> operator[](const S& index) const;
166 template <class OI>
167 const_reference operator[](std::initializer_list<OI> index) const;
168 const_reference operator[](size_type i) const;
169
170 template <class It>
171 const_reference element(It first, It last) const;
172
173 xexpression_type& expression() noexcept;
174 const xexpression_type& expression() const noexcept;
175
176 template <class O>
177 bool broadcast_shape(O& shape, bool reuse_cache = false) const;
178
179 template <class O>
180 bool has_linear_assign(const O& /*strides*/) const noexcept;
181
182 template <class ST>
183 stepper stepper_begin(const ST& shape);
184 template <class ST>
185 stepper stepper_end(const ST& shape, layout_type);
186
187 template <class ST>
188 const_stepper stepper_begin(const ST& shape) const;
189 template <class ST>
190 const_stepper stepper_end(const ST& shape, layout_type) const;
191
192 template <class E>
193 using rebind_t = xindex_view<E, I>;
194
195 template <class E>
196 rebind_t<E> build_index_view(E&& e) const;
197
198 private:
199
200 CT m_e;
201 const indices_type m_indices;
202 const inner_shape_type m_shape;
203
204 void assign_temporary_impl(temporary_type&& tmp);
205
206 friend class xview_semantic<xindex_view<CT, I>>;
207 };
208
209 /***************
210 * xfiltration *
211 ***************/
212
231 template <class ECT, class CCT>
233 {
234 public:
235
236 using self_type = xfiltration<ECT, CCT>;
237 using xexpression_type = std::decay_t<ECT>;
238 using const_reference = typename xexpression_type::const_reference;
239
240 template <class ECTA, class CCTA>
241 xfiltration(ECTA&& e, CCTA&& condition);
242
243 template <class E>
244 disable_xexpression<E, self_type&> operator=(const E&);
245
246 template <class E>
247 disable_xexpression<E, self_type&> operator+=(const E&);
248
249 template <class E>
250 disable_xexpression<E, self_type&> operator-=(const E&);
251
252 template <class E>
253 disable_xexpression<E, self_type&> operator*=(const E&);
254
255 template <class E>
256 disable_xexpression<E, self_type&> operator/=(const E&);
257
258 template <class E>
259 disable_xexpression<E, self_type&> operator%=(const E&);
260
261 private:
262
263 template <class F>
264 self_type& apply(F&& func);
265
266 ECT m_e;
267 CCT m_condition;
268 };
269
270 /******************************
271 * xindex_view implementation *
272 ******************************/
273
278
285 template <class CT, class I>
286 template <class CTA, class I2>
287 inline xindex_view<CT, I>::xindex_view(CTA&& e, I2&& indices) noexcept
288 : m_e(std::forward<CTA>(e))
289 , m_indices(std::forward<I2>(indices))
290 , m_shape({m_indices.size()})
291 {
292 }
293
295
300
303 template <class CT, class I>
304 template <class E>
305 inline auto xindex_view<CT, I>::operator=(const xexpression<E>& e) -> self_type&
306 {
307 return semantic_base::operator=(e);
308 }
309
311
312 template <class CT, class I>
313 template <class E>
314 inline auto xindex_view<CT, I>::operator=(const E& e) -> disable_xexpression<E, self_type>&
315 {
316 std::fill(this->begin(), this->end(), e);
317 return *this;
318 }
319
320 template <class CT, class I>
321 inline void xindex_view<CT, I>::assign_temporary_impl(temporary_type&& tmp)
322 {
323 std::copy(tmp.cbegin(), tmp.cend(), this->begin());
324 }
325
330
333 template <class CT, class I>
334 inline auto xindex_view<CT, I>::size() const noexcept -> size_type
335 {
336 return compute_size(shape());
337 }
338
342 template <class CT, class I>
343 inline auto xindex_view<CT, I>::dimension() const noexcept -> size_type
344 {
345 return 1;
346 }
347
351 template <class CT, class I>
352 inline auto xindex_view<CT, I>::shape() const noexcept -> const inner_shape_type&
353 {
354 return m_shape;
355 }
356
360 template <class CT, class I>
361 inline auto xindex_view<CT, I>::shape(size_type i) const -> size_type
362 {
363 return m_shape[i];
364 }
365
366 template <class CT, class I>
367 inline layout_type xindex_view<CT, I>::layout() const noexcept
368 {
369 return static_layout;
370 }
371
372 template <class CT, class I>
373 inline bool xindex_view<CT, I>::is_contiguous() const noexcept
374 {
375 return false;
376 }
377
379
384
389 template <class CT, class I>
390 template <class T>
391 inline void xindex_view<CT, I>::fill(const T& value)
392 {
393 std::fill(this->begin(), this->end(), value);
394 }
395
401 template <class CT, class I>
402 inline auto xindex_view<CT, I>::operator()(size_type idx) -> reference
403 {
404 return m_e[m_indices[idx]];
405 }
406
407 template <class CT, class I>
408 template <class... Args>
409 inline auto xindex_view<CT, I>::operator()(size_type, size_type idx1, Args... args) -> reference
410 {
411 return this->operator()(idx1, static_cast<size_type>(args)...);
412 }
413
418 template <class CT, class I>
419 inline auto xindex_view<CT, I>::unchecked(size_type idx) -> reference
420 {
421 return this->operator()(idx);
422 }
423
429 template <class CT, class I>
430 inline auto xindex_view<CT, I>::operator()(size_type idx) const -> const_reference
431 {
432 return m_e[m_indices[idx]];
433 }
434
435 template <class CT, class I>
436 template <class... Args>
437 inline auto xindex_view<CT, I>::operator()(size_type, size_type idx1, Args... args) const -> const_reference
438 {
439 return this->operator()(idx1, args...);
440 }
441
446 template <class CT, class I>
447 inline auto xindex_view<CT, I>::unchecked(size_type idx) const -> const_reference
448 {
449 return this->operator()(idx);
450 }
451
458 template <class CT, class I>
459 template <class S>
460 inline auto xindex_view<CT, I>::operator[](const S& index) -> disable_integral_t<S, reference>
461 {
462 return m_e[m_indices[index[0]]];
463 }
464
465 template <class CT, class I>
466 template <class OI>
467 inline auto xindex_view<CT, I>::operator[](std::initializer_list<OI> index) -> reference
468 {
469 return m_e[m_indices[*(index.begin())]];
470 }
471
472 template <class CT, class I>
473 inline auto xindex_view<CT, I>::operator[](size_type i) -> reference
474 {
475 return operator()(i);
476 }
477
484 template <class CT, class I>
485 template <class S>
486 inline auto xindex_view<CT, I>::operator[](const S& index) const -> disable_integral_t<S, const_reference>
487 {
488 return m_e[m_indices[index[0]]];
489 }
490
491 template <class CT, class I>
492 template <class OI>
493 inline auto xindex_view<CT, I>::operator[](std::initializer_list<OI> index) const -> const_reference
494 {
495 return m_e[m_indices[*(index.begin())]];
496 }
497
498 template <class CT, class I>
499 inline auto xindex_view<CT, I>::operator[](size_type i) const -> const_reference
500 {
501 return operator()(i);
502 }
503
510 template <class CT, class I>
511 template <class It>
512 inline auto xindex_view<CT, I>::element(It first, It /*last*/) -> reference
513 {
514 return m_e[m_indices[(*first)]];
515 }
516
523 template <class CT, class I>
524 template <class It>
525 inline auto xindex_view<CT, I>::element(It first, It /*last*/) const -> const_reference
526 {
527 return m_e[m_indices[(*first)]];
528 }
529
533 template <class CT, class I>
534 inline auto xindex_view<CT, I>::expression() noexcept -> xexpression_type&
535 {
536 return m_e;
537 }
538
542 template <class CT, class I>
543 inline auto xindex_view<CT, I>::expression() const noexcept -> const xexpression_type&
544 {
545 return m_e;
546 }
547
549
554
560 template <class CT, class I>
561 template <class O>
562 inline bool xindex_view<CT, I>::broadcast_shape(O& shape, bool) const
563 {
564 return xt::broadcast_shape(m_shape, shape);
565 }
566
572 template <class CT, class I>
573 template <class O>
574 inline bool xindex_view<CT, I>::has_linear_assign(const O& /*strides*/) const noexcept
575 {
576 return false;
577 }
578
580
581 /***************
582 * stepper api *
583 ***************/
584
585 template <class CT, class I>
586 template <class ST>
587 inline auto xindex_view<CT, I>::stepper_begin(const ST& shape) -> stepper
588 {
589 size_type offset = shape.size() - dimension();
590 return stepper(this, offset);
591 }
592
593 template <class CT, class I>
594 template <class ST>
595 inline auto xindex_view<CT, I>::stepper_end(const ST& shape, layout_type) -> stepper
596 {
597 size_type offset = shape.size() - dimension();
598 return stepper(this, offset, true);
599 }
600
601 template <class CT, class I>
602 template <class ST>
603 inline auto xindex_view<CT, I>::stepper_begin(const ST& shape) const -> const_stepper
604 {
605 size_type offset = shape.size() - dimension();
606 return const_stepper(this, offset);
607 }
608
609 template <class CT, class I>
610 template <class ST>
611 inline auto xindex_view<CT, I>::stepper_end(const ST& shape, layout_type) const -> const_stepper
612 {
613 size_type offset = shape.size() - dimension();
614 return const_stepper(this, offset, true);
615 }
616
617 template <class CT, class I>
618 template <class E>
619 inline auto xindex_view<CT, I>::build_index_view(E&& e) const -> rebind_t<E>
620 {
621 return rebind_t<E>(std::forward<E>(e), indices_type(m_indices));
622 }
623
624 /******************************
625 * xfiltration implementation *
626 ******************************/
627
632
639 template <class ECT, class CCT>
640 template <class ECTA, class CCTA>
641 inline xfiltration<ECT, CCT>::xfiltration(ECTA&& e, CCTA&& condition)
642 : m_e(std::forward<ECTA>(e))
643 , m_condition(std::forward<CCTA>(condition))
644 {
645 }
646
648
653
658 template <class ECT, class CCT>
659 template <class E>
660 inline auto xfiltration<ECT, CCT>::operator=(const E& e) -> disable_xexpression<E, self_type&>
661 {
662 return apply(
663 [this, &e](const_reference v, bool cond)
664 {
665 return cond ? e : v;
666 }
667 );
668 }
669
671
676
681 template <class ECT, class CCT>
682 template <class E>
683 inline auto xfiltration<ECT, CCT>::operator+=(const E& e) -> disable_xexpression<E, self_type&>
684 {
685 return apply(
686 [&e](const_reference v, bool cond)
687 {
688 return cond ? v + e : v;
689 }
690 );
691 }
692
698 template <class ECT, class CCT>
699 template <class E>
700 inline auto xfiltration<ECT, CCT>::operator-=(const E& e) -> disable_xexpression<E, self_type&>
701 {
702 return apply(
703 [&e](const_reference v, bool cond)
704 {
705 return cond ? v - e : v;
706 }
707 );
708 }
709
715 template <class ECT, class CCT>
716 template <class E>
717 inline auto xfiltration<ECT, CCT>::operator*=(const E& e) -> disable_xexpression<E, self_type&>
718 {
719 return apply(
720 [&e](const_reference v, bool cond)
721 {
722 return cond ? v * e : v;
723 }
724 );
725 }
726
732 template <class ECT, class CCT>
733 template <class E>
734 inline auto xfiltration<ECT, CCT>::operator/=(const E& e) -> disable_xexpression<E, self_type&>
735 {
736 return apply(
737 [&e](const_reference v, bool cond)
738 {
739 return cond ? v / e : v;
740 }
741 );
742 }
743
749 template <class ECT, class CCT>
750 template <class E>
751 inline auto xfiltration<ECT, CCT>::operator%=(const E& e) -> disable_xexpression<E, self_type&>
752 {
753 return apply(
754 [&e](const_reference v, bool cond)
755 {
756 return cond ? v % e : v;
757 }
758 );
759 }
760
761 template <class ECT, class CCT>
762 template <class F>
763 inline auto xfiltration<ECT, CCT>::apply(F&& func) -> self_type&
764 {
765 std::transform(m_e.cbegin(), m_e.cend(), m_condition.cbegin(), m_e.begin(), func);
766 return *this;
767 }
768
785 template <class E, class I>
786 inline auto index_view(E&& e, I&& indices) noexcept
787 {
788 using view_type = xindex_view<xclosure_t<E>, std::decay_t<I>>;
789 return view_type(std::forward<E>(e), std::forward<I>(indices));
790 }
791
792 template <class E, std::size_t L>
793 inline auto index_view(E&& e, const xindex (&indices)[L]) noexcept
794 {
795 using view_type = xindex_view<xclosure_t<E>, std::array<xindex, L>>;
796 return view_type(std::forward<E>(e), xt::to_array(indices));
797 }
798
820 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class O>
821 inline auto filter(E&& e, O&& condition) noexcept
822 {
823 auto indices = argwhere<L>(std::forward<O>(condition));
824 using view_type = xindex_view<xclosure_t<E>, decltype(indices)>;
825 return view_type(std::forward<E>(e), std::move(indices));
826 }
827
845 template <class E, class C>
846 inline auto filtration(E&& e, C&& condition) noexcept
847 {
848 using filtration_type = xfiltration<xclosure_t<E>, xclosure_t<C>>;
849 return filtration_type(std::forward<E>(e), std::forward<C>(condition));
850 }
851}
852
853#endif
Base class for xexpressions.
Filter of a xexpression for fast scalar assign.
xfiltration(ECTA &&e, CCTA &&condition)
Constructs a xfiltration on the given expression e, selecting the elements matching the specified con...
View of an xexpression from vector of indices.
xindex_view(CTA &&e, I2 &&indices) noexcept
Constructs an xindex_view, selecting the indices specified by indices.
bool has_linear_assign(const O &) const noexcept
size_type size() const noexcept
Returns the size of the xindex_view.
reference unchecked(size_type idx)
reference operator()(size_type idx=size_type(0))
Returns a reference to the element at the specified position in the xindex_view.
xexpression_type & expression() noexcept
bool broadcast_shape(O &shape, bool reuse_cache=false) const
const inner_shape_type & shape() const noexcept
void fill(const T &value)
size_type dimension() const noexcept
Base class for multidimensional iterable expressions.
auto end() noexcept -> layout_iterator< L >
auto begin() noexcept -> layout_iterator< L >
auto operator%=(const E &e) -> disable_xexpression< E, derived_type & >
auto operator+=(const E &e) -> disable_xexpression< E, derived_type & >
auto operator*=(const E &e) -> disable_xexpression< E, derived_type & >
auto operator/=(const E &e) -> disable_xexpression< E, derived_type & >
auto operator-=(const E &e) -> disable_xexpression< E, derived_type & >
auto argwhere(const T &arr)
return vector of indices where arr is not zero
standard mathematical functions for xexpressions
xarray_container< uvector< T, A >, L, xt::svector< typename uvector< T, A >::size_type, 4, SA, true > > xarray
Alias template on xarray_container with default parameters for data container type and shape / stride...
layout_type
Definition xlayout.hpp:24
auto filtration(E &&e, C &&condition) noexcept
creates a filtration of e filtered by condition.
auto index_view(E &&e, I &&indices) noexcept
creates an indexview from a container of indices.
auto filter(E &&e, O &&condition) noexcept
creates a view into e filtered by condition.