ndarray/impl_views/
splitting.rs

1// Copyright 2014-2016 bluss and ndarray developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use crate::imp_prelude::*;
10use crate::slice::MultiSliceArg;
11
12/// Methods for read-only array views.
13impl<'a, A, D> ArrayView<'a, A, D>
14where
15    D: Dimension,
16{
17    /// Split the array view along `axis` and return one view strictly before the
18    /// split and one view after the split.
19    ///
20    /// **Panics** if `axis` or `index` is out of bounds.
21    ///
22    /// **Examples:**
23    /// ```rust
24    /// # use ndarray::prelude::*;
25    /// let a = aview2(&[[0, 1, 2, 3],
26    ///                  [4, 5, 6, 7],
27    ///                  [8, 9, 0, 1]]);
28    ///
29    /// ```
30    /// The array view `a` has two axes and shape 3 × 4:
31    /// ```text
32    ///          ──▶ Axis(1)
33    ///         ┌─────┬─────┬─────┬─────┐ 0
34    ///       │ │ a₀₀ │ a₀₁ │ a₀₂ │ a₀₃ │
35    ///       ▼ ├─────┼─────┼─────┼─────┤ 1
36    ///  Axis(0)│ a₁₀ │ a₁₁ │ a₁₂ │ a₁₃ │
37    ///         ├─────┼─────┼─────┼─────┤ 2
38    ///         │ a₂₀ │ a₂₁ │ a₂₂ │ a₂₃ │
39    ///         └─────┴─────┴─────┴─────┘ 3 ↑
40    ///         0     1     2     3     4 ← possible split_at indices.
41    /// ```
42    ///
43    /// Row indices increase along `Axis(0)`, and column indices increase along
44    /// `Axis(1)`. Note that we split “before” an element index, and that
45    /// both 0 and the endpoint are valid split indices.
46    ///
47    /// **Example 1**: Split `a` along the first axis, in this case the rows, at
48    /// index 2.<br>
49    /// This produces views v1 and v2 of shapes 2 × 4 and 1 × 4:
50    ///
51    /// ```rust
52    /// # use ndarray::prelude::*;
53    /// # let a = aview2(&[[0; 4]; 3]);
54    /// let (v1, v2) = a.split_at(Axis(0), 2);
55    /// ```
56    /// ```text
57    ///         ┌─────┬─────┬─────┬─────┐       0  ↓ indices
58    ///         │ a₀₀ │ a₀₁ │ a₀₂ │ a₀₃ │            along Axis(0)
59    ///         ├─────┼─────┼─────┼─────┤ v1    1
60    ///         │ a₁₀ │ a₁₁ │ a₁₂ │ a₁₃ │
61    ///         └─────┴─────┴─────┴─────┘
62    ///         ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄       2
63    ///         ┌─────┬─────┬─────┬─────┐
64    ///         │ a₂₀ │ a₂₁ │ a₂₂ │ a₂₃ │ v2
65    ///         └─────┴─────┴─────┴─────┘       3
66    /// ```
67    ///
68    /// **Example 2**: Split `a` along the second axis, in this case the
69    /// columns, at index 2.<br>
70    /// This produces views u1 and u2 of shapes 3 × 2 and 3 × 2:
71    ///
72    /// ```rust
73    /// # use ndarray::prelude::*;
74    /// # let a = aview2(&[[0; 4]; 3]);
75    /// let (u1, u2) = a.split_at(Axis(1), 2);
76    ///
77    /// ```
78    /// ```text
79    ///              u1             u2
80    ///         ┌─────┬─────┐┊┌─────┬─────┐
81    ///         │ a₀₀ │ a₀₁ │┊│ a₀₂ │ a₀₃ │
82    ///         ├─────┼─────┤┊├─────┼─────┤
83    ///         │ a₁₀ │ a₁₁ │┊│ a₁₂ │ a₁₃ │
84    ///         ├─────┼─────┤┊├─────┼─────┤
85    ///         │ a₂₀ │ a₂₁ │┊│ a₂₂ │ a₂₃ │
86    ///         └─────┴─────┘┊└─────┴─────┘
87    ///         0     1      2      3     4  indices →
88    ///                                      along Axis(1)
89    /// ```
90    pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) {
91        unsafe {
92            let (left, right) = self.into_raw_view().split_at(axis, index);
93            (left.deref_into_view(), right.deref_into_view())
94        }
95    }
96}
97
98/// Methods for read-write array views.
99impl<'a, A, D> ArrayViewMut<'a, A, D>
100where
101    D: Dimension,
102{
103    /// Split the array view along `axis` and return one mutable view strictly
104    /// before the split and one mutable view after the split.
105    ///
106    /// **Panics** if `axis` or `index` is out of bounds.
107    pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) {
108        unsafe {
109            let (left, right) = self.into_raw_view_mut().split_at(axis, index);
110            (left.deref_into_view_mut(), right.deref_into_view_mut())
111        }
112    }
113
114    /// Split the view into multiple disjoint slices.
115    ///
116    /// This is similar to [`.multi_slice_mut()`], but `.multi_slice_move()`
117    /// consumes `self` and produces views with lifetimes matching that of
118    /// `self`.
119    ///
120    /// See [*Slicing*](#slicing) for full documentation. See also
121    /// [`MultiSliceArg`], [`s!`], [`SliceArg`](crate::SliceArg), and
122    /// [`SliceInfo`](crate::SliceInfo).
123    ///
124    /// [`.multi_slice_mut()`]: struct.ArrayBase.html#method.multi_slice_mut
125    ///
126    /// **Panics** if any of the following occur:
127    ///
128    /// * if any of the views would intersect (i.e. if any element would appear in multiple slices)
129    /// * if an index is out of bounds or step size is zero
130    /// * if `D` is `IxDyn` and `info` does not match the number of array axes
131    pub fn multi_slice_move<M>(self, info: M) -> M::Output
132    where
133        M: MultiSliceArg<'a, A, D>,
134    {
135        info.multi_slice_move(self)
136    }
137}