xtensor
Loading...
Searching...
No Matches
xtensor.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_TENSOR_HPP
11#define XTENSOR_TENSOR_HPP
12
13#include <algorithm>
14#include <array>
15#include <cstddef>
16#include <utility>
17#include <vector>
18
19#include "xbuffer_adaptor.hpp"
20#include "xcontainer.hpp"
21#include "xsemantic.hpp"
22
23namespace xt
24{
25
26 /***********************
27 * xtensor declaration *
28 ***********************/
29
30 namespace extension
31 {
32 template <class EC, std::size_t N, layout_type L, class Tag>
34
35 template <class EC, std::size_t N, layout_type L>
40
41 template <class EC, std::size_t N, layout_type L, class Tag>
42 using xtensor_container_base_t = typename xtensor_container_base<EC, N, L, Tag>::type;
43 }
44
45 template <class EC, std::size_t N, layout_type L, class Tag>
47 {
48 using storage_type = EC;
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>;
55 using inner_shape_type = shape_type;
59 static constexpr layout_type layout = L;
60 };
61
62 template <class EC, std::size_t N, layout_type L, class Tag>
64 : xcontainer_iterable_types<xtensor_container<EC, N, L, Tag>>
65 {
66 };
67
82 template <class EC, std::size_t N, layout_type L, class Tag>
83 class xtensor_container : public xstrided_container<xtensor_container<EC, N, L, Tag>>,
84 public xcontainer_semantic<xtensor_container<EC, N, L, Tag>>,
85 public extension::xtensor_container_base_t<EC, N, L, Tag>
86 {
87 public:
88
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;
109
112 explicit xtensor_container(const shape_type& shape, layout_type l = L);
113 explicit xtensor_container(const shape_type& shape, const_reference value, layout_type l = L);
114 explicit xtensor_container(const shape_type& shape, const strides_type& strides);
115 explicit xtensor_container(const shape_type& shape, const strides_type& strides, const_reference value);
116 explicit xtensor_container(storage_type&& storage, inner_shape_type&& shape, inner_strides_type&& strides);
117
118 template <class S = shape_type>
119 static xtensor_container from_shape(S&& s);
120
121 ~xtensor_container() = default;
122
123 xtensor_container(const xtensor_container&) = default;
124 xtensor_container& operator=(const xtensor_container&) = default;
125
127 xtensor_container& operator=(xtensor_container&&) = default;
128
129 template <class SC>
131 template <class SC>
133
134 template <class E>
136
137 template <class E>
138 xtensor_container& operator=(const xexpression<E>& e);
139
140 private:
141
142 storage_type m_storage;
143
144 storage_type& storage_impl() noexcept;
145 const storage_type& storage_impl() const noexcept;
146
147 friend class xcontainer<xtensor_container<EC, N, L, Tag>>;
148 };
149
150 /*****************************************
151 * xtensor_container_adaptor declaration *
152 *****************************************/
153
154 namespace extension
155 {
156 template <class EC, std::size_t N, layout_type L, class Tag>
158
159 template <class EC, std::size_t N, layout_type L>
164
165 template <class EC, std::size_t N, layout_type L, class Tag>
166 using xtensor_adaptor_base_t = typename xtensor_adaptor_base<EC, N, L, Tag>::type;
167 }
168
169 template <class EC, std::size_t N, layout_type L, class Tag>
171 {
172 using storage_type = std::remove_reference_t<EC>;
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>;
179 using inner_shape_type = shape_type;
183 static constexpr layout_type layout = L;
184 };
185
186 template <class EC, std::size_t N, layout_type L, class Tag>
188 : xcontainer_iterable_types<xtensor_adaptor<EC, N, L, Tag>>
189 {
190 };
191
208 template <class EC, std::size_t N, layout_type L, class Tag>
209 class xtensor_adaptor : public xstrided_container<xtensor_adaptor<EC, N, L, Tag>>,
210 public xcontainer_semantic<xtensor_adaptor<EC, N, L, Tag>>,
211 public extension::xtensor_adaptor_base_t<EC, N, L, Tag>
212 {
213 public:
214
216
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;
229
230 xtensor_adaptor(storage_type&& storage);
231 xtensor_adaptor(const storage_type& storage);
232
233 template <class D>
234 xtensor_adaptor(D&& storage, const shape_type& shape, layout_type l = L);
235
236 template <class D>
237 xtensor_adaptor(D&& storage, const shape_type& shape, const strides_type& strides);
238
239 ~xtensor_adaptor() = default;
240
241 xtensor_adaptor(const xtensor_adaptor&) = default;
242 xtensor_adaptor& operator=(const xtensor_adaptor&);
243
244 xtensor_adaptor(xtensor_adaptor&&) = default;
245 xtensor_adaptor& operator=(xtensor_adaptor&&);
246 xtensor_adaptor& operator=(temporary_type&&);
247
248 template <class E>
249 xtensor_adaptor& operator=(const xexpression<E>& e);
250
251 template <class P, class S>
252 void reset_buffer(P&& pointer, S&& size);
253
254 private:
255
256 container_closure_type m_storage;
257
258 storage_type& storage_impl() noexcept;
259 const storage_type& storage_impl() const noexcept;
260
261 friend class xcontainer<xtensor_adaptor<EC, N, L, Tag>>;
262 };
263
264 /****************************
265 * xtensor_view declaration *
266 ****************************/
267
268 template <class EC, std::size_t N, layout_type L, class Tag>
269 class xtensor_view;
270
271 namespace extension
272 {
273 template <class EC, std::size_t N, layout_type L, class Tag>
275
276 template <class EC, std::size_t N, layout_type L>
278 {
279 using type = xtensor_empty_base;
280 };
281
282 template <class EC, std::size_t N, layout_type L, class Tag>
283 using xtensor_view_base_t = typename xtensor_view_base<EC, N, L, Tag>::type;
284 }
285
286 template <class EC, std::size_t N, layout_type L, class Tag>
288 {
289 using storage_type = std::remove_reference_t<EC>;
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>;
296 using inner_shape_type = shape_type;
300 static constexpr layout_type layout = L;
301 };
302
303 template <class EC, std::size_t N, layout_type L, class Tag>
305 : xcontainer_iterable_types<xtensor_view<EC, N, L, Tag>>
306 {
307 };
308
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>
329 {
330 public:
331
333
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;
345
346 xtensor_view(storage_type&& storage);
347 xtensor_view(const storage_type& storage);
348
349 template <class D>
350 xtensor_view(D&& storage, const shape_type& shape, layout_type l = L);
351
352 template <class D>
353 xtensor_view(D&& storage, const shape_type& shape, const strides_type& strides);
354
355 ~xtensor_view() = default;
356
357 xtensor_view(const xtensor_view&) = default;
358 xtensor_view& operator=(const xtensor_view&);
359
360 xtensor_view(xtensor_view&&) = default;
361 xtensor_view& operator=(xtensor_view&&);
362
363 template <class E>
364 self_type& operator=(const xexpression<E>& e);
365
366 template <class E>
367 disable_xexpression<E, self_type>& operator=(const E& e);
368
369 private:
370
371 container_closure_type m_storage;
372
373 storage_type& storage_impl() noexcept;
374 const storage_type& storage_impl() const noexcept;
375
376 void assign_temporary_impl(temporary_type&& tmp);
377
378 friend class xcontainer<xtensor_view<EC, N, L, Tag>>;
379 friend class xview_semantic<xtensor_view<EC, N, L, Tag>>;
380 };
381
382 namespace detail
383 {
384 template <class V>
385 struct tensor_view_simd_helper
386 {
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>;
391 };
392 }
393
394 // xtensor_view can be used on pseudo containers, i.e. containers
395 // whose access operator does not return a reference. Since it
396 // is not possible to take the address f a temporary, the load_simd
397 // method implementation leads to a compilation error.
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
401 {
402 };
403
404 /************************************
405 * xtensor_container implementation *
406 ************************************/
407
415 template <class EC, std::size_t N, layout_type L, class Tag>
417 : base_type()
418 , m_storage(N == 0 ? 1 : 0, value_type())
419 {
420 }
421
425 template <class EC, std::size_t N, layout_type L, class Tag>
427 : base_type()
428 {
430 constexpr auto tmp = layout_type::row_major;
431 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
432 }
433
440 template <class EC, std::size_t N, layout_type L, class Tag>
442 : base_type()
443 {
445 }
446
454 template <class EC, std::size_t N, layout_type L, class Tag>
456 const shape_type& shape,
457 const_reference value,
459 )
460 : base_type()
461 {
463 std::fill(m_storage.begin(), m_storage.end(), value);
464 }
465
471 template <class EC, std::size_t N, layout_type L, class Tag>
472 inline xtensor_container<EC, N, L, Tag>::xtensor_container(const shape_type& shape, const strides_type& strides)
473 : base_type()
474 {
476 }
477
485 template <class EC, std::size_t N, layout_type L, class Tag>
487 const shape_type& shape,
488 const strides_type& strides,
489 const_reference value
490 )
491 : base_type()
492 {
494 std::fill(m_storage.begin(), m_storage.end(), value);
495 }
496
504 template <class EC, std::size_t N, layout_type L, class Tag>
506 storage_type&& storage,
507 inner_shape_type&& shape,
508 inner_strides_type&& strides
509 )
510 : base_type(std::move(shape), std::move(strides))
511 , m_storage(std::move(storage))
512 {
513 }
514
515 template <class EC, std::size_t N, layout_type L, class Tag>
516 template <class SC>
518 : base_type(
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())
523 )
524 , m_storage(std::move(rhs.storage()))
525 {
526 }
527
528 template <class EC, std::size_t N, layout_type L, class Tag>
529 template <class SC>
530 inline xtensor_container<EC, N, L, Tag>&
531 xtensor_container<EC, N, L, Tag>::operator=(xarray_container<EC, L, SC, Tag>&& rhs)
532 {
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()));
539 return *this;
540 }
541
542 template <class EC, std::size_t N, layout_type L, class Tag>
543 template <class S>
544 inline xtensor_container<EC, N, L, Tag> xtensor_container<EC, N, L, Tag>::from_shape(S&& s)
545 {
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);
549 }
550
552
560 template <class EC, std::size_t N, layout_type L, class Tag>
561 template <class E>
563 : base_type()
564 {
565 XTENSOR_ASSERT_MSG(N == e.derived_cast().dimension(), "Cannot change dimension of xtensor.");
566 // Avoids uninitialized data because of (m_shape == shape) condition
567 // in resize (called by assign), which is always true when dimension() == 0.
568 if (e.derived_cast().dimension() == 0)
569 {
570 detail::resize_data_container(m_storage, std::size_t(1));
571 }
572 semantic_base::assign(e);
573 }
574
578 template <class EC, std::size_t N, layout_type L, class Tag>
579 template <class E>
581 {
582 return semantic_base::operator=(e);
583 }
584
586
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&
589 {
590 return m_storage;
591 }
592
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&
595 {
596 return m_storage;
597 }
598
599 /**********************************
600 * xtensor_adaptor implementation *
601 **********************************/
602
611 template <class EC, std::size_t N, layout_type L, class Tag>
613 : base_type()
614 , m_storage(std::move(storage))
615 {
616 }
617
622 template <class EC, std::size_t N, layout_type L, class Tag>
623 inline xtensor_adaptor<EC, N, L, Tag>::xtensor_adaptor(const storage_type& storage)
624 : base_type()
625 , m_storage(storage)
626 {
627 }
628
636 template <class EC, std::size_t N, layout_type L, class Tag>
637 template <class D>
638 inline xtensor_adaptor<EC, N, L, Tag>::xtensor_adaptor(D&& storage, const shape_type& shape, layout_type l)
639 : base_type()
640 , m_storage(std::forward<D>(storage))
641 {
643 }
644
652 template <class EC, std::size_t N, layout_type L, class Tag>
653 template <class D>
655 D&& storage,
656 const shape_type& shape,
657 const strides_type& strides
658 )
659 : base_type()
660 , m_storage(std::forward<D>(storage))
661 {
663 }
664
666
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&
669 {
670 base_type::operator=(rhs);
671 m_storage = rhs.m_storage;
672 return *this;
673 }
674
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&
677 {
678 base_type::operator=(std::move(rhs));
679 m_storage = rhs.m_storage;
680 return *this;
681 }
682
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&
685 {
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());
690 return *this;
691 }
692
700 template <class EC, std::size_t N, layout_type L, class Tag>
701 template <class E>
703 {
704 return semantic_base::operator=(e);
705 }
706
708
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&
711 {
712 return m_storage;
713 }
714
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&
717 {
718 return m_storage;
719 }
720
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)
724 {
725 return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
726 }
727
728 /*******************************
729 * xtensor_view implementation *
730 *******************************/
731
740 template <class EC, std::size_t N, layout_type L, class Tag>
741 inline xtensor_view<EC, N, L, Tag>::xtensor_view(storage_type&& storage)
742 : base_type()
743 , m_storage(std::move(storage))
744 {
745 }
746
751 template <class EC, std::size_t N, layout_type L, class Tag>
752 inline xtensor_view<EC, N, L, Tag>::xtensor_view(const storage_type& storage)
753 : base_type()
754 , m_storage(storage)
755 {
756 }
757
765 template <class EC, std::size_t N, layout_type L, class Tag>
766 template <class D>
767 inline xtensor_view<EC, N, L, Tag>::xtensor_view(D&& storage, const shape_type& shape, layout_type l)
768 : base_type()
769 , m_storage(std::forward<D>(storage))
770 {
772 }
773
781 template <class EC, std::size_t N, layout_type L, class Tag>
782 template <class D>
783 inline xtensor_view<EC, N, L, Tag>::xtensor_view(D&& storage, const shape_type& shape, const strides_type& strides)
784 : base_type()
785 , m_storage(std::forward<D>(storage))
786 {
788 }
789
791
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&
794 {
795 base_type::operator=(rhs);
796 m_storage = rhs.m_storage;
797 return *this;
798 }
799
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&
802 {
803 base_type::operator=(std::move(rhs));
804 m_storage = rhs.m_storage;
805 return *this;
806 }
807
815 template <class EC, std::size_t N, layout_type L, class Tag>
816 template <class E>
818 {
819 return semantic_base::operator=(e);
820 }
821
823
824 template <class EC, std::size_t N, layout_type L, class Tag>
825 template <class E>
827 {
828 std::fill(m_storage.begin(), m_storage.end(), e);
829 return *this;
830 }
831
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&
834 {
835 return m_storage;
836 }
837
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&
840 {
841 return m_storage;
842 }
843
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)
846 {
847 std::copy(tmp.cbegin(), tmp.cend(), m_storage.begin());
848 }
849
857 template <class T>
858 inline auto from_indices(const std::vector<T>& idx)
859 {
860 using return_type = xtensor<typename T::value_type, 2>;
861 using size_type = typename return_type::size_type;
862
863 if (idx.size() == 0)
864 {
865 return return_type::from_shape({size_type(0), size_type(0)});
866 }
867
868 return_type out = return_type::from_shape({idx.size(), idx[0].size()});
869
870 for (size_type i = 0; i < out.shape()[0]; ++i)
871 {
872 for (size_type j = 0; j < out.shape()[1]; ++j)
873 {
874 out(i, j) = idx[i][j];
875 }
876 }
877
878 return out;
879 }
880
889 template <class T>
890 inline auto flatten_indices(const std::vector<T>& idx)
891 {
892 auto n = idx.size();
893 if (n != 0)
894 {
895 n *= idx[0].size();
896 }
897
898 using return_type = xtensor<typename T::value_type, 1>;
899 return_type out = return_type::from_shape({n});
900 auto iter = out.begin();
901 for_each(
902 idx.begin(),
903 idx.end(),
904 [&iter](const auto& t)
905 {
906 iter = std::copy(t.cbegin(), t.cend(), iter);
907 }
908 );
909
910 return out;
911 }
912
913 struct ravel_vector_tag;
914 struct ravel_tensor_tag;
915
916 namespace detail
917 {
918 template <class C, class Tag>
919 struct ravel_return_type;
920
921 template <class C>
922 struct ravel_return_type<C, ravel_vector_tag>
923 {
924 using index_type = typename C::value_type;
925 using value_type = typename index_type::value_type;
926 using type = std::vector<value_type>;
927
928 template <class T>
929 static std::vector<value_type> init(T n)
930 {
931 return std::vector<value_type>(n);
932 }
933 };
934
935 template <class C>
936 struct ravel_return_type<C, ravel_tensor_tag>
937 {
938 using index_type = typename C::value_type;
939 using value_type = typename index_type::value_type;
940 using type = xt::xtensor<value_type, 1>;
941
942 template <class T>
943 static xt::xtensor<value_type, 1> init(T n)
944 {
945 return xtensor<value_type, 1>::from_shape({n});
946 }
947 };
948 }
949
950 template <class C, class Tag>
951 using ravel_return_type_t = typename detail::ravel_return_type<C, Tag>::type;
952
963 template <class Tag = ravel_tensor_tag, class C, class S>
964 ravel_return_type_t<C, Tag>
966 {
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);
971 compute_strides(shape, l, strides);
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)
976 {
977 *out_iter = element_offset<value_type>(strides, (*idx_iter).cbegin(), (*idx_iter).cend());
978 }
979 return out;
980 }
981}
982
983#endif
Implementation of the xsemantic_base interface for dense multidimensional containers.
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 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.
Partial implementation of xcontainer that embeds the strides and the shape.
void resize(S &&shape, bool force=false)
Resizes the container.
Dense multidimensional container adaptor with tensor semantics and fixed dimension.
Definition xtensor.hpp:212
xtensor_adaptor(storage_type &&storage)
Constructs an xtensor_adaptor of the given stl-like container.
Definition xtensor.hpp:612
Dense multidimensional container with tensor semantic and fixed dimension.
Definition xtensor.hpp:86
xtensor_container()
Allocates an uninitialized xtensor_container that holds 0 elements.
Definition xtensor.hpp:416
Dense multidimensional container adaptor with view semantics and fixed dimension.
Definition xtensor.hpp:329
xtensor_view(storage_type &&storage)
Constructs an xtensor_view of the given stl-like container.
Definition xtensor.hpp:741
Implementation of the xsemantic_base interface for multidimensional views.
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.
Definition xstrides.hpp:566
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
Definition xstrides.hpp:248
standard mathematical functions for xexpressions
layout_type
Definition xlayout.hpp:24
auto flatten_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.
Definition xtensor.hpp:890
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.
Definition xtensor.hpp:965
auto from_indices(const std::vector< T > &idx)
Converts std::vector<index_type> (returned e.g.
Definition xtensor.hpp:858