xtensor
 
Loading...
Searching...
No Matches
xarray.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_ARRAY_HPP
11#define XTENSOR_ARRAY_HPP
12
13#include <algorithm>
14#include <utility>
15
16#include <xtl/xsequence.hpp>
17
18#include "../containers/xbuffer_adaptor.hpp"
19#include "../containers/xcontainer.hpp"
20#include "../core/xsemantic.hpp"
21
22namespace xt
23{
24
25 /********************************
26 * xarray_container declaration *
27 ********************************/
28
29 namespace extension
30 {
31 template <class EC, layout_type L, class SC, class Tag>
33
34 template <class EC, layout_type L, class SC>
36 {
37 using type = xtensor_empty_base;
38 };
39
40 template <class EC, layout_type L, class SC, class Tag>
41 using xarray_container_base_t = typename xarray_container_base<EC, L, SC, Tag>::type;
42 }
43
44 template <class EC, layout_type L, class SC, class Tag>
46 {
47 using storage_type = EC;
48 using reference = inner_reference_t<storage_type>;
49 using const_reference = typename storage_type::const_reference;
50 using size_type = typename storage_type::size_type;
51 using shape_type = SC;
52 using strides_type = get_strides_t<shape_type>;
53 using backstrides_type = get_strides_t<shape_type>;
54 using inner_shape_type = shape_type;
55 using inner_strides_type = strides_type;
56 using inner_backstrides_type = backstrides_type;
57 using temporary_type = xarray_container<EC, L, SC, Tag>;
58 static constexpr layout_type layout = L;
59 };
60
61 template <class EC, layout_type L, class SC, class Tag>
63 : xcontainer_iterable_types<xarray_container<EC, L, SC, Tag>>
64 {
65 };
66
80 template <class EC, layout_type L, class SC, class Tag>
81 class xarray_container : public xstrided_container<xarray_container<EC, L, SC, Tag>>,
82 public xcontainer_semantic<xarray_container<EC, L, SC, Tag>>,
83 public extension::xarray_container_base_t<EC, L, SC, Tag>
84 {
85 public:
86
87 using self_type = xarray_container<EC, L, SC, Tag>;
88 using base_type = xstrided_container<self_type>;
89 using semantic_base = xcontainer_semantic<self_type>;
90 using extension_base = extension::xarray_container_base_t<EC, L, SC, Tag>;
91 using storage_type = typename base_type::storage_type;
92 using allocator_type = typename base_type::allocator_type;
93 using value_type = typename base_type::value_type;
94 using reference = typename base_type::reference;
95 using const_reference = typename base_type::const_reference;
96 using pointer = typename base_type::pointer;
97 using const_pointer = typename base_type::const_pointer;
98 using shape_type = typename base_type::shape_type;
99 using inner_shape_type = typename base_type::inner_shape_type;
100 using strides_type = typename base_type::strides_type;
101 using backstrides_type = typename base_type::backstrides_type;
102 using inner_strides_type = typename base_type::inner_strides_type;
103 using inner_backstrides_type = typename base_type::inner_backstrides_type;
104 using temporary_type = typename semantic_base::temporary_type;
105 using expression_tag = Tag;
106 static constexpr std::size_t rank = SIZE_MAX;
107
109 explicit xarray_container(const shape_type& shape, layout_type l = L);
110 explicit xarray_container(const shape_type& shape, const_reference value, layout_type l = L);
111 explicit xarray_container(const shape_type& shape, const strides_type& strides);
112 explicit xarray_container(const shape_type& shape, const strides_type& strides, const_reference value);
113 explicit xarray_container(storage_type&& storage, inner_shape_type&& shape, inner_strides_type&& strides);
114
115 xarray_container(const value_type& t);
116 xarray_container(nested_initializer_list_t<value_type, 1> t);
117 xarray_container(nested_initializer_list_t<value_type, 2> t);
118 xarray_container(nested_initializer_list_t<value_type, 3> t);
119 xarray_container(nested_initializer_list_t<value_type, 4> t);
120 xarray_container(nested_initializer_list_t<value_type, 5> t);
121
122 template <class S = shape_type>
123 static xarray_container from_shape(S&& s);
124
125 ~xarray_container() = default;
126
127 xarray_container(const xarray_container&) = default;
128 xarray_container& operator=(const xarray_container&) = default;
129
131 xarray_container& operator=(xarray_container&&) = default;
132
133 template <std::size_t N>
135 template <std::size_t N>
137
138 template <class E>
140
141 template <class E>
142 xarray_container& operator=(const xexpression<E>& e);
143
144 private:
145
146 storage_type m_storage;
147
148 storage_type& storage_impl() noexcept;
149 const storage_type& storage_impl() const noexcept;
150
151 friend class xcontainer<xarray_container<EC, L, SC, Tag>>;
152 };
153
154 /******************************
155 * xarray_adaptor declaration *
156 ******************************/
157
158 namespace extension
159 {
160 template <class EC, layout_type L, class SC, class Tag>
162
163 template <class EC, layout_type L, class SC>
165 {
166 using type = xtensor_empty_base;
167 };
168
169 template <class EC, layout_type L, class SC, class Tag>
170 using xarray_adaptor_base_t = typename xarray_adaptor_base<EC, L, SC, Tag>::type;
171 }
172
173 template <class EC, layout_type L, class SC, class Tag>
175 {
176 using storage_type = std::remove_reference_t<EC>;
177 using reference = inner_reference_t<storage_type>;
178 using const_reference = typename storage_type::const_reference;
179 using size_type = typename storage_type::size_type;
180 using shape_type = SC;
181 using strides_type = get_strides_t<shape_type>;
182 using backstrides_type = get_strides_t<shape_type>;
183 using inner_shape_type = shape_type;
184 using inner_strides_type = strides_type;
185 using inner_backstrides_type = backstrides_type;
186 using temporary_type = xarray_container<temporary_container_t<storage_type>, L, SC, Tag>;
187 static constexpr layout_type layout = L;
188 };
189
190 template <class EC, layout_type L, class SC, class Tag>
191 struct xiterable_inner_types<xarray_adaptor<EC, L, SC, Tag>>
192 : xcontainer_iterable_types<xarray_adaptor<EC, L, SC, Tag>>
193 {
194 };
195
212 template <class EC, layout_type L, class SC, class Tag>
213 class xarray_adaptor : public xstrided_container<xarray_adaptor<EC, L, SC, Tag>>,
214 public xcontainer_semantic<xarray_adaptor<EC, L, SC, Tag>>,
215 public extension::xarray_adaptor_base_t<EC, L, SC, Tag>
216 {
217 public:
218
219 using container_closure_type = EC;
220
221 using self_type = xarray_adaptor<EC, L, SC, Tag>;
222 using base_type = xstrided_container<self_type>;
223 using semantic_base = xcontainer_semantic<self_type>;
224 using extension_base = extension::xarray_adaptor_base_t<EC, L, SC, Tag>;
225 using storage_type = typename base_type::storage_type;
226 using allocator_type = typename base_type::allocator_type;
227 using shape_type = typename base_type::shape_type;
228 using strides_type = typename base_type::strides_type;
229 using backstrides_type = typename base_type::backstrides_type;
230 using temporary_type = typename semantic_base::temporary_type;
231 using expression_tag = Tag;
232 static constexpr std::size_t rank = SIZE_MAX;
233
234 xarray_adaptor(storage_type&& storage);
235 xarray_adaptor(const storage_type& storage);
236
237 template <class D>
238 xarray_adaptor(D&& storage, const shape_type& shape, layout_type l = L);
239
240 template <class D>
241 xarray_adaptor(D&& storage, const shape_type& shape, const strides_type& strides);
242
243 ~xarray_adaptor() = default;
244
245 xarray_adaptor(const xarray_adaptor&) = default;
246 xarray_adaptor& operator=(const xarray_adaptor&);
247
248 xarray_adaptor(xarray_adaptor&&) = default;
249 xarray_adaptor& operator=(xarray_adaptor&&);
250 xarray_adaptor& operator=(temporary_type&&);
251
252 template <class E>
253 xarray_adaptor& operator=(const xexpression<E>& e);
254
255 template <class P, class S>
256 void reset_buffer(P&& pointer, S&& size);
257
258 private:
259
260 container_closure_type m_storage;
261
262 storage_type& storage_impl() noexcept;
263 const storage_type& storage_impl() const noexcept;
264
265 friend class xcontainer<xarray_adaptor<EC, L, SC, Tag>>;
266 };
267
268 /***********************************
269 * xarray_container implementation *
270 ***********************************/
271
276
279 template <class EC, layout_type L, class SC, class Tag>
280 inline xarray_container<EC, L, SC, Tag>::xarray_container()
281 : base_type()
282 , m_storage(1, value_type())
283 {
284 }
285
292 template <class EC, layout_type L, class SC, class Tag>
294 : base_type()
295 {
296 base_type::resize(shape, l);
297 }
298
306 template <class EC, layout_type L, class SC, class Tag>
308 const shape_type& shape,
309 const_reference value,
311 )
312 : base_type()
313 {
314 base_type::resize(shape, l);
315 std::fill(m_storage.begin(), m_storage.end(), value);
316 }
317
323 template <class EC, layout_type L, class SC, class Tag>
324 inline xarray_container<EC, L, SC, Tag>::xarray_container(const shape_type& shape, const strides_type& strides)
325 : base_type()
326 {
328 }
329
337 template <class EC, layout_type L, class SC, class Tag>
339 const shape_type& shape,
340 const strides_type& strides,
341 const_reference value
342 )
343 : base_type()
344 {
346 std::fill(m_storage.begin(), m_storage.end(), value);
347 }
348
354 template <class EC, layout_type L, class SC, class Tag>
356 : base_type()
357 {
358 base_type::resize(xt::shape<shape_type>(t), true);
359 nested_copy(m_storage.begin(), t);
360 }
361
369 template <class EC, layout_type L, class SC, class Tag>
371 storage_type&& storage,
372 inner_shape_type&& shape,
373 inner_strides_type&& strides
374 )
375 : base_type(std::move(shape), std::move(strides))
376 , m_storage(std::move(storage))
377 {
378 }
379
381
386
390 template <class EC, layout_type L, class SC, class Tag>
391 inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 1> t)
392 : base_type()
393 {
394 base_type::resize(xt::shape<shape_type>(t));
395 constexpr auto tmp = layout_type::row_major;
396 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
397 }
398
403 template <class EC, layout_type L, class SC, class Tag>
404 inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 2> t)
405 : base_type()
406 {
407 base_type::resize(xt::shape<shape_type>(t));
408 constexpr auto tmp = layout_type::row_major;
409 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
410 }
411
416 template <class EC, layout_type L, class SC, class Tag>
417 inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 3> t)
418 : base_type()
419 {
420 base_type::resize(xt::shape<shape_type>(t));
421 constexpr auto tmp = layout_type::row_major;
422 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
423 }
424
429 template <class EC, layout_type L, class SC, class Tag>
430 inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 4> t)
431 : base_type()
432 {
433 base_type::resize(xt::shape<shape_type>(t));
434 constexpr auto tmp = layout_type::row_major;
435 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
436 }
437
442 template <class EC, layout_type L, class SC, class Tag>
443 inline xarray_container<EC, L, SC, Tag>::xarray_container(nested_initializer_list_t<value_type, 5> t)
444 : base_type()
445 {
446 base_type::resize(xt::shape<shape_type>(t));
447 constexpr auto tmp = layout_type::row_major;
448 L == tmp ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin<tmp>(), t);
449 }
450
452
457 template <class EC, layout_type L, class SC, class Tag>
458 template <class S>
459 inline xarray_container<EC, L, SC, Tag> xarray_container<EC, L, SC, Tag>::from_shape(S&& s)
460 {
461 shape_type shape = xtl::forward_sequence<shape_type, S>(s);
462 return self_type(shape);
463 }
464
465 template <class EC, layout_type L, class SC, class Tag>
466 template <std::size_t N>
468 : base_type(
469 inner_shape_type(rhs.shape().cbegin(), rhs.shape().cend()),
470 inner_strides_type(rhs.strides().cbegin(), rhs.strides().cend()),
471 inner_backstrides_type(rhs.backstrides().cbegin(), rhs.backstrides().cend()),
472 std::move(rhs.layout())
473 )
474 , m_storage(std::move(rhs.storage()))
475 {
476 }
477
478 template <class EC, layout_type L, class SC, class Tag>
479 template <std::size_t N>
480 inline xarray_container<EC, L, SC, Tag>&
481 xarray_container<EC, L, SC, Tag>::operator=(xtensor_container<EC, N, L, Tag>&& rhs)
482 {
483 this->shape_impl().assign(rhs.shape().cbegin(), rhs.shape().cend());
484 this->strides_impl().assign(rhs.strides().cbegin(), rhs.strides().cend());
485 this->backstrides_impl().assign(rhs.backstrides().cbegin(), rhs.backstrides().cend());
486 this->mutable_layout() = rhs.layout();
487 m_storage = std::move(rhs.storage());
488 return *this;
489 }
490
495
498 template <class EC, layout_type L, class SC, class Tag>
499 template <class E>
501 : base_type()
502 {
503 // Avoids unintialized data because of (m_shape == shape) condition
504 // in resize (called by assign), which is always true when dimension == 0.
505 if (e.derived_cast().dimension() == 0)
506 {
507 detail::resize_data_container(m_storage, std::size_t(1));
508 }
509 semantic_base::assign(e);
510 }
511
515 template <class EC, layout_type L, class SC, class Tag>
516 template <class E>
517 inline auto xarray_container<EC, L, SC, Tag>::operator=(const xexpression<E>& e) -> self_type&
518 {
519 return semantic_base::operator=(e);
520 }
521
523
524 template <class EC, layout_type L, class SC, class Tag>
525 inline auto xarray_container<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
526 {
527 return m_storage;
528 }
529
530 template <class EC, layout_type L, class SC, class Tag>
531 inline auto xarray_container<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
532 {
533 return m_storage;
534 }
535
536 /******************
537 * xarray_adaptor *
538 ******************/
539
544
548 template <class EC, layout_type L, class SC, class Tag>
550 : base_type()
551 , m_storage(std::move(storage))
552 {
553 }
554
559 template <class EC, layout_type L, class SC, class Tag>
561 : base_type()
562 , m_storage(storage)
563 {
564 }
565
573 template <class EC, layout_type L, class SC, class Tag>
574 template <class D>
576 : base_type()
577 , m_storage(std::forward<D>(storage))
578 {
579 base_type::resize(shape, l);
580 }
581
589 template <class EC, layout_type L, class SC, class Tag>
590 template <class D>
592 D&& storage,
593 const shape_type& shape,
594 const strides_type& strides
595 )
596 : base_type()
597 , m_storage(std::forward<D>(storage))
598 {
600 }
601
603
604 template <class EC, layout_type L, class SC, class Tag>
605 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(const xarray_adaptor& rhs) -> self_type&
606 {
607 base_type::operator=(rhs);
608 m_storage = rhs.m_storage;
609 return *this;
610 }
611
612 template <class EC, layout_type L, class SC, class Tag>
613 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(xarray_adaptor&& rhs) -> self_type&
614 {
615 base_type::operator=(std::move(rhs));
616 m_storage = rhs.m_storage;
617 return *this;
618 }
619
620 template <class EC, layout_type L, class SC, class Tag>
621 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(temporary_type&& rhs) -> self_type&
622 {
623 base_type::shape_impl() = std::move(const_cast<shape_type&>(rhs.shape()));
624 base_type::strides_impl() = std::move(const_cast<strides_type&>(rhs.strides()));
625 base_type::backstrides_impl() = std::move(const_cast<backstrides_type&>(rhs.backstrides()));
626 m_storage = std::move(rhs.storage());
627 return *this;
628 }
629
634
637 template <class EC, layout_type L, class SC, class Tag>
638 template <class E>
639 inline auto xarray_adaptor<EC, L, SC, Tag>::operator=(const xexpression<E>& e) -> self_type&
640 {
641 return semantic_base::operator=(e);
642 }
643
645
646 template <class EC, layout_type L, class SC, class Tag>
647 inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() noexcept -> storage_type&
648 {
649 return m_storage;
650 }
651
652 template <class EC, layout_type L, class SC, class Tag>
653 inline auto xarray_adaptor<EC, L, SC, Tag>::storage_impl() const noexcept -> const storage_type&
654 {
655 return m_storage;
656 }
657
658 template <class EC, layout_type L, class SC, class Tag>
659 template <class P, class S>
660 inline void xarray_adaptor<EC, L, SC, Tag>::reset_buffer(P&& pointer, S&& size)
661 {
662 return m_storage.reset_data(std::forward<P>(pointer), std::forward<S>(size));
663 }
664}
665
666#endif
Dense multidimensional container adaptor with tensor semantic.
Definition xarray.hpp:216
xarray_adaptor(D &&storage, const shape_type &shape, layout_type l=L)
Constructs an xarray_adaptor of the given stl-like container, with the specified shape and layout_typ...
Definition xarray.hpp:575
xarray_adaptor(D &&storage, const shape_type &shape, const strides_type &strides)
Constructs an xarray_adaptor of the given stl-like container, with the specified shape and strides.
Definition xarray.hpp:591
xarray_adaptor(const storage_type &storage)
Constructs an xarray_adaptor of the given stl-like container.
Definition xarray.hpp:560
xarray_adaptor(storage_type &&storage)
Constructs an xarray_adaptor of the given stl-like container.
Definition xarray.hpp:549
Dense multidimensional container with tensor semantic.
Definition xarray.hpp:84
xarray_container(const shape_type &shape, const strides_type &strides, const_reference value)
Allocates an uninitialized xarray_container with the specified shape and strides.
Definition xarray.hpp:338
xarray_container(const shape_type &shape, const strides_type &strides)
Allocates an uninitialized xarray_container with the specified shape and strides.
Definition xarray.hpp:324
xarray_container(nested_initializer_list_t< value_type, 2 > t)
Allocates a two-dimensional xarray_container.
Definition xarray.hpp:404
xarray_container(nested_initializer_list_t< value_type, 5 > t)
Allocates a five-dimensional xarray_container.
Definition xarray.hpp:443
xarray_container(const shape_type &shape, layout_type l=L)
Allocates an uninitialized xarray_container with the specified shape and layout_type.
Definition xarray.hpp:293
xarray_container(const shape_type &shape, const_reference value, layout_type l=L)
Allocates an xarray_container with the specified shape and layout_type.
Definition xarray.hpp:307
xarray_container(const value_type &t)
Allocates an xarray_container that holds a single element initialized to the specified value.
Definition xarray.hpp:355
xarray_container(nested_initializer_list_t< value_type, 1 > t)
Allocates a one-dimensional xarray_container.
Definition xarray.hpp:391
xarray_container(storage_type &&storage, inner_shape_type &&shape, inner_strides_type &&strides)
Allocates an xarray_container by moving specified data, shape and strides.
Definition xarray.hpp:370
xarray_container(nested_initializer_list_t< value_type, 3 > t)
Allocates a three-dimensional xarray_container.
Definition xarray.hpp:417
xarray_container(nested_initializer_list_t< value_type, 4 > t)
Allocates a four-dimensional xarray_container.
Definition xarray.hpp:430
xarray_container(const xexpression< E > &e)
The extended copy constructor.
Definition xarray.hpp:500
xarray_container()
Allocates an uninitialized xarray_container that holds 0 element.
Definition xarray.hpp:280
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.
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 with tensor semantic and fixed dimension.
Definition xtensor.hpp:86
auto strides(const E &e, stride_type type=stride_type::normal) noexcept
Get strides of an object.
Definition xstrides.hpp:250
standard mathematical functions for xexpressions
layout_type
Definition xlayout.hpp:24