ndarray/
alias_asref.rs

1use crate::{
2    iter::Axes,
3    ArrayBase,
4    Axis,
5    AxisDescription,
6    Dimension,
7    NdIndex,
8    RawArrayView,
9    RawData,
10    RawDataMut,
11    Slice,
12    SliceArg,
13};
14
15/// Functions coming from RawRef
16impl<A, S: RawData<Elem = A>, D: Dimension> ArrayBase<S, D>
17{
18    /// Return a raw pointer to the element at `index`, or return `None`
19    /// if the index is out of bounds.
20    ///
21    /// ```
22    /// use ndarray::arr2;
23    ///
24    /// let a = arr2(&[[1., 2.], [3., 4.]]);
25    ///
26    /// let v = a.raw_view();
27    /// let p = a.get_ptr((0, 1)).unwrap();
28    ///
29    /// assert_eq!(unsafe { *p }, 2.);
30    /// ```
31    pub fn get_ptr<I>(&self, index: I) -> Option<*const A>
32    where I: NdIndex<D>
33    {
34        self.as_raw_ref().get_ptr(index)
35    }
36
37    /// Return a raw pointer to the element at `index`, or return `None`
38    /// if the index is out of bounds.
39    ///
40    /// ```
41    /// use ndarray::arr2;
42    ///
43    /// let mut a = arr2(&[[1., 2.], [3., 4.]]);
44    ///
45    /// let v = a.raw_view_mut();
46    /// let p = a.get_mut_ptr((0, 1)).unwrap();
47    ///
48    /// unsafe {
49    ///     *p = 5.;
50    /// }
51    ///
52    /// assert_eq!(a.get((0, 1)), Some(&5.));
53    /// ```
54    pub fn get_mut_ptr<I>(&mut self, index: I) -> Option<*mut A>
55    where
56        S: RawDataMut<Elem = A>,
57        I: NdIndex<D>,
58    {
59        self.as_raw_ref_mut().get_mut_ptr(index)
60    }
61
62    /// Return a pointer to the first element in the array.
63    ///
64    /// Raw access to array elements needs to follow the strided indexing
65    /// scheme: an element at multi-index *I* in an array with strides *S* is
66    /// located at offset
67    ///
68    /// *Σ<sub>0 ≤ k < d</sub> I<sub>k</sub> × S<sub>k</sub>*
69    ///
70    /// where *d* is `self.ndim()`.
71    #[inline(always)]
72    pub fn as_ptr(&self) -> *const A
73    {
74        self.as_raw_ref().as_ptr()
75    }
76
77    /// Return a raw view of the array.
78    #[inline]
79    pub fn raw_view(&self) -> RawArrayView<S::Elem, D>
80    {
81        self.as_raw_ref().raw_view()
82    }
83}
84
85/// Functions coming from LayoutRef
86impl<S: RawData, D: Dimension> ArrayBase<S, D>
87{
88    /// Slice the array in place without changing the number of dimensions.
89    ///
90    /// In particular, if an axis is sliced with an index, the axis is
91    /// collapsed, as in [`.collapse_axis()`], rather than removed, as in
92    /// [`.slice_move()`] or [`.index_axis_move()`].
93    ///
94    /// [`.collapse_axis()`]: Self::collapse_axis
95    /// [`.slice_move()`]: Self::slice_move
96    /// [`.index_axis_move()`]: Self::index_axis_move
97    ///
98    /// See [*Slicing*](#slicing) for full documentation.
99    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
100    ///
101    /// **Panics** in the following cases:
102    ///
103    /// - if an index is out of bounds
104    /// - if a step size is zero
105    /// - if [`NewAxis`](`crate::SliceInfoElem::NewAxis`) is in `info`, e.g. if `NewAxis` was
106    ///   used in the [`s!`] macro
107    /// - if `D` is `IxDyn` and `info` does not match the number of array axes
108    #[track_caller]
109    pub fn slice_collapse<I>(&mut self, info: I)
110    where I: SliceArg<D>
111    {
112        self.as_layout_ref_mut().slice_collapse(info);
113    }
114
115    /// Slice the array in place along the specified axis.
116    ///
117    /// **Panics** if an index is out of bounds or step size is zero.<br>
118    /// **Panics** if `axis` is out of bounds.
119    #[track_caller]
120    pub fn slice_axis_inplace(&mut self, axis: Axis, indices: Slice)
121    {
122        self.as_layout_ref_mut().slice_axis_inplace(axis, indices);
123    }
124
125    /// Slice the array in place, with a closure specifying the slice for each
126    /// axis.
127    ///
128    /// This is especially useful for code which is generic over the
129    /// dimensionality of the array.
130    ///
131    /// **Panics** if an index is out of bounds or step size is zero.
132    #[track_caller]
133    pub fn slice_each_axis_inplace<F>(&mut self, f: F)
134    where F: FnMut(AxisDescription) -> Slice
135    {
136        self.as_layout_ref_mut().slice_each_axis_inplace(f);
137    }
138
139    /// Selects `index` along the axis, collapsing the axis into length one.
140    ///
141    /// **Panics** if `axis` or `index` is out of bounds.
142    #[track_caller]
143    pub fn collapse_axis(&mut self, axis: Axis, index: usize)
144    {
145        self.as_layout_ref_mut().collapse_axis(axis, index);
146    }
147
148    /// Return `true` if the array data is laid out in contiguous “C order” in
149    /// memory (where the last index is the most rapidly varying).
150    ///
151    /// Return `false` otherwise, i.e. the array is possibly not
152    /// contiguous in memory, it has custom strides, etc.
153    pub fn is_standard_layout(&self) -> bool
154    {
155        self.as_layout_ref().is_standard_layout()
156    }
157
158    /// Return true if the array is known to be contiguous.
159    pub(crate) fn is_contiguous(&self) -> bool
160    {
161        self.as_layout_ref().is_contiguous()
162    }
163
164    /// Return an iterator over the length and stride of each axis.
165    pub fn axes(&self) -> Axes<'_, D>
166    {
167        self.as_layout_ref().axes()
168    }
169
170    /*
171    /// Return the axis with the least stride (by absolute value)
172    pub fn min_stride_axis(&self) -> Axis {
173        self.dim.min_stride_axis(&self.strides)
174    }
175    */
176
177    /// Return the axis with the greatest stride (by absolute value),
178    /// preferring axes with len > 1.
179    pub fn max_stride_axis(&self) -> Axis
180    {
181        self.as_layout_ref().max_stride_axis()
182    }
183
184    /// Reverse the stride of `axis`.
185    ///
186    /// ***Panics*** if the axis is out of bounds.
187    #[track_caller]
188    pub fn invert_axis(&mut self, axis: Axis)
189    {
190        self.as_layout_ref_mut().invert_axis(axis);
191    }
192
193    /// Swap axes `ax` and `bx`.
194    ///
195    /// This does not move any data, it just adjusts the array’s dimensions
196    /// and strides.
197    ///
198    /// **Panics** if the axes are out of bounds.
199    ///
200    /// ```
201    /// use ndarray::arr2;
202    ///
203    /// let mut a = arr2(&[[1., 2., 3.]]);
204    /// a.swap_axes(0, 1);
205    /// assert!(
206    ///     a == arr2(&[[1.], [2.], [3.]])
207    /// );
208    /// ```
209    #[track_caller]
210    pub fn swap_axes(&mut self, ax: usize, bx: usize)
211    {
212        self.as_layout_ref_mut().swap_axes(ax, bx);
213    }
214
215    /// If possible, merge in the axis `take` to `into`.
216    ///
217    /// Returns `true` iff the axes are now merged.
218    ///
219    /// This method merges the axes if movement along the two original axes
220    /// (moving fastest along the `into` axis) can be equivalently represented
221    /// as movement along one (merged) axis. Merging the axes preserves this
222    /// order in the merged axis. If `take` and `into` are the same axis, then
223    /// the axis is "merged" if its length is ≤ 1.
224    ///
225    /// If the return value is `true`, then the following hold:
226    ///
227    /// * The new length of the `into` axis is the product of the original
228    ///   lengths of the two axes.
229    ///
230    /// * The new length of the `take` axis is 0 if the product of the original
231    ///   lengths of the two axes is 0, and 1 otherwise.
232    ///
233    /// If the return value is `false`, then merging is not possible, and the
234    /// original shape and strides have been preserved.
235    ///
236    /// Note that the ordering constraint means that if it's possible to merge
237    /// `take` into `into`, it's usually not possible to merge `into` into
238    /// `take`, and vice versa.
239    ///
240    /// ```
241    /// use ndarray::Array3;
242    /// use ndarray::Axis;
243    ///
244    /// let mut a = Array3::<f64>::zeros((2, 3, 4));
245    /// assert!(a.merge_axes(Axis(1), Axis(2)));
246    /// assert_eq!(a.shape(), &[2, 1, 12]);
247    /// ```
248    ///
249    /// ***Panics*** if an axis is out of bounds.
250    #[track_caller]
251    pub fn merge_axes(&mut self, take: Axis, into: Axis) -> bool
252    {
253        self.as_layout_ref_mut().merge_axes(take, into)
254    }
255
256    /// Return the total number of elements in the array.
257    pub fn len(&self) -> usize
258    {
259        self.as_layout_ref().len()
260    }
261
262    /// Return the length of `axis`.
263    ///
264    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
265    /// number of dimensions (axes) of the array.
266    ///
267    /// ***Panics*** if the axis is out of bounds.
268    #[track_caller]
269    pub fn len_of(&self, axis: Axis) -> usize
270    {
271        self.as_layout_ref().len_of(axis)
272    }
273
274    /// Return whether the array has any elements
275    pub fn is_empty(&self) -> bool
276    {
277        self.as_layout_ref().is_empty()
278    }
279
280    /// Return the number of dimensions (axes) in the array
281    pub fn ndim(&self) -> usize
282    {
283        self.as_layout_ref().ndim()
284    }
285
286    /// Return the shape of the array in its “pattern” form,
287    /// an integer in the one-dimensional case, tuple in the n-dimensional cases
288    /// and so on.
289    pub fn dim(&self) -> D::Pattern
290    {
291        self.as_layout_ref().dim()
292    }
293
294    /// Return the shape of the array as it's stored in the array.
295    ///
296    /// This is primarily useful for passing to other `ArrayBase`
297    /// functions, such as when creating another array of the same
298    /// shape and dimensionality.
299    ///
300    /// ```
301    /// use ndarray::Array;
302    ///
303    /// let a = Array::from_elem((2, 3), 5.);
304    ///
305    /// // Create an array of zeros that's the same shape and dimensionality as `a`.
306    /// let b = Array::<f64, _>::zeros(a.raw_dim());
307    /// ```
308    pub fn raw_dim(&self) -> D
309    {
310        self.as_layout_ref().raw_dim()
311    }
312
313    /// Return the shape of the array as a slice.
314    ///
315    /// Note that you probably don't want to use this to create an array of the
316    /// same shape as another array because creating an array with e.g.
317    /// [`Array::zeros()`](ArrayBase::zeros) using a shape of type `&[usize]`
318    /// results in a dynamic-dimensional array. If you want to create an array
319    /// that has the same shape and dimensionality as another array, use
320    /// [`.raw_dim()`](ArrayBase::raw_dim) instead:
321    ///
322    /// ```rust
323    /// use ndarray::{Array, Array2};
324    ///
325    /// let a = Array2::<i32>::zeros((3, 4));
326    /// let shape = a.shape();
327    /// assert_eq!(shape, &[3, 4]);
328    ///
329    /// // Since `a.shape()` returned `&[usize]`, we get an `ArrayD` instance:
330    /// let b = Array::zeros(shape);
331    /// assert_eq!(a.clone().into_dyn(), b);
332    ///
333    /// // To get the same dimension type, use `.raw_dim()` instead:
334    /// let c = Array::zeros(a.raw_dim());
335    /// assert_eq!(a, c);
336    /// ```
337    pub fn shape(&self) -> &[usize]
338    {
339        self.as_layout_ref().shape()
340    }
341
342    /// Return the strides of the array as a slice.
343    pub fn strides(&self) -> &[isize]
344    {
345        self.as_layout_ref().strides()
346    }
347
348    /// Return the stride of `axis`.
349    ///
350    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
351    /// number of dimensions (axes) of the array.
352    ///
353    /// ***Panics*** if the axis is out of bounds.
354    #[track_caller]
355    pub fn stride_of(&self, axis: Axis) -> isize
356    {
357        self.as_layout_ref().stride_of(axis)
358    }
359}