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 <tuple>
17#include <type_traits>
18#include <utility>
19
20#include "xexpression.hpp"
21#include "xiterable.hpp"
22#include "xoperation.hpp"
23#include "xsemantic.hpp"
24#include "xstrides.hpp"
25#include "xutils.hpp"
26
27namespace xt
28{
29
30 /*************************
31 * xindex_view extension *
32 *************************/
33
34 namespace extension
35 {
36 template <class Tag, class CT, class I>
38
39 template <class CT, class I>
44
45 template <class CT, class I>
46 struct xindex_view_base : xindex_view_base_impl<xexpression_tag_t<CT>, CT, I>
47 {
48 };
49
50 template <class CT, class I>
51 using xindex_view_base_t = typename xindex_view_base<CT, I>::type;
52 }
53
54 /***************
55 * xindex_view *
56 ***************/
57
58 template <class CT, class I>
59 class xindex_view;
60
61 template <class CT, class I>
63 {
64 using xexpression_type = std::decay_t<CT>;
66 };
67
68 template <class CT, class I>
70 {
71 using inner_shape_type = std::array<std::size_t, 1>;
74 };
75
90 template <class CT, class I>
91 class xindex_view : public xview_semantic<xindex_view<CT, I>>,
92 public xiterable<xindex_view<CT, I>>,
93 public extension::xindex_view_base_t<CT, I>
94 {
95 public:
96
98 using xexpression_type = std::decay_t<CT>;
100
101 using extension_base = extension::xindex_view_base_t<CT, I>;
102 using expression_tag = typename extension_base::expression_tag;
103
104 using value_type = typename xexpression_type::value_type;
106 using const_reference = typename xexpression_type::const_reference;
107 using pointer = typename xexpression_type::pointer;
108 using const_pointer = typename xexpression_type::const_pointer;
109 using size_type = typename xexpression_type::size_type;
110 using difference_type = typename xexpression_type::difference_type;
111
113 using inner_shape_type = typename iterable_base::inner_shape_type;
114 using shape_type = inner_shape_type;
115
116 using indices_type = I;
117
118 using stepper = typename iterable_base::stepper;
119 using const_stepper = typename iterable_base::const_stepper;
120
121 using temporary_type = typename xcontainer_inner_types<self_type>::temporary_type;
123
124 using bool_load_type = typename xexpression_type::bool_load_type;
125
126 static constexpr layout_type static_layout = layout_type::dynamic;
127 static constexpr bool contiguous_layout = false;
128
129 template <class CTA, class I2>
130 xindex_view(CTA&& e, I2&& indices) noexcept;
131
132 template <class E>
133 self_type& operator=(const xexpression<E>& e);
134
135 template <class E>
136 disable_xexpression<E, self_type>& operator=(const E& e);
137
138 size_type size() const noexcept;
139 size_type dimension() const noexcept;
140 const inner_shape_type& shape() const noexcept;
141 size_type shape(size_type index) const;
142 layout_type layout() const noexcept;
143 bool is_contiguous() const noexcept;
144
145 template <class T>
146 void fill(const T& value);
147
148 reference operator()(size_type idx = size_type(0));
149 template <class... Args>
150 reference operator()(size_type idx0, size_type idx1, Args... args);
151 reference unchecked(size_type idx);
152 template <class S>
153 disable_integral_t<S, reference> operator[](const S& index);
154 template <class OI>
155 reference operator[](std::initializer_list<OI> index);
156 reference operator[](size_type i);
157
158 template <class It>
159 reference element(It first, It last);
160
161 const_reference operator()(size_type idx = size_type(0)) const;
162 template <class... Args>
163 const_reference operator()(size_type idx0, size_type idx1, Args... args) const;
164 const_reference unchecked(size_type idx) const;
165 template <class S>
166 disable_integral_t<S, const_reference> operator[](const S& index) const;
167 template <class OI>
168 const_reference operator[](std::initializer_list<OI> index) const;
169 const_reference operator[](size_type i) const;
170
171 template <class It>
172 const_reference element(It first, It last) const;
173
174 xexpression_type& expression() noexcept;
175 const xexpression_type& expression() const noexcept;
176
177 template <class O>
178 bool broadcast_shape(O& shape, bool reuse_cache = false) const;
179
180 template <class O>
181 bool has_linear_assign(const O& /*strides*/) const noexcept;
182
183 template <class ST>
184 stepper stepper_begin(const ST& shape);
185 template <class ST>
186 stepper stepper_end(const ST& shape, layout_type);
187
188 template <class ST>
189 const_stepper stepper_begin(const ST& shape) const;
190 template <class ST>
191 const_stepper stepper_end(const ST& shape, layout_type) const;
192
193 template <class E>
195
196 template <class E>
197 rebind_t<E> build_index_view(E&& e) const;
198
199 private:
200
201 CT m_e;
202 const indices_type m_indices;
203 const inner_shape_type m_shape;
204
205 void assign_temporary_impl(temporary_type&& tmp);
206
207 friend class xview_semantic<xindex_view<CT, I>>;
208 };
209
210 /***************
211 * xfiltration *
212 ***************/
213
232 template <class ECT, class CCT>
234 {
235 public:
236
238 using xexpression_type = std::decay_t<ECT>;
239 using const_reference = typename xexpression_type::const_reference;
240
241 template <class ECTA, class CCTA>
243
244 template <class E>
245 disable_xexpression<E, self_type&> operator=(const E&);
246
247 template <class E>
248 disable_xexpression<E, self_type&> operator+=(const E&);
249
250 template <class E>
251 disable_xexpression<E, self_type&> operator-=(const E&);
252
253 template <class E>
254 disable_xexpression<E, self_type&> operator*=(const E&);
255
256 template <class E>
257 disable_xexpression<E, self_type&> operator/=(const E&);
258
259 template <class E>
260 disable_xexpression<E, self_type&> operator%=(const E&);
261
262 private:
263
264 template <class F>
265 self_type& apply(F&& func);
266
267 ECT m_e;
268 CCT m_condition;
269 };
270
271 /******************************
272 * xindex_view implementation *
273 ******************************/
274
286 template <class CT, class I>
287 template <class CTA, class I2>
289 : m_e(std::forward<CTA>(e))
290 , m_indices(std::forward<I2>(indices))
291 , m_shape({m_indices.size()})
292 {
293 }
294
296
304 template <class CT, class I>
305 template <class E>
307 {
308 return semantic_base::operator=(e);
309 }
310
312
313 template <class CT, class I>
314 template <class E>
316 {
317 std::fill(this->begin(), this->end(), e);
318 return *this;
319 }
320
321 template <class CT, class I>
322 inline void xindex_view<CT, I>::assign_temporary_impl(temporary_type&& tmp)
323 {
324 std::copy(tmp.cbegin(), tmp.cend(), this->begin());
325 }
326
334 template <class CT, class I>
335 inline auto xindex_view<CT, I>::size() const noexcept -> size_type
336 {
337 return compute_size(shape());
338 }
339
343 template <class CT, class I>
345 {
346 return 1;
347 }
348
352 template <class CT, class I>
353 inline auto xindex_view<CT, I>::shape() const noexcept -> const inner_shape_type&
354 {
355 return m_shape;
356 }
357
361 template <class CT, class I>
362 inline auto xindex_view<CT, I>::shape(size_type i) const -> size_type
363 {
364 return m_shape[i];
365 }
366
367 template <class CT, class I>
369 {
370 return static_layout;
371 }
372
373 template <class CT, class I>
374 inline bool xindex_view<CT, I>::is_contiguous() const noexcept
375 {
376 return false;
377 }
378
380
385
390 template <class CT, class I>
391 template <class T>
392 inline void xindex_view<CT, I>::fill(const T& value)
393 {
394 std::fill(this->begin(), this->end(), value);
395 }
396
402 template <class CT, class I>
403 inline auto xindex_view<CT, I>::operator()(size_type idx) -> reference
404 {
405 return m_e[m_indices[idx]];
406 }
407
408 template <class CT, class I>
409 template <class... Args>
410 inline auto xindex_view<CT, I>::operator()(size_type, size_type idx1, Args... args) -> reference
411 {
412 return this->operator()(idx1, static_cast<size_type>(args)...);
413 }
414
419 template <class CT, class I>
420 inline auto xindex_view<CT, I>::unchecked(size_type idx) -> reference
421 {
422 return this->operator()(idx);
423 }
424
430 template <class CT, class I>
431 inline auto xindex_view<CT, I>::operator()(size_type idx) const -> const_reference
432 {
433 return m_e[m_indices[idx]];
434 }
435
436 template <class CT, class I>
437 template <class... Args>
438 inline auto xindex_view<CT, I>::operator()(size_type, size_type idx1, Args... args) const -> const_reference
439 {
440 return this->operator()(idx1, args...);
441 }
442
447 template <class CT, class I>
448 inline auto xindex_view<CT, I>::unchecked(size_type idx) const -> const_reference
449 {
450 return this->operator()(idx);
451 }
452
459 template <class CT, class I>
460 template <class S>
462 {
463 return m_e[m_indices[index[0]]];
464 }
465
466 template <class CT, class I>
467 template <class OI>
468 inline auto xindex_view<CT, I>::operator[](std::initializer_list<OI> index) -> reference
469 {
470 return m_e[m_indices[*(index.begin())]];
471 }
472
473 template <class CT, class I>
474 inline auto xindex_view<CT, I>::operator[](size_type i) -> reference
475 {
476 return operator()(i);
477 }
478
485 template <class CT, class I>
486 template <class S>
488 {
489 return m_e[m_indices[index[0]]];
490 }
491
492 template <class CT, class I>
493 template <class OI>
494 inline auto xindex_view<CT, I>::operator[](std::initializer_list<OI> index) const -> const_reference
495 {
496 return m_e[m_indices[*(index.begin())]];
497 }
498
499 template <class CT, class I>
500 inline auto xindex_view<CT, I>::operator[](size_type i) const -> const_reference
501 {
502 return operator()(i);
503 }
504
510 template <class CT, class I>
511 template <class It>
513 {
514 return m_e[m_indices[(*first)]];
515 }
516
522 template <class CT, class I>
523 template <class It>
524 inline auto xindex_view<CT, I>::element(It first, It /*last*/) const -> const_reference
525 {
526 return m_e[m_indices[(*first)]];
527 }
528
532 template <class CT, class I>
533 inline auto xindex_view<CT, I>::expression() noexcept -> xexpression_type&
534 {
535 return m_e;
536 }
537
541 template <class CT, class I>
542 inline auto xindex_view<CT, I>::expression() const noexcept -> const xexpression_type&
543 {
544 return m_e;
545 }
546
548
559 template <class CT, class I>
560 template <class O>
561 inline bool xindex_view<CT, I>::broadcast_shape(O& shape, bool) const
562 {
563 return xt::broadcast_shape(m_shape, shape);
564 }
565
571 template <class CT, class I>
572 template <class O>
573 inline bool xindex_view<CT, I>::has_linear_assign(const O& /*strides*/) const noexcept
574 {
575 return false;
576 }
577
579
580 /***************
581 * stepper api *
582 ***************/
583
584 template <class CT, class I>
585 template <class ST>
586 inline auto xindex_view<CT, I>::stepper_begin(const ST& shape) -> stepper
587 {
588 size_type offset = shape.size() - dimension();
589 return stepper(this, offset);
590 }
591
592 template <class CT, class I>
593 template <class ST>
594 inline auto xindex_view<CT, I>::stepper_end(const ST& shape, layout_type) -> stepper
595 {
596 size_type offset = shape.size() - dimension();
597 return stepper(this, offset, true);
598 }
599
600 template <class CT, class I>
601 template <class ST>
602 inline auto xindex_view<CT, I>::stepper_begin(const ST& shape) const -> const_stepper
603 {
604 size_type offset = shape.size() - dimension();
605 return const_stepper(this, offset);
606 }
607
608 template <class CT, class I>
609 template <class ST>
610 inline auto xindex_view<CT, I>::stepper_end(const ST& shape, layout_type) const -> const_stepper
611 {
612 size_type offset = shape.size() - dimension();
613 return const_stepper(this, offset, true);
614 }
615
616 template <class CT, class I>
617 template <class E>
618 inline auto xindex_view<CT, I>::build_index_view(E&& e) const -> rebind_t<E>
619 {
620 return rebind_t<E>(std::forward<E>(e), indices_type(m_indices));
621 }
622
623 /******************************
624 * xfiltration implementation *
625 ******************************/
626
638 template <class ECT, class CCT>
639 template <class ECTA, class CCTA>
641 : m_e(std::forward<ECTA>(e))
642 , m_condition(std::forward<CCTA>(condition))
643 {
644 }
645
647
657 template <class ECT, class CCT>
658 template <class E>
660 {
661 return apply(
662 [this, &e](const_reference v, bool cond)
663 {
664 return cond ? e : v;
665 }
666 );
667 }
668
670
680 template <class ECT, class CCT>
681 template <class E>
683 {
684 return apply(
685 [&e](const_reference v, bool cond)
686 {
687 return cond ? v + e : v;
688 }
689 );
690 }
691
697 template <class ECT, class CCT>
698 template <class E>
700 {
701 return apply(
702 [&e](const_reference v, bool cond)
703 {
704 return cond ? v - e : v;
705 }
706 );
707 }
708
714 template <class ECT, class CCT>
715 template <class E>
717 {
718 return apply(
719 [&e](const_reference v, bool cond)
720 {
721 return cond ? v * e : v;
722 }
723 );
724 }
725
731 template <class ECT, class CCT>
732 template <class E>
734 {
735 return apply(
736 [&e](const_reference v, bool cond)
737 {
738 return cond ? v / e : v;
739 }
740 );
741 }
742
748 template <class ECT, class CCT>
749 template <class E>
751 {
752 return apply(
753 [&e](const_reference v, bool cond)
754 {
755 return cond ? v % e : v;
756 }
757 );
758 }
759
760 template <class ECT, class CCT>
761 template <class F>
762 inline auto xfiltration<ECT, CCT>::apply(F&& func) -> self_type&
763 {
764 std::transform(m_e.cbegin(), m_e.cend(), m_condition.cbegin(), m_e.begin(), func);
765 return *this;
766 }
767
784 template <class E, class I>
785 inline auto index_view(E&& e, I&& indices) noexcept
786 {
787 using view_type = xindex_view<xclosure_t<E>, std::decay_t<I>>;
788 return view_type(std::forward<E>(e), std::forward<I>(indices));
789 }
790
791 template <class E, std::size_t L>
792 inline auto index_view(E&& e, const xindex (&indices)[L]) noexcept
793 {
794 using view_type = xindex_view<xclosure_t<E>, std::array<xindex, L>>;
795 return view_type(std::forward<E>(e), xt::to_array(indices));
796 }
797
819 template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class E, class O>
820 inline auto filter(E&& e, O&& condition) noexcept
821 {
822 auto indices = argwhere<L>(std::forward<O>(condition));
823 using view_type = xindex_view<xclosure_t<E>, decltype(indices)>;
824 return view_type(std::forward<E>(e), std::move(indices));
825 }
826
844 template <class E, class C>
845 inline auto filtration(E&& e, C&& condition) noexcept
846 {
848 return filtration_type(std::forward<E>(e), std::forward<C>(condition));
849 }
850}
851
852#endif
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
Checks whether the xindex_view can be linearly assigned to an expression with the specified strides.
size_type size() const noexcept
Returns the size of the xindex_view.
reference unchecked(size_type idx)
Returns a reference to the element at the specified position in the xindex_view.
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
Returns a reference to the underlying expression of the view.
bool broadcast_shape(O &shape, bool reuse_cache=false) const
Broadcast the shape of the xindex_view to the specified parameter.
const inner_shape_type & shape() const noexcept
Returns the shape of the xindex_view.
void fill(const T &value)
Fills the view with the given value.
size_type dimension() const noexcept
Returns the number of dimensions of the xindex_view.
Base class for multidimensional iterable expressions.
Implementation of the xsemantic_base interface for multidimensional views.
standard mathematical functions for xexpressions
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.