ndarray/
impl_methods.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 alloc::slice;
10use alloc::vec;
11#[cfg(not(feature = "std"))]
12use alloc::vec::Vec;
13#[allow(unused_imports)]
14use rawpointer::PointerExt;
15use std::mem::{size_of, ManuallyDrop};
16
17use crate::imp_prelude::*;
18
19use crate::argument_traits::AssignElem;
20use crate::dimension;
21use crate::dimension::broadcast::co_broadcast;
22use crate::dimension::reshape_dim;
23use crate::dimension::IntoDimension;
24use crate::dimension::{
25    abs_index,
26    axes_of,
27    do_slice,
28    merge_axes,
29    move_min_stride_axis_to_last,
30    offset_from_low_addr_ptr_to_logical_ptr,
31    size_of_shape_checked,
32    stride_offset,
33    Axes,
34};
35use crate::error::{self, from_kind, ErrorKind, ShapeError};
36use crate::itertools::zip;
37use crate::math_cell::MathCell;
38use crate::order::Order;
39use crate::shape_builder::ShapeArg;
40use crate::zip::{IntoNdProducer, Zip};
41use crate::ArrayRef;
42use crate::AxisDescription;
43use crate::LayoutRef;
44use crate::RawRef;
45use crate::{arraytraits, DimMax};
46
47use crate::iter::{
48    AxisChunksIter,
49    AxisChunksIterMut,
50    AxisIter,
51    AxisIterMut,
52    AxisWindows,
53    ExactChunks,
54    ExactChunksMut,
55    IndexedIter,
56    IndexedIterMut,
57    Iter,
58    IterMut,
59    Lanes,
60    LanesMut,
61    Windows,
62};
63use crate::slice::{MultiSliceArg, SliceArg};
64use crate::stacking::concatenate;
65use crate::{NdIndex, Slice, SliceInfoElem};
66
67/// # Methods For All Array Types
68impl<A, D: Dimension> LayoutRef<A, D>
69{
70    /// Return the total number of elements in the array.
71    pub fn len(&self) -> usize
72    {
73        self._dim().size()
74    }
75
76    /// Return the length of `axis`.
77    ///
78    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
79    /// number of dimensions (axes) of the array.
80    ///
81    /// ***Panics*** if the axis is out of bounds.
82    #[track_caller]
83    pub fn len_of(&self, axis: Axis) -> usize
84    {
85        self._dim()[axis.index()]
86    }
87
88    /// Return whether the array has any elements
89    pub fn is_empty(&self) -> bool
90    {
91        self.len() == 0
92    }
93
94    /// Return the number of dimensions (axes) in the array
95    pub fn ndim(&self) -> usize
96    {
97        self._dim().ndim()
98    }
99
100    /// Return the shape of the array in its “pattern” form,
101    /// an integer in the one-dimensional case, tuple in the n-dimensional cases
102    /// and so on.
103    pub fn dim(&self) -> D::Pattern
104    {
105        self._dim().clone().into_pattern()
106    }
107
108    /// Return the shape of the array as it's stored in the array.
109    ///
110    /// This is primarily useful for passing to other `ArrayBase`
111    /// functions, such as when creating another array of the same
112    /// shape and dimensionality.
113    ///
114    /// ```
115    /// use ndarray::Array;
116    ///
117    /// let a = Array::from_elem((2, 3), 5.);
118    ///
119    /// // Create an array of zeros that's the same shape and dimensionality as `a`.
120    /// let b = Array::<f64, _>::zeros(a.raw_dim());
121    /// ```
122    pub fn raw_dim(&self) -> D
123    {
124        self._dim().clone()
125    }
126
127    /// Return the shape of the array as a slice.
128    ///
129    /// Note that you probably don't want to use this to create an array of the
130    /// same shape as another array because creating an array with e.g.
131    /// [`Array::zeros()`](ArrayBase::zeros) using a shape of type `&[usize]`
132    /// results in a dynamic-dimensional array. If you want to create an array
133    /// that has the same shape and dimensionality as another array, use
134    /// [`.raw_dim()`](ArrayBase::raw_dim) instead:
135    ///
136    /// ```rust
137    /// use ndarray::{Array, Array2};
138    ///
139    /// let a = Array2::<i32>::zeros((3, 4));
140    /// let shape = a.shape();
141    /// assert_eq!(shape, &[3, 4]);
142    ///
143    /// // Since `a.shape()` returned `&[usize]`, we get an `ArrayD` instance:
144    /// let b = Array::zeros(shape);
145    /// assert_eq!(a.clone().into_dyn(), b);
146    ///
147    /// // To get the same dimension type, use `.raw_dim()` instead:
148    /// let c = Array::zeros(a.raw_dim());
149    /// assert_eq!(a, c);
150    /// ```
151    pub fn shape(&self) -> &[usize]
152    {
153        self._dim().slice()
154    }
155
156    /// Return the strides of the array as a slice.
157    pub fn strides(&self) -> &[isize]
158    {
159        let s = self._strides().slice();
160        // reinterpret unsigned integer as signed
161        unsafe { slice::from_raw_parts(s.as_ptr() as *const _, s.len()) }
162    }
163
164    /// Return the stride of `axis`.
165    ///
166    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
167    /// number of dimensions (axes) of the array.
168    ///
169    /// ***Panics*** if the axis is out of bounds.
170    #[track_caller]
171    pub fn stride_of(&self, axis: Axis) -> isize
172    {
173        // strides are reinterpreted as isize
174        self._strides()[axis.index()] as isize
175    }
176}
177
178impl<A, D: Dimension> ArrayRef<A, D>
179{
180    /// Return a read-only view of the array
181    pub fn view(&self) -> ArrayView<'_, A, D>
182    {
183        // debug_assert!(self.pointer_is_inbounds());
184        unsafe { ArrayView::new(*self._ptr(), self._dim().clone(), self._strides().clone()) }
185    }
186
187    /// Return a read-write view of the array
188    pub fn view_mut(&mut self) -> ArrayViewMut<'_, A, D>
189    {
190        unsafe { ArrayViewMut::new(*self._ptr(), self._dim().clone(), self._strides().clone()) }
191    }
192
193    /// Return a shared view of the array with elements as if they were embedded in cells.
194    ///
195    /// The cell view requires a mutable borrow of the array. Once borrowed the
196    /// cell view itself can be copied and accessed without exclusivity.
197    ///
198    /// The view acts "as if" the elements are temporarily in cells, and elements
199    /// can be changed through shared references using the regular cell methods.
200    pub fn cell_view(&mut self) -> ArrayView<'_, MathCell<A>, D>
201    {
202        self.view_mut().into_cell_view()
203    }
204
205    /// Return an uniquely owned copy of the array.
206    ///
207    /// If the input array is contiguous, then the output array will have the same
208    /// memory layout. Otherwise, the layout of the output array is unspecified.
209    /// If you need a particular layout, you can allocate a new array with the
210    /// desired memory layout and [`.assign()`](Self::assign) the data.
211    /// Alternatively, you can collect an iterator, like this for a result in
212    /// standard layout:
213    ///
214    /// ```
215    /// # use ndarray::prelude::*;
216    /// # let arr = Array::from_shape_vec((2, 2).f(), vec![1, 2, 3, 4]).unwrap();
217    /// # let owned = {
218    /// Array::from_shape_vec(arr.raw_dim(), arr.iter().cloned().collect()).unwrap()
219    /// # };
220    /// # assert!(owned.is_standard_layout());
221    /// # assert_eq!(arr, owned);
222    /// ```
223    ///
224    /// or this for a result in column-major (Fortran) layout:
225    ///
226    /// ```
227    /// # use ndarray::prelude::*;
228    /// # let arr = Array::from_shape_vec((2, 2), vec![1, 2, 3, 4]).unwrap();
229    /// # let owned = {
230    /// Array::from_shape_vec(arr.raw_dim().f(), arr.t().iter().cloned().collect()).unwrap()
231    /// # };
232    /// # assert!(owned.t().is_standard_layout());
233    /// # assert_eq!(arr, owned);
234    /// ```
235    pub fn to_owned(&self) -> Array<A, D>
236    where A: Clone
237    {
238        if let Some(slc) = self.as_slice_memory_order() {
239            unsafe {
240                Array::from_shape_vec_unchecked(self._dim().clone().strides(self._strides().clone()), slc.to_vec())
241            }
242        } else {
243            self.map(A::clone)
244        }
245    }
246}
247
248impl<A, S, D> ArrayBase<S, D>
249where
250    S: RawData<Elem = A>,
251    D: Dimension,
252{
253    /// Return an uniquely owned copy of the array.
254    ///
255    /// If the input array is contiguous, then the output array will have the same
256    /// memory layout. Otherwise, the layout of the output array is unspecified.
257    /// If you need a particular layout, you can allocate a new array with the
258    /// desired memory layout and [`.assign()`](ArrayRef::assign) the data.
259    /// Alternatively, you can collectan iterator, like this for a result in
260    /// standard layout:
261    ///
262    /// ```
263    /// # use ndarray::prelude::*;
264    /// # let arr = Array::from_shape_vec((2, 2).f(), vec![1, 2, 3, 4]).unwrap();
265    /// # let owned = {
266    /// Array::from_shape_vec(arr.raw_dim(), arr.iter().cloned().collect()).unwrap()
267    /// # };
268    /// # assert!(owned.is_standard_layout());
269    /// # assert_eq!(arr, owned);
270    /// ```
271    ///
272    /// or this for a result in column-major (Fortran) layout:
273    ///
274    /// ```
275    /// # use ndarray::prelude::*;
276    /// # let arr = Array::from_shape_vec((2, 2), vec![1, 2, 3, 4]).unwrap();
277    /// # let owned = {
278    /// Array::from_shape_vec(arr.raw_dim().f(), arr.t().iter().cloned().collect()).unwrap()
279    /// # };
280    /// # assert!(owned.t().is_standard_layout());
281    /// # assert_eq!(arr, owned);
282    /// ```
283    pub fn to_owned(&self) -> Array<A, D>
284    where
285        A: Clone,
286        S: Data,
287    {
288        (**self).to_owned()
289    }
290
291    /// Return a shared ownership (copy on write) array, cloning the array
292    /// elements if necessary.
293    pub fn to_shared(&self) -> ArcArray<A, D>
294    where
295        A: Clone,
296        S: Data,
297    {
298        S::to_shared(self)
299    }
300
301    /// Turn the array into a uniquely owned array, cloning the array elements
302    /// if necessary.
303    pub fn into_owned(self) -> Array<A, D>
304    where
305        A: Clone,
306        S: Data,
307    {
308        S::into_owned(self)
309    }
310
311    /// Converts the array into `Array<A, D>` if this is possible without
312    /// cloning the array elements. Otherwise, returns `self` unchanged.
313    ///
314    /// ```
315    /// use ndarray::{array, rcarr2, ArcArray2, Array2};
316    ///
317    /// // Reference-counted, clone-on-write `ArcArray`.
318    /// let a: ArcArray2<_> = rcarr2(&[[1., 2.], [3., 4.]]);
319    /// {
320    ///     // Another reference to the same data.
321    ///     let b: ArcArray2<_> = a.clone();
322    ///     // Since there are two references to the same data, `.into_owned()`
323    ///     // would require cloning the data, so `.try_into_owned_nocopy()`
324    ///     // returns `Err`.
325    ///     assert!(b.try_into_owned_nocopy().is_err());
326    /// }
327    /// // Here, since the second reference has been dropped, the `ArcArray`
328    /// // can be converted into an `Array` without cloning the data.
329    /// let unique: Array2<_> = a.try_into_owned_nocopy().unwrap();
330    /// assert_eq!(unique, array![[1., 2.], [3., 4.]]);
331    /// ```
332    pub fn try_into_owned_nocopy(self) -> Result<Array<A, D>, Self>
333    where S: Data
334    {
335        S::try_into_owned_nocopy(self)
336    }
337
338    /// Turn the array into a shared ownership (copy on write) array,
339    /// cloning the array elements if necessary.
340    ///
341    /// If you want to generalize over `Array` and `ArcArray` inputs but avoid
342    /// an `A: Clone` bound, use `Into::<ArcArray<A, D>>::into` instead of this
343    /// method.
344    pub fn into_shared(self) -> ArcArray<A, D>
345    where
346        A: Clone,
347        S: DataOwned,
348    {
349        S::into_shared(self)
350    }
351}
352
353impl<A, D: Dimension> ArrayRef<A, D>
354{
355    /// Returns a reference to the first element of the array, or `None` if it
356    /// is empty.
357    ///
358    /// # Example
359    ///
360    /// ```rust
361    /// use ndarray::Array3;
362    ///
363    /// let mut a = Array3::<f64>::zeros([3, 4, 2]);
364    /// a[[0, 0, 0]] = 42.;
365    /// assert_eq!(a.first(), Some(&42.));
366    ///
367    /// let b = Array3::<f64>::zeros([3, 0, 5]);
368    /// assert_eq!(b.first(), None);
369    /// ```
370    pub fn first(&self) -> Option<&A>
371    {
372        if self.is_empty() {
373            None
374        } else {
375            Some(unsafe { &*self.as_ptr() })
376        }
377    }
378
379    /// Returns a mutable reference to the first element of the array, or
380    /// `None` if it is empty.
381    ///
382    /// # Example
383    ///
384    /// ```rust
385    /// use ndarray::Array3;
386    ///
387    /// let mut a = Array3::<f64>::zeros([3, 4, 2]);
388    /// *a.first_mut().unwrap() = 42.;
389    /// assert_eq!(a[[0, 0, 0]], 42.);
390    ///
391    /// let mut b = Array3::<f64>::zeros([3, 0, 5]);
392    /// assert_eq!(b.first_mut(), None);
393    /// ```
394    pub fn first_mut(&mut self) -> Option<&mut A>
395    {
396        if self.is_empty() {
397            None
398        } else {
399            Some(unsafe { &mut *self.as_mut_ptr() })
400        }
401    }
402
403    /// Returns a reference to the last element of the array, or `None` if it
404    /// is empty.
405    ///
406    /// # Example
407    ///
408    /// ```rust
409    /// use ndarray::Array3;
410    ///
411    /// let mut a = Array3::<f64>::zeros([3, 4, 2]);
412    /// a[[2, 3, 1]] = 42.;
413    /// assert_eq!(a.last(), Some(&42.));
414    ///
415    /// let b = Array3::<f64>::zeros([3, 0, 5]);
416    /// assert_eq!(b.last(), None);
417    /// ```
418    pub fn last(&self) -> Option<&A>
419    {
420        if self.is_empty() {
421            None
422        } else {
423            let mut index = self.raw_dim();
424            for ax in 0..index.ndim() {
425                index[ax] -= 1;
426            }
427            Some(unsafe { self.uget(index) })
428        }
429    }
430
431    /// Returns a mutable reference to the last element of the array, or `None`
432    /// if it is empty.
433    ///
434    /// # Example
435    ///
436    /// ```rust
437    /// use ndarray::Array3;
438    ///
439    /// let mut a = Array3::<f64>::zeros([3, 4, 2]);
440    /// *a.last_mut().unwrap() = 42.;
441    /// assert_eq!(a[[2, 3, 1]], 42.);
442    ///
443    /// let mut b = Array3::<f64>::zeros([3, 0, 5]);
444    /// assert_eq!(b.last_mut(), None);
445    /// ```
446    pub fn last_mut(&mut self) -> Option<&mut A>
447    {
448        if self.is_empty() {
449            None
450        } else {
451            let mut index = self.raw_dim();
452            for ax in 0..index.ndim() {
453                index[ax] -= 1;
454            }
455            Some(unsafe { self.uget_mut(index) })
456        }
457    }
458
459    /// Return an iterator of references to the elements of the array.
460    ///
461    /// Elements are visited in the *logical order* of the array, which
462    /// is where the rightmost index is varying the fastest.
463    ///
464    /// Iterator element type is `&A`.
465    pub fn iter(&self) -> Iter<'_, A, D>
466    {
467        // debug_assert!(self.pointer_is_inbounds());
468        self.view().into_iter()
469    }
470
471    /// Return an iterator of mutable references to the elements of the array.
472    ///
473    /// Elements are visited in the *logical order* of the array, which
474    /// is where the rightmost index is varying the fastest.
475    ///
476    /// Iterator element type is `&mut A`.
477    pub fn iter_mut(&mut self) -> IterMut<'_, A, D>
478    {
479        self.view_mut().into_iter()
480    }
481
482    /// Return an iterator of indexes and references to the elements of the array.
483    ///
484    /// Elements are visited in the *logical order* of the array, which
485    /// is where the rightmost index is varying the fastest.
486    ///
487    /// Iterator element type is `(D::Pattern, &A)`.
488    ///
489    /// See also [`Zip::indexed`]
490    pub fn indexed_iter(&self) -> IndexedIter<'_, A, D>
491    {
492        IndexedIter::new(self.view().into_elements_base())
493    }
494
495    /// Return an iterator of indexes and mutable references to the elements of the array.
496    ///
497    /// Elements are visited in the *logical order* of the array, which
498    /// is where the rightmost index is varying the fastest.
499    ///
500    /// Iterator element type is `(D::Pattern, &mut A)`.
501    pub fn indexed_iter_mut(&mut self) -> IndexedIterMut<'_, A, D>
502    {
503        IndexedIterMut::new(self.view_mut().into_elements_base())
504    }
505
506    /// Return a sliced view of the array.
507    ///
508    /// See [*Slicing*](#slicing) for full documentation.
509    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
510    ///
511    /// **Panics** if an index is out of bounds or step size is zero.<br>
512    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
513    #[track_caller]
514    pub fn slice<I>(&self, info: I) -> ArrayView<'_, A, I::OutDim>
515    where I: SliceArg<D>
516    {
517        self.view().slice_move(info)
518    }
519
520    /// Return a sliced read-write view of the array.
521    ///
522    /// See [*Slicing*](#slicing) for full documentation.
523    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
524    ///
525    /// **Panics** if an index is out of bounds or step size is zero.<br>
526    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
527    #[track_caller]
528    pub fn slice_mut<I>(&mut self, info: I) -> ArrayViewMut<'_, A, I::OutDim>
529    where I: SliceArg<D>
530    {
531        self.view_mut().slice_move(info)
532    }
533
534    /// Return multiple disjoint, sliced, mutable views of the array.
535    ///
536    /// See [*Slicing*](#slicing) for full documentation. See also
537    /// [`MultiSliceArg`], [`s!`], [`SliceArg`], and
538    /// [`SliceInfo`](crate::SliceInfo).
539    ///
540    /// **Panics** if any of the following occur:
541    ///
542    /// * if any of the views would intersect (i.e. if any element would appear in multiple slices)
543    /// * if an index is out of bounds or step size is zero
544    /// * if `D` is `IxDyn` and `info` does not match the number of array axes
545    ///
546    /// # Example
547    ///
548    /// ```
549    /// use ndarray::{arr2, s};
550    ///
551    /// let mut a = arr2(&[[1, 2, 3], [4, 5, 6]]);
552    /// let (mut edges, mut middle) = a.multi_slice_mut((s![.., ..;2], s![.., 1]));
553    /// edges.fill(1);
554    /// middle.fill(0);
555    /// assert_eq!(a, arr2(&[[1, 0, 1], [1, 0, 1]]));
556    /// ```
557    #[track_caller]
558    pub fn multi_slice_mut<'a, M>(&'a mut self, info: M) -> M::Output
559    where M: MultiSliceArg<'a, A, D>
560    {
561        info.multi_slice_move(self.view_mut())
562    }
563}
564
565impl<A, S, D> ArrayBase<S, D>
566where
567    S: RawData<Elem = A>,
568    D: Dimension,
569{
570    /// Slice the array, possibly changing the number of dimensions.
571    ///
572    /// See [*Slicing*](#slicing) for full documentation.
573    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
574    ///
575    /// **Panics** if an index is out of bounds or step size is zero.<br>
576    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
577    #[track_caller]
578    pub fn slice_move<I>(mut self, info: I) -> ArrayBase<S, I::OutDim>
579    where I: SliceArg<D>
580    {
581        assert_eq!(info.in_ndim(), self.ndim(), "The input dimension of `info` must match the array to be sliced.",);
582        let out_ndim = info.out_ndim();
583        let mut new_dim = I::OutDim::zeros(out_ndim);
584        let mut new_strides = I::OutDim::zeros(out_ndim);
585
586        let mut old_axis = 0;
587        let mut new_axis = 0;
588        info.as_ref().iter().for_each(|&ax_info| match ax_info {
589            SliceInfoElem::Slice { start, end, step } => {
590                // Slice the axis in-place to update the `dim`, `strides`, and `ptr`.
591                self.slice_axis_inplace(Axis(old_axis), Slice { start, end, step });
592                // Copy the sliced dim and stride to corresponding axis.
593                new_dim[new_axis] = self.parts.dim[old_axis];
594                new_strides[new_axis] = self.parts.strides[old_axis];
595                old_axis += 1;
596                new_axis += 1;
597            }
598            SliceInfoElem::Index(index) => {
599                // Collapse the axis in-place to update the `ptr`.
600                let i_usize = abs_index(self.len_of(Axis(old_axis)), index);
601                self.collapse_axis(Axis(old_axis), i_usize);
602                // Skip copying the axis since it should be removed. Note that
603                // removing this axis is safe because `.collapse_axis()` panics
604                // if the index is out-of-bounds, so it will panic if the axis
605                // is zero length.
606                old_axis += 1;
607            }
608            SliceInfoElem::NewAxis => {
609                // Set the dim and stride of the new axis.
610                new_dim[new_axis] = 1;
611                new_strides[new_axis] = 0;
612                new_axis += 1;
613            }
614        });
615        debug_assert_eq!(old_axis, self.ndim());
616        debug_assert_eq!(new_axis, out_ndim);
617
618        // safe because new dimension, strides allow access to a subset of old data
619        unsafe { self.with_strides_dim(new_strides, new_dim) }
620    }
621}
622
623impl<A, D: Dimension> LayoutRef<A, D>
624{
625    /// Slice the array in place without changing the number of dimensions.
626    ///
627    /// In particular, if an axis is sliced with an index, the axis is
628    /// collapsed, as in [`.collapse_axis()`], rather than removed, as in
629    /// [`.slice_move()`] or [`.index_axis_move()`].
630    ///
631    /// [`.collapse_axis()`]: LayoutRef::collapse_axis
632    /// [`.slice_move()`]: ArrayBase::slice_move
633    /// [`.index_axis_move()`]: ArrayBase::index_axis_move
634    ///
635    /// See [*Slicing*](#slicing) for full documentation.
636    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
637    ///
638    /// **Panics** in the following cases:
639    ///
640    /// - if an index is out of bounds
641    /// - if a step size is zero
642    /// - if [`SliceInfoElem::NewAxis`] is in `info`, e.g. if [`NewAxis`] was
643    ///   used in the [`s!`] macro
644    /// - if `D` is `IxDyn` and `info` does not match the number of array axes
645    #[track_caller]
646    pub fn slice_collapse<I>(&mut self, info: I)
647    where I: SliceArg<D>
648    {
649        assert_eq!(info.in_ndim(), self.ndim(), "The input dimension of `info` must match the array to be sliced.",);
650        let mut axis = 0;
651        info.as_ref().iter().for_each(|&ax_info| match ax_info {
652            SliceInfoElem::Slice { start, end, step } => {
653                self.slice_axis_inplace(Axis(axis), Slice { start, end, step });
654                axis += 1;
655            }
656            SliceInfoElem::Index(index) => {
657                let i_usize = abs_index(self.len_of(Axis(axis)), index);
658                self.collapse_axis(Axis(axis), i_usize);
659                axis += 1;
660            }
661            SliceInfoElem::NewAxis => panic!("`slice_collapse` does not support `NewAxis`."),
662        });
663        debug_assert_eq!(axis, self.ndim());
664    }
665}
666
667impl<A, D: Dimension> ArrayRef<A, D>
668{
669    /// Return a view of the array, sliced along the specified axis.
670    ///
671    /// **Panics** if an index is out of bounds or step size is zero.<br>
672    /// **Panics** if `axis` is out of bounds.
673    #[track_caller]
674    #[must_use = "slice_axis returns an array view with the sliced result"]
675    pub fn slice_axis(&self, axis: Axis, indices: Slice) -> ArrayView<'_, A, D>
676    {
677        let mut view = self.view();
678        view.slice_axis_inplace(axis, indices);
679        view
680    }
681
682    /// Return a mutable view of the array, sliced along the specified axis.
683    ///
684    /// **Panics** if an index is out of bounds or step size is zero.<br>
685    /// **Panics** if `axis` is out of bounds.
686    #[track_caller]
687    #[must_use = "slice_axis_mut returns an array view with the sliced result"]
688    pub fn slice_axis_mut(&mut self, axis: Axis, indices: Slice) -> ArrayViewMut<'_, A, D>
689    {
690        let mut view_mut = self.view_mut();
691        view_mut.slice_axis_inplace(axis, indices);
692        view_mut
693    }
694}
695
696impl<A, D: Dimension> LayoutRef<A, D>
697{
698    /// Slice the array in place along the specified axis.
699    ///
700    /// **Panics** if an index is out of bounds or step size is zero.<br>
701    /// **Panics** if `axis` is out of bounds.
702    #[track_caller]
703    pub fn slice_axis_inplace(&mut self, axis: Axis, indices: Slice)
704    {
705        let parts = &mut self.0;
706        let offset =
707            do_slice(&mut parts.dim.slice_mut()[axis.index()], &mut parts.strides.slice_mut()[axis.index()], indices);
708        unsafe {
709            self.0.ptr = self._ptr().offset(offset);
710        }
711        // debug_assert!(self.pointer_is_inbounds());
712    }
713}
714
715impl<A, S, D> ArrayBase<S, D>
716where
717    S: RawData<Elem = A>,
718    D: Dimension,
719{
720    /// Slice the array in place along the specified axis, then return the sliced array.
721    ///
722    /// **Panics** if an index is out of bounds or step size is zero.<br>
723    /// **Panics** if `axis` is out of bounds.
724    #[must_use = "slice_axis_move returns an array with the sliced result"]
725    pub fn slice_axis_move(mut self, axis: Axis, indices: Slice) -> Self
726    {
727        self.slice_axis_inplace(axis, indices);
728        self
729    }
730}
731
732impl<A, D: Dimension> ArrayRef<A, D>
733{
734    /// Return a view of a slice of the array, with a closure specifying the
735    /// slice for each axis.
736    ///
737    /// This is especially useful for code which is generic over the
738    /// dimensionality of the array.
739    ///
740    /// **Panics** if an index is out of bounds or step size is zero.
741    #[track_caller]
742    pub fn slice_each_axis<F>(&self, f: F) -> ArrayView<'_, A, D>
743    where F: FnMut(AxisDescription) -> Slice
744    {
745        let mut view = self.view();
746        view.slice_each_axis_inplace(f);
747        view
748    }
749
750    /// Return a mutable view of a slice of the array, with a closure
751    /// specifying the slice for each axis.
752    ///
753    /// This is especially useful for code which is generic over the
754    /// dimensionality of the array.
755    ///
756    /// **Panics** if an index is out of bounds or step size is zero.
757    #[track_caller]
758    pub fn slice_each_axis_mut<F>(&mut self, f: F) -> ArrayViewMut<'_, A, D>
759    where F: FnMut(AxisDescription) -> Slice
760    {
761        let mut view = self.view_mut();
762        view.slice_each_axis_inplace(f);
763        view
764    }
765}
766
767impl<A, D: Dimension> LayoutRef<A, D>
768{
769    /// Slice the array in place, with a closure specifying the slice for each
770    /// axis.
771    ///
772    /// This is especially useful for code which is generic over the
773    /// dimensionality of the array.
774    ///
775    /// **Panics** if an index is out of bounds or step size is zero.
776    #[track_caller]
777    pub fn slice_each_axis_inplace<F>(&mut self, mut f: F)
778    where F: FnMut(AxisDescription) -> Slice
779    {
780        for ax in 0..self.ndim() {
781            self.slice_axis_inplace(
782                Axis(ax),
783                f(AxisDescription {
784                    axis: Axis(ax),
785                    len: self._dim()[ax],
786                    stride: self._strides()[ax] as isize,
787                }),
788            )
789        }
790    }
791}
792
793impl<A, D: Dimension> ArrayRef<A, D>
794{
795    /// Return a reference to the element at `index`, or return `None`
796    /// if the index is out of bounds.
797    ///
798    /// Arrays also support indexing syntax: `array[index]`.
799    ///
800    /// ```
801    /// use ndarray::arr2;
802    ///
803    /// let a = arr2(&[[1., 2.],
804    ///                [3., 4.]]);
805    ///
806    /// assert!(
807    ///     a.get((0, 1)) == Some(&2.) &&
808    ///     a.get((0, 2)) == None &&
809    ///     a[(0, 1)] == 2. &&
810    ///     a[[0, 1]] == 2.
811    /// );
812    /// ```
813    pub fn get<I>(&self, index: I) -> Option<&A>
814    where I: NdIndex<D>
815    {
816        unsafe { self.get_ptr(index).map(|ptr| &*ptr) }
817    }
818}
819
820impl<A, D: Dimension> RawRef<A, D>
821{
822    /// Return a raw pointer to the element at `index`, or return `None`
823    /// if the index is out of bounds.
824    ///
825    /// ```
826    /// use ndarray::arr2;
827    ///
828    /// let a = arr2(&[[1., 2.], [3., 4.]]);
829    ///
830    /// let v = a.raw_view();
831    /// let p = a.get_ptr((0, 1)).unwrap();
832    ///
833    /// assert_eq!(unsafe { *p }, 2.);
834    /// ```
835    pub fn get_ptr<I>(&self, index: I) -> Option<*const A>
836    where I: NdIndex<D>
837    {
838        let ptr = self._ptr();
839        index
840            .index_checked(self._dim(), self._strides())
841            .map(move |offset| unsafe { ptr.as_ptr().offset(offset) as *const _ })
842    }
843}
844
845impl<A, D: Dimension> ArrayRef<A, D>
846{
847    /// Return a mutable reference to the element at `index`, or return `None`
848    /// if the index is out of bounds.
849    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut A>
850    where I: NdIndex<D>
851    {
852        unsafe { self.get_mut_ptr(index).map(|ptr| &mut *ptr) }
853    }
854}
855
856impl<A, D: Dimension> RawRef<A, D>
857{
858    /// Return a raw pointer to the element at `index`, or return `None`
859    /// if the index is out of bounds.
860    ///
861    /// ```
862    /// use ndarray::arr2;
863    ///
864    /// let mut a = arr2(&[[1., 2.], [3., 4.]]);
865    ///
866    /// let v = a.raw_view_mut();
867    /// let p = a.get_mut_ptr((0, 1)).unwrap();
868    ///
869    /// unsafe {
870    ///     *p = 5.;
871    /// }
872    ///
873    /// assert_eq!(a.get((0, 1)), Some(&5.));
874    /// ```
875    pub fn get_mut_ptr<I>(&mut self, index: I) -> Option<*mut A>
876    where I: NdIndex<D>
877    {
878        // const and mut are separate to enforce &mutness as well as the
879        // extra code in as_mut_ptr
880        let ptr = self.as_mut_ptr();
881        index
882            .index_checked(self._dim(), self._strides())
883            .map(move |offset| unsafe { ptr.offset(offset) })
884    }
885}
886
887impl<A, D: Dimension> ArrayRef<A, D>
888{
889    /// Perform *unchecked* array indexing.
890    ///
891    /// Return a reference to the element at `index`.
892    ///
893    /// **Note:** only unchecked for non-debug builds of ndarray.
894    ///
895    /// # Safety
896    ///
897    /// The caller must ensure that the index is in-bounds.
898    #[inline]
899    pub unsafe fn uget<I>(&self, index: I) -> &A
900    where I: NdIndex<D>
901    {
902        arraytraits::debug_bounds_check(self, &index);
903        let off = index.index_unchecked(self._strides());
904        &*self._ptr().as_ptr().offset(off)
905    }
906
907    /// Perform *unchecked* array indexing.
908    ///
909    /// Return a mutable reference to the element at `index`.
910    ///
911    /// **Note:** Only unchecked for non-debug builds of ndarray.
912    ///
913    /// # Safety
914    ///
915    /// The caller must ensure that:
916    ///
917    /// 1. the index is in-bounds and
918    ///
919    /// 2. the data is uniquely held by the array. (This property is guaranteed
920    ///    for `Array` and `ArrayViewMut`, but not for `ArcArray` or `CowArray`.)
921    #[inline]
922    pub unsafe fn uget_mut<I>(&mut self, index: I) -> &mut A
923    where I: NdIndex<D>
924    {
925        // debug_assert!(self.data.is_unique());
926        arraytraits::debug_bounds_check(self, &index);
927        let off = index.index_unchecked(self._strides());
928        &mut *self._ptr().as_ptr().offset(off)
929    }
930
931    /// Swap elements at indices `index1` and `index2`.
932    ///
933    /// Indices may be equal.
934    ///
935    /// ***Panics*** if an index is out of bounds.
936    #[track_caller]
937    pub fn swap<I>(&mut self, index1: I, index2: I)
938    where I: NdIndex<D>
939    {
940        let ptr = self.as_mut_ptr();
941        let offset1 = index1.index_checked(self._dim(), self._strides());
942        let offset2 = index2.index_checked(self._dim(), self._strides());
943        if let Some(offset1) = offset1 {
944            if let Some(offset2) = offset2 {
945                unsafe {
946                    std::ptr::swap(ptr.offset(offset1), ptr.offset(offset2));
947                }
948                return;
949            }
950        }
951        panic!("swap: index out of bounds for indices {:?} {:?}", index1, index2);
952    }
953
954    /// Swap elements *unchecked* at indices `index1` and `index2`.
955    ///
956    /// Indices may be equal.
957    ///
958    /// **Note:** only unchecked for non-debug builds of ndarray.
959    ///
960    /// # Safety
961    ///
962    /// The caller must ensure that:
963    ///
964    /// 1. both `index1` and `index2` are in-bounds and
965    ///
966    /// 2. the data is uniquely held by the array. (This property is guaranteed
967    ///    for `Array` and `ArrayViewMut`, but not for `ArcArray` or `CowArray`.)
968    pub unsafe fn uswap<I>(&mut self, index1: I, index2: I)
969    where I: NdIndex<D>
970    {
971        // debug_assert!(self.data.is_unique());
972        arraytraits::debug_bounds_check(self, &index1);
973        arraytraits::debug_bounds_check(self, &index2);
974        let off1 = index1.index_unchecked(self._strides());
975        let off2 = index2.index_unchecked(self._strides());
976        std::ptr::swap(self._ptr().as_ptr().offset(off1), self._ptr().as_ptr().offset(off2));
977    }
978
979    // `get` for zero-dimensional arrays
980    // panics if dimension is not zero. otherwise an element is always present.
981    fn get_0d(&self) -> &A
982    {
983        assert!(self.ndim() == 0);
984        unsafe { &*self.as_ptr() }
985    }
986
987    /// Returns a view restricted to `index` along the axis, with the axis
988    /// removed.
989    ///
990    /// See [*Subviews*](#subviews) for full documentation.
991    ///
992    /// **Panics** if `axis` or `index` is out of bounds.
993    ///
994    /// ```
995    /// use ndarray::{arr2, ArrayView, Axis};
996    ///
997    /// let a = arr2(&[[1., 2. ],    // ... axis 0, row 0
998    ///                [3., 4. ],    // --- axis 0, row 1
999    ///                [5., 6. ]]);  // ... axis 0, row 2
1000    /// //               .   \
1001    /// //                .   axis 1, column 1
1002    /// //                 axis 1, column 0
1003    /// assert!(
1004    ///     a.index_axis(Axis(0), 1) == ArrayView::from(&[3., 4.]) &&
1005    ///     a.index_axis(Axis(1), 1) == ArrayView::from(&[2., 4., 6.])
1006    /// );
1007    /// ```
1008    #[track_caller]
1009    pub fn index_axis(&self, axis: Axis, index: usize) -> ArrayView<'_, A, D::Smaller>
1010    where D: RemoveAxis
1011    {
1012        self.view().index_axis_move(axis, index)
1013    }
1014
1015    /// Returns a mutable view restricted to `index` along the axis, with the
1016    /// axis removed.
1017    ///
1018    /// **Panics** if `axis` or `index` is out of bounds.
1019    ///
1020    /// ```
1021    /// use ndarray::{arr2, aview2, Axis};
1022    ///
1023    /// let mut a = arr2(&[[1., 2. ],
1024    ///                    [3., 4. ]]);
1025    /// //                   .   \
1026    /// //                    .   axis 1, column 1
1027    /// //                     axis 1, column 0
1028    ///
1029    /// {
1030    ///     let mut column1 = a.index_axis_mut(Axis(1), 1);
1031    ///     column1 += 10.;
1032    /// }
1033    ///
1034    /// assert!(
1035    ///     a == aview2(&[[1., 12.],
1036    ///                   [3., 14.]])
1037    /// );
1038    /// ```
1039    #[track_caller]
1040    pub fn index_axis_mut(&mut self, axis: Axis, index: usize) -> ArrayViewMut<'_, A, D::Smaller>
1041    where D: RemoveAxis
1042    {
1043        self.view_mut().index_axis_move(axis, index)
1044    }
1045}
1046
1047impl<A, S, D> ArrayBase<S, D>
1048where
1049    S: RawData<Elem = A>,
1050    D: Dimension,
1051{
1052    /// Collapses the array to `index` along the axis and removes the axis.
1053    ///
1054    /// See [`.index_axis()`](ArrayRef::index_axis) and [*Subviews*](#subviews) for full documentation.
1055    ///
1056    /// **Panics** if `axis` or `index` is out of bounds.
1057    #[track_caller]
1058    pub fn index_axis_move(mut self, axis: Axis, index: usize) -> ArrayBase<S, D::Smaller>
1059    where D: RemoveAxis
1060    {
1061        self.collapse_axis(axis, index);
1062        let dim = self.parts.dim.remove_axis(axis);
1063        let strides = self.parts.strides.remove_axis(axis);
1064        // safe because new dimension, strides allow access to a subset of old data
1065        unsafe { self.with_strides_dim(strides, dim) }
1066    }
1067}
1068
1069impl<A, D: Dimension> LayoutRef<A, D>
1070{
1071    /// Selects `index` along the axis, collapsing the axis into length one.
1072    ///
1073    /// **Panics** if `axis` or `index` is out of bounds.
1074    #[track_caller]
1075    pub fn collapse_axis(&mut self, axis: Axis, index: usize)
1076    {
1077        let parts = &mut self.0;
1078        let offset = dimension::do_collapse_axis(&mut parts.dim, &parts.strides, axis.index(), index);
1079        self.0.ptr = unsafe { self._ptr().offset(offset) };
1080        // debug_assert!(self.pointer_is_inbounds());
1081    }
1082}
1083
1084impl<A, D: Dimension> ArrayRef<A, D>
1085{
1086    /// Along `axis`, select arbitrary subviews corresponding to `indices`
1087    /// and copy them into a new array.
1088    ///
1089    /// **Panics** if `axis` or an element of `indices` is out of bounds.
1090    ///
1091    /// ```
1092    /// use ndarray::{arr2, Axis};
1093    ///
1094    /// let x = arr2(&[[0., 1.],
1095    ///                [2., 3.],
1096    ///                [4., 5.],
1097    ///                [6., 7.],
1098    ///                [8., 9.]]);
1099    ///
1100    /// let r = x.select(Axis(0), &[0, 4, 3]);
1101    /// assert!(
1102    ///         r == arr2(&[[0., 1.],
1103    ///                     [8., 9.],
1104    ///                     [6., 7.]])
1105    ///);
1106    /// ```
1107    #[track_caller]
1108    pub fn select(&self, axis: Axis, indices: &[Ix]) -> Array<A, D>
1109    where
1110        A: Clone,
1111        D: RemoveAxis,
1112    {
1113        if self.ndim() == 1 {
1114            // using .len_of(axis) means that we check if `axis` is in bounds too.
1115            let axis_len = self.len_of(axis);
1116            // bounds check the indices first
1117            if let Some(max_index) = indices.iter().cloned().max() {
1118                if max_index >= axis_len {
1119                    panic!("ndarray: index {} is out of bounds in array of len {}", max_index, self.len_of(axis));
1120                }
1121            } // else: indices empty is ok
1122            let view = self.view().into_dimensionality::<Ix1>().unwrap();
1123            Array::from_iter(indices.iter().map(move |&index| {
1124                // Safety: bounds checked indexes
1125                unsafe { view.uget(index).clone() }
1126            }))
1127            .into_dimensionality::<D>()
1128            .unwrap()
1129        } else {
1130            let mut subs = vec![self.view(); indices.len()];
1131            for (&i, sub) in zip(indices, &mut subs[..]) {
1132                sub.collapse_axis(axis, i);
1133            }
1134            if subs.is_empty() {
1135                let mut dim = self.raw_dim();
1136                dim.set_axis(axis, 0);
1137                unsafe { Array::from_shape_vec_unchecked(dim, vec![]) }
1138            } else {
1139                concatenate(axis, &subs).unwrap()
1140            }
1141        }
1142    }
1143
1144    /// Return a producer and iterable that traverses over the *generalized*
1145    /// rows of the array. For a 2D array these are the regular rows.
1146    ///
1147    /// This is equivalent to `.lanes(Axis(n - 1))` where *n* is `self.ndim()`.
1148    ///
1149    /// For an array of dimensions *a* × *b* × *c* × ... × *l* × *m*
1150    /// it has *a* × *b* × *c* × ... × *l* rows each of length *m*.
1151    ///
1152    /// For example, in a 2 × 2 × 3 array, each row is 3 elements long
1153    /// and there are 2 × 2 = 4 rows in total.
1154    ///
1155    /// Iterator element is `ArrayView1<A>` (1D array view).
1156    ///
1157    /// ```
1158    /// use ndarray::arr3;
1159    ///
1160    /// let a = arr3(&[[[ 0,  1,  2],    // -- row 0, 0
1161    ///                 [ 3,  4,  5]],   // -- row 0, 1
1162    ///                [[ 6,  7,  8],    // -- row 1, 0
1163    ///                 [ 9, 10, 11]]]); // -- row 1, 1
1164    ///
1165    /// // `rows` will yield the four generalized rows of the array.
1166    /// for row in a.rows() {
1167    ///     /* loop body */
1168    /// }
1169    /// ```
1170    pub fn rows(&self) -> Lanes<'_, A, D::Smaller>
1171    {
1172        let mut n = self.ndim();
1173        if n == 0 {
1174            n += 1;
1175        }
1176        Lanes::new(self.view(), Axis(n - 1))
1177    }
1178
1179    /// Return a producer and iterable that traverses over the *generalized*
1180    /// rows of the array and yields mutable array views.
1181    ///
1182    /// Iterator element is `ArrayView1<A>` (1D read-write array view).
1183    pub fn rows_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
1184    {
1185        let mut n = self.ndim();
1186        if n == 0 {
1187            n += 1;
1188        }
1189        LanesMut::new(self.view_mut(), Axis(n - 1))
1190    }
1191
1192    /// Return a producer and iterable that traverses over the *generalized*
1193    /// columns of the array. For a 2D array these are the regular columns.
1194    ///
1195    /// This is equivalent to `.lanes(Axis(0))`.
1196    ///
1197    /// For an array of dimensions *a* × *b* × *c* × ... × *l* × *m*
1198    /// it has *b* × *c* × ... × *l* × *m* columns each of length *a*.
1199    ///
1200    /// For example, in a 2 × 2 × 3 array, each column is 2 elements long
1201    /// and there are 2 × 3 = 6 columns in total.
1202    ///
1203    /// Iterator element is `ArrayView1<A>` (1D array view).
1204    ///
1205    /// ```
1206    /// use ndarray::arr3;
1207    ///
1208    /// // The generalized columns of a 3D array:
1209    /// // are directed along the 0th axis: 0 and 6, 1 and 7 and so on...
1210    /// let a = arr3(&[[[ 0,  1,  2], [ 3,  4,  5]],
1211    ///                [[ 6,  7,  8], [ 9, 10, 11]]]);
1212    ///
1213    /// // Here `columns` will yield the six generalized columns of the array.
1214    /// for column in a.columns() {
1215    ///     /* loop body */
1216    /// }
1217    /// ```
1218    pub fn columns(&self) -> Lanes<'_, A, D::Smaller>
1219    {
1220        Lanes::new(self.view(), Axis(0))
1221    }
1222
1223    /// Return a producer and iterable that traverses over the *generalized*
1224    /// columns of the array and yields mutable array views.
1225    ///
1226    /// Iterator element is `ArrayView1<A>` (1D read-write array view).
1227    pub fn columns_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
1228    {
1229        LanesMut::new(self.view_mut(), Axis(0))
1230    }
1231
1232    /// Return a producer and iterable that traverses over all 1D lanes
1233    /// pointing in the direction of `axis`.
1234    ///
1235    /// When pointing in the direction of the first axis, they are *columns*,
1236    /// in the direction of the last axis *rows*; in general they are all
1237    /// *lanes* and are one dimensional.
1238    ///
1239    /// Iterator element is `ArrayView1<A>` (1D array view).
1240    ///
1241    /// ```
1242    /// use ndarray::{arr3, aview1, Axis};
1243    ///
1244    /// let a = arr3(&[[[ 0,  1,  2],
1245    ///                 [ 3,  4,  5]],
1246    ///                [[ 6,  7,  8],
1247    ///                 [ 9, 10, 11]]]);
1248    ///
1249    /// let inner0 = a.lanes(Axis(0));
1250    /// let inner1 = a.lanes(Axis(1));
1251    /// let inner2 = a.lanes(Axis(2));
1252    ///
1253    /// // The first lane for axis 0 is [0, 6]
1254    /// assert_eq!(inner0.into_iter().next().unwrap(), aview1(&[0, 6]));
1255    /// // The first lane for axis 1 is [0, 3]
1256    /// assert_eq!(inner1.into_iter().next().unwrap(), aview1(&[0, 3]));
1257    /// // The first lane for axis 2 is [0, 1, 2]
1258    /// assert_eq!(inner2.into_iter().next().unwrap(), aview1(&[0, 1, 2]));
1259    /// ```
1260    pub fn lanes(&self, axis: Axis) -> Lanes<'_, A, D::Smaller>
1261    {
1262        Lanes::new(self.view(), axis)
1263    }
1264
1265    /// Return a producer and iterable that traverses over all 1D lanes
1266    /// pointing in the direction of `axis`.
1267    ///
1268    /// Iterator element is `ArrayViewMut1<A>` (1D read-write array view).
1269    pub fn lanes_mut(&mut self, axis: Axis) -> LanesMut<'_, A, D::Smaller>
1270    {
1271        LanesMut::new(self.view_mut(), axis)
1272    }
1273
1274    /// Return an iterator that traverses over the outermost dimension
1275    /// and yields each subview.
1276    ///
1277    /// This is equivalent to `.axis_iter(Axis(0))`.
1278    ///
1279    /// Iterator element is `ArrayView<A, D::Smaller>` (read-only array view).
1280    #[allow(deprecated)]
1281    pub fn outer_iter(&self) -> AxisIter<'_, A, D::Smaller>
1282    where D: RemoveAxis
1283    {
1284        self.view().into_outer_iter()
1285    }
1286
1287    /// Return an iterator that traverses over the outermost dimension
1288    /// and yields each subview.
1289    ///
1290    /// This is equivalent to `.axis_iter_mut(Axis(0))`.
1291    ///
1292    /// Iterator element is `ArrayViewMut<A, D::Smaller>` (read-write array view).
1293    #[allow(deprecated)]
1294    pub fn outer_iter_mut(&mut self) -> AxisIterMut<'_, A, D::Smaller>
1295    where D: RemoveAxis
1296    {
1297        self.view_mut().into_outer_iter_mut()
1298    }
1299
1300    /// Return an iterator that traverses over `axis`
1301    /// and yields each subview along it.
1302    ///
1303    /// For example, in a 3 × 4 × 5 array, with `axis` equal to `Axis(2)`,
1304    /// the iterator element
1305    /// is a 3 × 4 subview (and there are 5 in total), as shown
1306    /// in the picture below.
1307    ///
1308    /// Iterator element is `ArrayView<A, D::Smaller>` (read-only array view).
1309    ///
1310    /// See [*Subviews*](#subviews) for full documentation.
1311    ///
1312    /// **Panics** if `axis` is out of bounds.
1313    ///
1314    /// <img src="https://rust-ndarray.github.io/ndarray/images/axis_iter_3_4_5.svg" height="250px">
1315    #[track_caller]
1316    pub fn axis_iter(&self, axis: Axis) -> AxisIter<'_, A, D::Smaller>
1317    where D: RemoveAxis
1318    {
1319        AxisIter::new(self.view(), axis)
1320    }
1321
1322    /// Return an iterator that traverses over `axis`
1323    /// and yields each mutable subview along it.
1324    ///
1325    /// Iterator element is `ArrayViewMut<A, D::Smaller>`
1326    /// (read-write array view).
1327    ///
1328    /// **Panics** if `axis` is out of bounds.
1329    #[track_caller]
1330    pub fn axis_iter_mut(&mut self, axis: Axis) -> AxisIterMut<'_, A, D::Smaller>
1331    where D: RemoveAxis
1332    {
1333        AxisIterMut::new(self.view_mut(), axis)
1334    }
1335
1336    /// Return an iterator that traverses over `axis` by chunks of `size`,
1337    /// yielding non-overlapping views along that axis.
1338    ///
1339    /// Iterator element is `ArrayView<A, D>`
1340    ///
1341    /// The last view may have less elements if `size` does not divide
1342    /// the axis' dimension.
1343    ///
1344    /// **Panics** if `axis` is out of bounds or if `size` is zero.
1345    ///
1346    /// ```
1347    /// use ndarray::Array;
1348    /// use ndarray::{arr3, Axis};
1349    ///
1350    /// let a = Array::from_iter(0..28).into_shape_with_order((2, 7, 2)).unwrap();
1351    /// let mut iter = a.axis_chunks_iter(Axis(1), 2);
1352    ///
1353    /// // first iteration yields a 2 × 2 × 2 view
1354    /// assert_eq!(iter.next().unwrap(),
1355    ///            arr3(&[[[ 0,  1], [ 2, 3]],
1356    ///                   [[14, 15], [16, 17]]]));
1357    ///
1358    /// // however the last element is a 2 × 1 × 2 view since 7 % 2 == 1
1359    /// assert_eq!(iter.next_back().unwrap(), arr3(&[[[12, 13]],
1360    ///                                              [[26, 27]]]));
1361    /// ```
1362    #[track_caller]
1363    pub fn axis_chunks_iter(&self, axis: Axis, size: usize) -> AxisChunksIter<'_, A, D>
1364    {
1365        AxisChunksIter::new(self.view(), axis, size)
1366    }
1367
1368    /// Return an iterator that traverses over `axis` by chunks of `size`,
1369    /// yielding non-overlapping read-write views along that axis.
1370    ///
1371    /// Iterator element is `ArrayViewMut<A, D>`
1372    ///
1373    /// **Panics** if `axis` is out of bounds or if `size` is zero.
1374    #[track_caller]
1375    pub fn axis_chunks_iter_mut(&mut self, axis: Axis, size: usize) -> AxisChunksIterMut<'_, A, D>
1376    {
1377        AxisChunksIterMut::new(self.view_mut(), axis, size)
1378    }
1379
1380    /// Return an exact chunks producer (and iterable).
1381    ///
1382    /// It produces the whole chunks of a given n-dimensional chunk size,
1383    /// skipping the remainder along each dimension that doesn't fit evenly.
1384    ///
1385    /// The produced element is a `ArrayView<A, D>` with exactly the dimension
1386    /// `chunk_size`.
1387    ///
1388    /// **Panics** if any dimension of `chunk_size` is zero<br>
1389    /// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
1390    /// number of array axes.)
1391    #[track_caller]
1392    pub fn exact_chunks<E>(&self, chunk_size: E) -> ExactChunks<'_, A, D>
1393    where E: IntoDimension<Dim = D>
1394    {
1395        ExactChunks::new(self.view(), chunk_size)
1396    }
1397
1398    /// Return an exact chunks producer (and iterable).
1399    ///
1400    /// It produces the whole chunks of a given n-dimensional chunk size,
1401    /// skipping the remainder along each dimension that doesn't fit evenly.
1402    ///
1403    /// The produced element is a `ArrayViewMut<A, D>` with exactly
1404    /// the dimension `chunk_size`.
1405    ///
1406    /// **Panics** if any dimension of `chunk_size` is zero<br>
1407    /// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
1408    /// number of array axes.)
1409    ///
1410    /// ```rust
1411    /// use ndarray::Array;
1412    /// use ndarray::arr2;
1413    /// let mut a = Array::zeros((6, 7));
1414    ///
1415    /// // Fill each 2 × 2 chunk with the index of where it appeared in iteration
1416    /// for (i, mut chunk) in a.exact_chunks_mut((2, 2)).into_iter().enumerate() {
1417    ///     chunk.fill(i);
1418    /// }
1419    ///
1420    /// // The resulting array is:
1421    /// assert_eq!(
1422    ///   a,
1423    ///   arr2(&[[0, 0, 1, 1, 2, 2, 0],
1424    ///          [0, 0, 1, 1, 2, 2, 0],
1425    ///          [3, 3, 4, 4, 5, 5, 0],
1426    ///          [3, 3, 4, 4, 5, 5, 0],
1427    ///          [6, 6, 7, 7, 8, 8, 0],
1428    ///          [6, 6, 7, 7, 8, 8, 0]]));
1429    /// ```
1430    #[track_caller]
1431    pub fn exact_chunks_mut<E>(&mut self, chunk_size: E) -> ExactChunksMut<'_, A, D>
1432    where E: IntoDimension<Dim = D>
1433    {
1434        ExactChunksMut::new(self.view_mut(), chunk_size)
1435    }
1436
1437    /// Return a window producer and iterable.
1438    ///
1439    /// The windows are all distinct overlapping views of size `window_size`
1440    /// that fit into the array's shape.
1441    ///
1442    /// This is essentially equivalent to [`ArrayRef::windows_with_stride()`] with unit stride.
1443    #[track_caller]
1444    pub fn windows<E>(&self, window_size: E) -> Windows<'_, A, D>
1445    where E: IntoDimension<Dim = D>
1446    {
1447        Windows::new(self.view(), window_size)
1448    }
1449
1450    /// Return a window producer and iterable.
1451    ///
1452    /// The windows are all distinct views of size `window_size`
1453    /// that fit into the array's shape.
1454    ///
1455    /// The stride is ordered by the outermost axis.<br>
1456    /// Hence, a (x₀, x₁, ..., xₙ) stride will be applied to
1457    /// (A₀, A₁, ..., Aₙ) where Aₓ stands for `Axis(x)`.
1458    ///
1459    /// This produces all windows that fit within the array for the given stride,
1460    /// assuming the window size is not larger than the array size.
1461    ///
1462    /// The produced element is an `ArrayView<A, D>` with exactly the dimension
1463    /// `window_size`.
1464    ///
1465    /// Note that passing a stride of only ones is similar to
1466    /// calling [`ArrayRef::windows()`].
1467    ///
1468    /// **Panics** if any dimension of `window_size` or `stride` is zero.<br>
1469    /// (**Panics** if `D` is `IxDyn` and `window_size` or `stride` does not match the
1470    /// number of array axes.)
1471    ///
1472    /// This is the same illustration found in [`ArrayRef::windows()`],
1473    /// 2×2 windows in a 3×4 array, but now with a (1, 2) stride:
1474    ///
1475    /// ```text
1476    ///          ──▶ Axis(1)
1477    ///
1478    ///      │   ┏━━━━━┳━━━━━┱─────┬─────┐   ┌─────┬─────┲━━━━━┳━━━━━┓
1479    ///      ▼   ┃ a₀₀ ┃ a₀₁ ┃     │     │   │     │     ┃ a₀₂ ┃ a₀₃ ┃
1480    /// Axis(0)  ┣━━━━━╋━━━━━╉─────┼─────┤   ├─────┼─────╊━━━━━╋━━━━━┫
1481    ///          ┃ a₁₀ ┃ a₁₁ ┃     │     │   │     │     ┃ a₁₂ ┃ a₁₃ ┃
1482    ///          ┡━━━━━╇━━━━━╃─────┼─────┤   ├─────┼─────╄━━━━━╇━━━━━┩
1483    ///          │     │     │     │     │   │     │     │     │     │
1484    ///          └─────┴─────┴─────┴─────┘   └─────┴─────┴─────┴─────┘
1485    ///
1486    ///          ┌─────┬─────┬─────┬─────┐   ┌─────┬─────┬─────┬─────┐
1487    ///          │     │     │     │     │   │     │     │     │     │
1488    ///          ┢━━━━━╈━━━━━╅─────┼─────┤   ├─────┼─────╆━━━━━╈━━━━━┪
1489    ///          ┃ a₁₀ ┃ a₁₁ ┃     │     │   │     │     ┃ a₁₂ ┃ a₁₃ ┃
1490    ///          ┣━━━━━╋━━━━━╉─────┼─────┤   ├─────┼─────╊━━━━━╋━━━━━┫
1491    ///          ┃ a₂₀ ┃ a₂₁ ┃     │     │   │     │     ┃ a₂₂ ┃ a₂₃ ┃
1492    ///          ┗━━━━━┻━━━━━┹─────┴─────┘   └─────┴─────┺━━━━━┻━━━━━┛
1493    /// ```
1494    #[track_caller]
1495    pub fn windows_with_stride<E>(&self, window_size: E, stride: E) -> Windows<'_, A, D>
1496    where E: IntoDimension<Dim = D>
1497    {
1498        Windows::new_with_stride(self.view(), window_size, stride)
1499    }
1500
1501    /// Returns a producer which traverses over all windows of a given length along an axis.
1502    ///
1503    /// The windows are all distinct, possibly-overlapping views. The shape of each window
1504    /// is the shape of `self`, with the length of `axis` replaced with `window_size`.
1505    ///
1506    /// **Panics** if `axis` is out-of-bounds or if `window_size` is zero.
1507    ///
1508    /// ```
1509    /// use ndarray::{Array3, Axis, s};
1510    ///
1511    /// let arr = Array3::from_shape_fn([4, 5, 2], |(i, j, k)| i * 100 + j * 10 + k);
1512    /// let correct = vec![
1513    ///     arr.slice(s![.., 0..3, ..]),
1514    ///     arr.slice(s![.., 1..4, ..]),
1515    ///     arr.slice(s![.., 2..5, ..]),
1516    /// ];
1517    /// for (window, correct) in arr.axis_windows(Axis(1), 3).into_iter().zip(&correct) {
1518    ///     assert_eq!(window, correct);
1519    ///     assert_eq!(window.shape(), &[4, 3, 2]);
1520    /// }
1521    /// ```
1522    pub fn axis_windows(&self, axis: Axis, window_size: usize) -> AxisWindows<'_, A, D>
1523    {
1524        self.axis_windows_with_stride(axis, window_size, 1)
1525    }
1526
1527    /// Returns a producer which traverses over windows of a given length and
1528    /// stride along an axis.
1529    ///
1530    /// Note that a calling this method with a stride of 1 is equivalent to
1531    /// calling [`ArrayRef::axis_windows()`].
1532    pub fn axis_windows_with_stride(&self, axis: Axis, window_size: usize, stride_size: usize)
1533        -> AxisWindows<'_, A, D>
1534    {
1535        let axis_index = axis.index();
1536
1537        ndassert!(
1538            axis_index < self.ndim(),
1539            concat!("Window axis {} does not match array dimension {} ", "(with array of shape {:?})"),
1540            axis_index,
1541            self.ndim(),
1542            self.shape()
1543        );
1544
1545        ndassert!(
1546            stride_size >0,
1547            "Stride size must be greater than zero"
1548        );
1549
1550        AxisWindows::new_with_stride(self.view(), axis, window_size, stride_size)
1551    }
1552
1553    /// Return a view of the diagonal elements of the array.
1554    ///
1555    /// The diagonal is simply the sequence indexed by *(0, 0, .., 0)*,
1556    /// *(1, 1, ..., 1)* etc as long as all axes have elements.
1557    pub fn diag(&self) -> ArrayView1<'_, A>
1558    {
1559        self.view().into_diag()
1560    }
1561
1562    /// Return a read-write view over the diagonal elements of the array.
1563    pub fn diag_mut(&mut self) -> ArrayViewMut1<'_, A>
1564    {
1565        self.view_mut().into_diag()
1566    }
1567}
1568
1569impl<A, S, D> ArrayBase<S, D>
1570where
1571    S: RawData<Elem = A>,
1572    D: Dimension,
1573{
1574    // Return (length, stride) for diagonal
1575    fn diag_params(&self) -> (Ix, Ixs)
1576    {
1577        /* empty shape has len 1 */
1578        let len = self.parts.dim.slice().iter().cloned().min().unwrap_or(1);
1579        let stride = self.strides().iter().sum();
1580        (len, stride)
1581    }
1582
1583    /// Return the diagonal as a one-dimensional array.
1584    pub fn into_diag(self) -> ArrayBase<S, Ix1>
1585    {
1586        let (len, stride) = self.diag_params();
1587        // safe because new len stride allows access to a subset of the current elements
1588        unsafe { self.with_strides_dim(Ix1(stride as Ix), Ix1(len)) }
1589    }
1590
1591    /// Try to make the array unshared.
1592    ///
1593    /// This is equivalent to `.ensure_unique()` if `S: DataMut`.
1594    ///
1595    /// This method is mostly only useful with unsafe code.
1596    fn try_ensure_unique(&mut self)
1597    where S: RawDataMut
1598    {
1599        debug_assert!(self.pointer_is_inbounds());
1600        S::try_ensure_unique(self);
1601        debug_assert!(self.pointer_is_inbounds());
1602    }
1603
1604    /// Make the array unshared.
1605    ///
1606    /// This method is mostly only useful with unsafe code.
1607    pub(crate) fn ensure_unique(&mut self)
1608    where S: DataMut
1609    {
1610        debug_assert!(self.pointer_is_inbounds());
1611        S::ensure_unique(self);
1612        debug_assert!(self.pointer_is_inbounds());
1613    }
1614}
1615
1616impl<A, D: Dimension> LayoutRef<A, D>
1617{
1618    /// Return `true` if the array data is laid out in contiguous “C order” in
1619    /// memory (where the last index is the most rapidly varying).
1620    ///
1621    /// Return `false` otherwise, i.e. the array is possibly not
1622    /// contiguous in memory, it has custom strides, etc.
1623    pub fn is_standard_layout(&self) -> bool
1624    {
1625        dimension::is_layout_c(self._dim(), self._strides())
1626    }
1627
1628    /// Return true if the array is known to be contiguous.
1629    pub(crate) fn is_contiguous(&self) -> bool
1630    {
1631        D::is_contiguous(self._dim(), self._strides())
1632    }
1633}
1634
1635impl<A, D: Dimension> ArrayRef<A, D>
1636{
1637    /// Return a standard-layout array containing the data, cloning if
1638    /// necessary.
1639    ///
1640    /// If `self` is in standard layout, a COW view of the data is returned
1641    /// without cloning. Otherwise, the data is cloned, and the returned array
1642    /// owns the cloned data.
1643    ///
1644    /// ```
1645    /// use ndarray::Array2;
1646    ///
1647    /// let standard = Array2::<f64>::zeros((3, 4));
1648    /// assert!(standard.is_standard_layout());
1649    /// let cow_view = standard.as_standard_layout();
1650    /// assert!(cow_view.is_view());
1651    /// assert!(cow_view.is_standard_layout());
1652    ///
1653    /// let fortran = standard.reversed_axes();
1654    /// assert!(!fortran.is_standard_layout());
1655    /// let cow_owned = fortran.as_standard_layout();
1656    /// assert!(cow_owned.is_owned());
1657    /// assert!(cow_owned.is_standard_layout());
1658    /// ```
1659    pub fn as_standard_layout(&self) -> CowArray<'_, A, D>
1660    where A: Clone
1661    {
1662        if self.is_standard_layout() {
1663            CowArray::from(self.view())
1664        } else {
1665            let v = crate::iterators::to_vec_mapped(self.iter(), A::clone);
1666            let dim = self._dim().clone();
1667            debug_assert_eq!(v.len(), dim.size());
1668
1669            unsafe {
1670                // Safe because the shape and element type are from the existing array
1671                // and the strides are the default strides.
1672                CowArray::from(Array::from_shape_vec_unchecked(dim, v))
1673            }
1674        }
1675    }
1676}
1677
1678impl<A, D: Dimension> RawRef<A, D>
1679{
1680    /// Return a pointer to the first element in the array.
1681    ///
1682    /// Raw access to array elements needs to follow the strided indexing
1683    /// scheme: an element at multi-index *I* in an array with strides *S* is
1684    /// located at offset
1685    ///
1686    /// *Σ<sub>0 ≤ k < d</sub> I<sub>k</sub> × S<sub>k</sub>*
1687    ///
1688    /// where *d* is `self.ndim()`.
1689    #[inline(always)]
1690    pub fn as_ptr(&self) -> *const A
1691    {
1692        self._ptr().as_ptr() as *const A
1693    }
1694
1695    /// Return a mutable pointer to the first element in the array reference.
1696    #[inline(always)]
1697    pub fn as_mut_ptr(&mut self) -> *mut A
1698    {
1699        self._ptr().as_ptr()
1700    }
1701}
1702
1703impl<A, S, D> ArrayBase<S, D>
1704where
1705    S: RawData<Elem = A>,
1706    D: Dimension,
1707{
1708    /// Return a mutable pointer to the first element in the array.
1709    ///
1710    /// This method attempts to unshare the data. If `S: DataMut`, then the
1711    /// data is guaranteed to be uniquely held on return.
1712    ///
1713    /// # Warning
1714    ///
1715    /// When accessing elements through this pointer, make sure to use strides
1716    /// obtained *after* calling this method, since the process of unsharing
1717    /// the data may change the strides.
1718    #[inline(always)]
1719    pub fn as_mut_ptr(&mut self) -> *mut A
1720    where S: RawDataMut
1721    {
1722        self.try_ensure_unique(); // for ArcArray
1723        self.parts.ptr.as_ptr()
1724    }
1725}
1726
1727impl<A, D: Dimension> RawRef<A, D>
1728{
1729    /// Return a raw view of the array.
1730    #[inline]
1731    pub fn raw_view(&self) -> RawArrayView<A, D>
1732    {
1733        unsafe { RawArrayView::new(*self._ptr(), self._dim().clone(), self._strides().clone()) }
1734    }
1735
1736    /// Return a raw mutable view of the array.
1737    #[inline]
1738    pub fn raw_view_mut(&mut self) -> RawArrayViewMut<A, D>
1739    {
1740        unsafe { RawArrayViewMut::new(*self._ptr(), self._dim().clone(), self._strides().clone()) }
1741    }
1742}
1743
1744impl<A, S, D> ArrayBase<S, D>
1745where
1746    S: RawData<Elem = A>,
1747    D: Dimension,
1748{
1749    /// Return a raw mutable view of the array.
1750    ///
1751    /// This method attempts to unshare the data. If `S: DataMut`, then the
1752    /// data is guaranteed to be uniquely held on return.
1753    #[inline]
1754    pub fn raw_view_mut(&mut self) -> RawArrayViewMut<A, D>
1755    where S: RawDataMut
1756    {
1757        self.try_ensure_unique(); // for ArcArray
1758        unsafe { RawArrayViewMut::new(self.parts.ptr, self.parts.dim.clone(), self.parts.strides.clone()) }
1759    }
1760
1761    /// Return a raw mutable view of the array.
1762    ///
1763    /// Safety: The caller must ensure that the owned array is unshared when this is called
1764    #[inline]
1765    pub(crate) unsafe fn raw_view_mut_unchecked(&mut self) -> RawArrayViewMut<A, D>
1766    where S: DataOwned
1767    {
1768        RawArrayViewMut::new(*self._ptr(), self._dim().clone(), self._strides().clone())
1769    }
1770
1771    /// Return the array’s data as a slice, if it is contiguous and in standard order.
1772    /// Return `None` otherwise.
1773    pub fn as_slice_mut(&mut self) -> Option<&mut [A]>
1774    where S: DataMut
1775    {
1776        if self.is_standard_layout() {
1777            self.ensure_unique();
1778            unsafe { Some(slice::from_raw_parts_mut(self._ptr().as_ptr(), self.len())) }
1779        } else {
1780            None
1781        }
1782    }
1783
1784    /// Return the array’s data as a slice if it is contiguous,
1785    /// return `None` otherwise.
1786    ///
1787    /// In the contiguous case, in order to return a unique reference, this
1788    /// method unshares the data if necessary, but it preserves the existing
1789    /// strides.
1790    pub fn as_slice_memory_order_mut(&mut self) -> Option<&mut [A]>
1791    where S: DataMut
1792    {
1793        self.try_as_slice_memory_order_mut().ok()
1794    }
1795
1796    /// Return the array’s data as a slice if it is contiguous, otherwise
1797    /// return `self` in the `Err` variant.
1798    pub(crate) fn try_as_slice_memory_order_mut(&mut self) -> Result<&mut [A], &mut Self>
1799    where S: DataMut
1800    {
1801        if self.is_contiguous() {
1802            self.ensure_unique();
1803            let offset = offset_from_low_addr_ptr_to_logical_ptr(self._dim(), self._strides());
1804            unsafe { Ok(slice::from_raw_parts_mut(self._ptr().sub(offset).as_ptr(), self.len())) }
1805        } else {
1806            Err(self)
1807        }
1808    }
1809}
1810
1811impl<A, D: Dimension> ArrayRef<A, D>
1812{
1813    /// Return the array’s data as a slice, if it is contiguous and in standard order.
1814    /// Return `None` otherwise.
1815    ///
1816    /// If this function returns `Some(_)`, then the element order in the slice
1817    /// corresponds to the logical order of the array’s elements.
1818    pub fn as_slice(&self) -> Option<&[A]>
1819    {
1820        if self.is_standard_layout() {
1821            unsafe { Some(slice::from_raw_parts(self._ptr().as_ptr(), self.len())) }
1822        } else {
1823            None
1824        }
1825    }
1826
1827    /// Return the array’s data as a slice, if it is contiguous and in standard order.
1828    /// Return `None` otherwise.
1829    pub fn as_slice_mut(&mut self) -> Option<&mut [A]>
1830    {
1831        if self.is_standard_layout() {
1832            unsafe { Some(slice::from_raw_parts_mut(self._ptr().as_ptr(), self.len())) }
1833        } else {
1834            None
1835        }
1836    }
1837
1838    /// Return the array’s data as a slice if it is contiguous,
1839    /// return `None` otherwise.
1840    ///
1841    /// If this function returns `Some(_)`, then the elements in the slice
1842    /// have whatever order the elements have in memory.
1843    pub fn as_slice_memory_order(&self) -> Option<&[A]>
1844    {
1845        if self.is_contiguous() {
1846            let offset = offset_from_low_addr_ptr_to_logical_ptr(self._dim(), self._strides());
1847            unsafe { Some(slice::from_raw_parts(self._ptr().sub(offset).as_ptr(), self.len())) }
1848        } else {
1849            None
1850        }
1851    }
1852
1853    /// Return the array’s data as a slice if it is contiguous,
1854    /// return `None` otherwise.
1855    ///
1856    /// In the contiguous case, in order to return a unique reference, this
1857    /// method unshares the data if necessary, but it preserves the existing
1858    /// strides.
1859    pub fn as_slice_memory_order_mut(&mut self) -> Option<&mut [A]>
1860    {
1861        self.try_as_slice_memory_order_mut().ok()
1862    }
1863
1864    /// Return the array’s data as a slice if it is contiguous, otherwise
1865    /// return `self` in the `Err` variant.
1866    pub(crate) fn try_as_slice_memory_order_mut(&mut self) -> Result<&mut [A], &mut Self>
1867    {
1868        if self.is_contiguous() {
1869            let offset = offset_from_low_addr_ptr_to_logical_ptr(self._dim(), self._strides());
1870            unsafe { Ok(slice::from_raw_parts_mut(self._ptr().sub(offset).as_ptr(), self.len())) }
1871        } else {
1872            Err(self)
1873        }
1874    }
1875
1876    /// Transform the array into `new_shape`; any shape with the same number of elements is
1877    /// accepted.
1878    ///
1879    /// `order` specifies the *logical* order in which the array is to be read and reshaped.
1880    /// The array is returned as a `CowArray`; a view if possible, otherwise an owned array.
1881    ///
1882    /// For example, when starting from the one-dimensional sequence 1 2 3 4 5 6, it would be
1883    /// understood as a 2 x 3 array in row major ("C") order this way:
1884    ///
1885    /// ```text
1886    /// 1 2 3
1887    /// 4 5 6
1888    /// ```
1889    ///
1890    /// and as 2 x 3 in column major ("F") order this way:
1891    ///
1892    /// ```text
1893    /// 1 3 5
1894    /// 2 4 6
1895    /// ```
1896    ///
1897    /// This example should show that any time we "reflow" the elements in the array to a different
1898    /// number of rows and columns (or more axes if applicable), it is important to pick an index
1899    /// ordering, and that's the reason for the function parameter for `order`.
1900    ///
1901    /// The `new_shape` parameter should be a dimension and an optional order like these examples:
1902    ///
1903    /// ```text
1904    /// (3, 4)                          // Shape 3 x 4 with default order (RowMajor)
1905    /// ((3, 4), Order::RowMajor))      // use specific order
1906    /// ((3, 4), Order::ColumnMajor))   // use specific order
1907    /// ((3, 4), Order::C))             // use shorthand for order - shorthands C and F
1908    /// ```
1909    ///
1910    /// **Errors** if the new shape doesn't have the same number of elements as the array's current
1911    /// shape.
1912    ///
1913    /// # Example
1914    ///
1915    /// ```
1916    /// use ndarray::array;
1917    /// use ndarray::Order;
1918    ///
1919    /// assert!(
1920    ///     array![1., 2., 3., 4., 5., 6.].to_shape(((2, 3), Order::RowMajor)).unwrap()
1921    ///     == array![[1., 2., 3.],
1922    ///               [4., 5., 6.]]
1923    /// );
1924    ///
1925    /// assert!(
1926    ///     array![1., 2., 3., 4., 5., 6.].to_shape(((2, 3), Order::ColumnMajor)).unwrap()
1927    ///     == array![[1., 3., 5.],
1928    ///               [2., 4., 6.]]
1929    /// );
1930    /// ```
1931    pub fn to_shape<E>(&self, new_shape: E) -> Result<CowArray<'_, A, E::Dim>, ShapeError>
1932    where
1933        E: ShapeArg,
1934        A: Clone,
1935    {
1936        let (shape, order) = new_shape.into_shape_and_order();
1937        self.to_shape_order(shape, order.unwrap_or(Order::RowMajor))
1938    }
1939
1940    fn to_shape_order<E>(&self, shape: E, order: Order) -> Result<CowArray<'_, A, E>, ShapeError>
1941    where
1942        E: Dimension,
1943        A: Clone,
1944    {
1945        let len = self._dim().size();
1946        if size_of_shape_checked(&shape) != Ok(len) {
1947            return Err(error::incompatible_shapes(self._dim(), &shape));
1948        }
1949
1950        // Create a view if the length is 0, safe because the array and new shape is empty.
1951        if len == 0 {
1952            unsafe {
1953                return Ok(CowArray::from(ArrayView::from_shape_ptr(shape, self.as_ptr())));
1954            }
1955        }
1956
1957        // Try to reshape the array as a view into the existing data
1958        match reshape_dim(self._dim(), self._strides(), &shape, order) {
1959            Ok(to_strides) => unsafe {
1960                return Ok(CowArray::from(ArrayView::new(*self._ptr(), shape, to_strides)));
1961            },
1962            Err(err) if err.kind() == ErrorKind::IncompatibleShape => {
1963                return Err(error::incompatible_shapes(self._dim(), &shape));
1964            }
1965            _otherwise => {}
1966        }
1967
1968        // otherwise create a new array and copy the elements
1969        unsafe {
1970            let (shape, view) = match order {
1971                Order::RowMajor => (shape.set_f(false), self.view()),
1972                Order::ColumnMajor => (shape.set_f(true), self.t()),
1973            };
1974            Ok(CowArray::from(Array::from_shape_trusted_iter_unchecked(shape, view.into_iter(), A::clone)))
1975        }
1976    }
1977}
1978
1979impl<A, S, D> ArrayBase<S, D>
1980where
1981    S: RawData<Elem = A>,
1982    D: Dimension,
1983{
1984    /// Transform the array into `shape`; any shape with the same number of
1985    /// elements is accepted, but the source array must be contiguous.
1986    ///
1987    /// If an index ordering is not specified, the default is `RowMajor`.
1988    /// The operation will only succeed if the array's memory layout is compatible with
1989    /// the index ordering, so that the array elements can be rearranged in place.
1990    ///
1991    /// If required use `.to_shape()` or `.into_shape_clone` instead for more flexible reshaping of
1992    /// arrays, which allows copying elements if required.
1993    ///
1994    /// **Errors** if the shapes don't have the same number of elements.<br>
1995    /// **Errors** if order RowMajor is given but input is not c-contiguous.
1996    /// **Errors** if order ColumnMajor is given but input is not f-contiguous.
1997    ///
1998    /// If shape is not given: use memory layout of incoming array. Row major arrays are
1999    /// reshaped using row major index ordering, column major arrays with column major index
2000    /// ordering.
2001    ///
2002    /// The `new_shape` parameter should be a dimension and an optional order like these examples:
2003    ///
2004    /// ```text
2005    /// (3, 4)                          // Shape 3 x 4 with default order (RowMajor)
2006    /// ((3, 4), Order::RowMajor))      // use specific order
2007    /// ((3, 4), Order::ColumnMajor))   // use specific order
2008    /// ((3, 4), Order::C))             // use shorthand for order - shorthands C and F
2009    /// ```
2010    ///
2011    /// # Example
2012    ///
2013    /// ```
2014    /// use ndarray::{aview1, aview2};
2015    /// use ndarray::Order;
2016    ///
2017    /// assert!(
2018    ///     aview1(&[1., 2., 3., 4.]).into_shape_with_order((2, 2)).unwrap()
2019    ///     == aview2(&[[1., 2.],
2020    ///                 [3., 4.]])
2021    /// );
2022    ///
2023    /// assert!(
2024    ///     aview1(&[1., 2., 3., 4.]).into_shape_with_order(((2, 2), Order::ColumnMajor)).unwrap()
2025    ///     == aview2(&[[1., 3.],
2026    ///                 [2., 4.]])
2027    /// );
2028    /// ```
2029    pub fn into_shape_with_order<E>(self, shape: E) -> Result<ArrayBase<S, E::Dim>, ShapeError>
2030    where E: ShapeArg
2031    {
2032        let (shape, order) = shape.into_shape_and_order();
2033        self.into_shape_with_order_impl(shape, order.unwrap_or(Order::RowMajor))
2034    }
2035
2036    fn into_shape_with_order_impl<E>(self, shape: E, order: Order) -> Result<ArrayBase<S, E>, ShapeError>
2037    where E: Dimension
2038    {
2039        let shape = shape.into_dimension();
2040        if size_of_shape_checked(&shape) != Ok(self.parts.dim.size()) {
2041            return Err(error::incompatible_shapes(&self.parts.dim, &shape));
2042        }
2043
2044        // Check if contiguous, then we can change shape
2045        unsafe {
2046            // safe because arrays are contiguous and len is unchanged
2047            match order {
2048                Order::RowMajor if self.is_standard_layout() =>
2049                    Ok(self.with_strides_dim(shape.default_strides(), shape)),
2050                Order::ColumnMajor if self.raw_view().reversed_axes().is_standard_layout() =>
2051                    Ok(self.with_strides_dim(shape.fortran_strides(), shape)),
2052                _otherwise => Err(error::from_kind(error::ErrorKind::IncompatibleLayout)),
2053            }
2054        }
2055    }
2056
2057    /// Transform the array into `shape`; any shape with the same number of
2058    /// elements is accepted, but the source array or view must be in standard
2059    /// or column-major (Fortran) layout.
2060    ///
2061    /// **Note** that `.into_shape()` "moves" elements differently depending on if the input array
2062    /// is C-contig or F-contig, it follows the index order that corresponds to the memory order.
2063    /// Prefer to use `.to_shape()` or `.into_shape_with_order()`.
2064    ///
2065    /// Because of this, the method **is deprecated**. That reshapes depend on memory order is not
2066    /// intuitive.
2067    ///
2068    /// **Errors** if the shapes don't have the same number of elements.<br>
2069    /// **Errors** if the input array is not c- or f-contiguous.
2070    ///
2071    /// ```
2072    /// use ndarray::{aview1, aview2};
2073    ///
2074    /// assert!(
2075    ///     aview1(&[1., 2., 3., 4.]).into_shape((2, 2)).unwrap()
2076    ///     == aview2(&[[1., 2.],
2077    ///                 [3., 4.]])
2078    /// );
2079    /// ```
2080    #[deprecated(note = "Use `.into_shape_with_order()` or `.to_shape()`", since = "0.16.0")]
2081    pub fn into_shape<E>(self, shape: E) -> Result<ArrayBase<S, E::Dim>, ShapeError>
2082    where E: IntoDimension
2083    {
2084        let shape = shape.into_dimension();
2085        if size_of_shape_checked(&shape) != Ok(self.parts.dim.size()) {
2086            return Err(error::incompatible_shapes(&self.parts.dim, &shape));
2087        }
2088        // Check if contiguous, if not => copy all, else just adapt strides
2089        unsafe {
2090            // safe because arrays are contiguous and len is unchanged
2091            if self.is_standard_layout() {
2092                Ok(self.with_strides_dim(shape.default_strides(), shape))
2093            } else if self.ndim() > 1 && self.raw_view().reversed_axes().is_standard_layout() {
2094                Ok(self.with_strides_dim(shape.fortran_strides(), shape))
2095            } else {
2096                Err(error::from_kind(error::ErrorKind::IncompatibleLayout))
2097            }
2098        }
2099    }
2100
2101    /// Transform the array into `shape`; any shape with the same number of
2102    /// elements is accepted. Array elements are reordered in place if
2103    /// possible, otherwise they are copied to create a new array.
2104    ///
2105    /// If an index ordering is not specified, the default is `RowMajor`.
2106    ///
2107    /// # `.to_shape` vs `.into_shape_clone`
2108    ///
2109    /// - `to_shape` supports views and outputting views
2110    /// - `to_shape` borrows the original array, `into_shape_clone` consumes the original
2111    /// - `into_shape_clone` preserves array type (Array vs ArcArray), but does not support views.
2112    ///
2113    /// **Errors** if the shapes don't have the same number of elements.<br>
2114    pub fn into_shape_clone<E>(self, shape: E) -> Result<ArrayBase<S, E::Dim>, ShapeError>
2115    where
2116        S: DataOwned,
2117        A: Clone,
2118        E: ShapeArg,
2119    {
2120        let (shape, order) = shape.into_shape_and_order();
2121        let order = order.unwrap_or(Order::RowMajor);
2122        self.into_shape_clone_order(shape, order)
2123    }
2124
2125    fn into_shape_clone_order<E>(self, shape: E, order: Order) -> Result<ArrayBase<S, E>, ShapeError>
2126    where
2127        S: DataOwned,
2128        A: Clone,
2129        E: Dimension,
2130    {
2131        let len = self._dim().size();
2132        if size_of_shape_checked(&shape) != Ok(len) {
2133            return Err(error::incompatible_shapes(self._dim(), &shape));
2134        }
2135
2136        // Safe because the array and new shape is empty.
2137        if len == 0 {
2138            unsafe {
2139                return Ok(self.with_strides_dim(shape.default_strides(), shape));
2140            }
2141        }
2142
2143        // Try to reshape the array's current data
2144        match reshape_dim(self._dim(), self._strides(), &shape, order) {
2145            Ok(to_strides) => unsafe {
2146                return Ok(self.with_strides_dim(to_strides, shape));
2147            },
2148            Err(err) if err.kind() == ErrorKind::IncompatibleShape => {
2149                return Err(error::incompatible_shapes(self._dim(), &shape));
2150            }
2151            _otherwise => {}
2152        }
2153
2154        // otherwise, clone and allocate a new array
2155        unsafe {
2156            let (shape, view) = match order {
2157                Order::RowMajor => (shape.set_f(false), self.view()),
2158                Order::ColumnMajor => (shape.set_f(true), self.t()),
2159            };
2160
2161            Ok(ArrayBase::from_shape_trusted_iter_unchecked(shape, view.into_iter(), A::clone))
2162        }
2163    }
2164
2165    /// *Note: Reshape is for `ArcArray` only. Use `.into_shape_with_order()` for
2166    /// other arrays and array views.*
2167    ///
2168    /// Transform the array into `shape`; any shape with the same number of
2169    /// elements is accepted.
2170    ///
2171    /// May clone all elements if needed to arrange elements in standard
2172    /// layout (and break sharing).
2173    ///
2174    /// **Panics** if shapes are incompatible.
2175    ///
2176    /// *This method is obsolete, because it is inflexible in how logical order
2177    /// of the array is handled. See [`ArrayRef::to_shape()`].*
2178    ///
2179    /// ```
2180    /// use ndarray::{rcarr1, rcarr2};
2181    ///
2182    /// assert!(
2183    ///     rcarr1(&[1., 2., 3., 4.]).reshape((2, 2))
2184    ///     == rcarr2(&[[1., 2.],
2185    ///                 [3., 4.]])
2186    /// );
2187    /// ```
2188    #[track_caller]
2189    #[deprecated(note = "Use `.into_shape_with_order()` or `.to_shape()`", since = "0.16.0")]
2190    pub fn reshape<E>(&self, shape: E) -> ArrayBase<S, E::Dim>
2191    where
2192        S: DataShared + DataOwned,
2193        A: Clone,
2194        E: IntoDimension,
2195    {
2196        let shape = shape.into_dimension();
2197        if size_of_shape_checked(&shape) != Ok(self._dim().size()) {
2198            panic!(
2199                "ndarray: incompatible shapes in reshape, attempted from: {:?}, to: {:?}",
2200                self._dim().slice(),
2201                shape.slice()
2202            )
2203        }
2204        // Check if contiguous, if not => copy all, else just adapt strides
2205        if self.is_standard_layout() {
2206            let cl = self.clone();
2207            // safe because array is contiguous and shape has equal number of elements
2208            unsafe { cl.with_strides_dim(shape.default_strides(), shape) }
2209        } else {
2210            let v = self.iter().cloned().collect::<Vec<A>>();
2211            unsafe { ArrayBase::from_shape_vec_unchecked(shape, v) }
2212        }
2213    }
2214}
2215
2216impl<A, D: Dimension> ArrayRef<A, D>
2217{
2218    /// Flatten the array to a one-dimensional array.
2219    ///
2220    /// The array is returned as a `CowArray`; a view if possible, otherwise an owned array.
2221    ///
2222    /// ```
2223    /// use ndarray::{arr1, arr3};
2224    ///
2225    /// let array = arr3(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
2226    /// let flattened = array.flatten();
2227    /// assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
2228    /// ```
2229    pub fn flatten(&self) -> CowArray<'_, A, Ix1>
2230    where A: Clone
2231    {
2232        self.flatten_with_order(Order::RowMajor)
2233    }
2234
2235    /// Flatten the array to a one-dimensional array.
2236    ///
2237    /// `order` specifies the *logical* order in which the array is to be read and reshaped.
2238    /// The array is returned as a `CowArray`; a view if possible, otherwise an owned array.
2239    ///
2240    /// ```
2241    /// use ndarray::{arr1, arr2};
2242    /// use ndarray::Order;
2243    ///
2244    /// let array = arr2(&[[1, 2], [3, 4], [5, 6], [7, 8]]);
2245    /// let flattened = array.flatten_with_order(Order::RowMajor);
2246    /// assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
2247    /// let flattened = array.flatten_with_order(Order::ColumnMajor);
2248    /// assert_eq!(flattened, arr1(&[1, 3, 5, 7, 2, 4, 6, 8]));
2249    /// ```
2250    pub fn flatten_with_order(&self, order: Order) -> CowArray<'_, A, Ix1>
2251    where A: Clone
2252    {
2253        self.to_shape((self.len(), order)).unwrap()
2254    }
2255}
2256
2257impl<A, S, D> ArrayBase<S, D>
2258where
2259    S: RawData<Elem = A>,
2260    D: Dimension,
2261{
2262    /// Flatten the array to a one-dimensional array, consuming the array.
2263    ///
2264    /// If possible, no copy is made, and the new array use the same memory as the original array.
2265    /// Otherwise, a new array is allocated and the elements are copied.
2266    ///
2267    /// ```
2268    /// use ndarray::{arr1, arr3};
2269    ///
2270    /// let array = arr3(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
2271    /// let flattened = array.into_flat();
2272    /// assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
2273    /// ```
2274    pub fn into_flat(self) -> ArrayBase<S, Ix1>
2275    where
2276        A: Clone,
2277        S: DataOwned,
2278    {
2279        let len = self.len();
2280        self.into_shape_clone(Ix1(len)).unwrap()
2281    }
2282
2283    /// Convert any array or array view to a dynamic dimensional array or
2284    /// array view (respectively).
2285    ///
2286    /// ```
2287    /// use ndarray::{arr2, ArrayD};
2288    ///
2289    /// let array: ArrayD<i32> = arr2(&[[1, 2],
2290    ///                                 [3, 4]]).into_dyn();
2291    /// ```
2292    pub fn into_dyn(self) -> ArrayBase<S, IxDyn>
2293    {
2294        // safe because new dims equivalent
2295        unsafe {
2296            ArrayBase::from_data_ptr(self.data, self.parts.ptr)
2297                .with_strides_dim(self.parts.strides.into_dyn(), self.parts.dim.into_dyn())
2298        }
2299    }
2300
2301    /// Convert an array or array view to another with the same type, but different dimensionality
2302    /// type. Errors if the dimensions don't agree (the number of axes must match).
2303    ///
2304    /// Note that conversion to a dynamic dimensional array will never fail (and is equivalent to
2305    /// the `into_dyn` method).
2306    ///
2307    /// ```
2308    /// use ndarray::{ArrayD, Ix2, IxDyn};
2309    ///
2310    /// // Create a dynamic dimensionality array and convert it to an Array2
2311    /// // (Ix2 dimension type).
2312    ///
2313    /// let array = ArrayD::<f64>::zeros(IxDyn(&[10, 10]));
2314    ///
2315    /// assert!(array.into_dimensionality::<Ix2>().is_ok());
2316    /// ```
2317    pub fn into_dimensionality<D2>(self) -> Result<ArrayBase<S, D2>, ShapeError>
2318    where D2: Dimension
2319    {
2320        unsafe {
2321            if D::NDIM == D2::NDIM {
2322                // safe because D == D2
2323                let dim = unlimited_transmute::<D, D2>(self.parts.dim);
2324                let strides = unlimited_transmute::<D, D2>(self.parts.strides);
2325                return Ok(ArrayBase::from_data_ptr(self.data, self.parts.ptr).with_strides_dim(strides, dim));
2326            } else if D::NDIM.is_none() || D2::NDIM.is_none() {
2327                // one is dynamic dim
2328                // safe because dim, strides are equivalent under a different type
2329                if let Some(dim) = D2::from_dimension(&self.parts.dim) {
2330                    if let Some(strides) = D2::from_dimension(&self.parts.strides) {
2331                        return Ok(self.with_strides_dim(strides, dim));
2332                    }
2333                }
2334            }
2335        }
2336        Err(ShapeError::from_kind(ErrorKind::IncompatibleShape))
2337    }
2338}
2339
2340impl<A, D: Dimension> ArrayRef<A, D>
2341{
2342    /// Act like a larger size and/or shape array by *broadcasting*
2343    /// into a larger shape, if possible.
2344    ///
2345    /// Return `None` if shapes can not be broadcast together.
2346    ///
2347    /// ***Background***
2348    ///
2349    ///  * Two axes are compatible if they are equal, or one of them is 1.
2350    ///  * In this instance, only the axes of the smaller side (self) can be 1.
2351    ///
2352    /// Compare axes beginning with the *last* axis of each shape.
2353    ///
2354    /// For example (1, 2, 4) can be broadcast into (7, 6, 2, 4)
2355    /// because its axes are either equal or 1 (or missing);
2356    /// while (2, 2) can *not* be broadcast into (2, 4).
2357    ///
2358    /// The implementation creates a view with strides set to zero for the
2359    /// axes that are to be repeated.
2360    ///
2361    /// The broadcasting documentation for NumPy has more information.
2362    ///
2363    /// ```
2364    /// use ndarray::{aview1, aview2};
2365    ///
2366    /// assert!(
2367    ///     aview1(&[1., 0.]).broadcast((10, 2)).unwrap()
2368    ///     == aview2(&[[1., 0.]; 10])
2369    /// );
2370    /// ```
2371    pub fn broadcast<E>(&self, dim: E) -> Option<ArrayView<'_, A, E::Dim>>
2372    where E: IntoDimension
2373    {
2374        /// Return new stride when trying to grow `from` into shape `to`
2375        ///
2376        /// Broadcasting works by returning a "fake stride" where elements
2377        /// to repeat are in axes with 0 stride, so that several indexes point
2378        /// to the same element.
2379        ///
2380        /// **Note:** Cannot be used for mutable iterators, since repeating
2381        /// elements would create aliasing pointers.
2382        fn upcast<D: Dimension, E: Dimension>(to: &D, from: &E, stride: &E) -> Option<D>
2383        {
2384            // Make sure the product of non-zero axis lengths does not exceed
2385            // `isize::MAX`. This is the only safety check we need to perform
2386            // because all the other constraints of `ArrayBase` are guaranteed
2387            // to be met since we're starting from a valid `ArrayBase`.
2388            let _ = size_of_shape_checked(to).ok()?;
2389
2390            let mut new_stride = to.clone();
2391            // begin at the back (the least significant dimension)
2392            // size of the axis has to either agree or `from` has to be 1
2393            if to.ndim() < from.ndim() {
2394                return None;
2395            }
2396
2397            {
2398                let mut new_stride_iter = new_stride.slice_mut().iter_mut().rev();
2399                for ((er, es), dr) in from
2400                    .slice()
2401                    .iter()
2402                    .rev()
2403                    .zip(stride.slice().iter().rev())
2404                    .zip(new_stride_iter.by_ref())
2405                {
2406                    /* update strides */
2407                    if *dr == *er {
2408                        /* keep stride */
2409                        *dr = *es;
2410                    } else if *er == 1 {
2411                        /* dead dimension, zero stride */
2412                        *dr = 0
2413                    } else {
2414                        return None;
2415                    }
2416                }
2417
2418                /* set remaining strides to zero */
2419                for dr in new_stride_iter {
2420                    *dr = 0;
2421                }
2422            }
2423            Some(new_stride)
2424        }
2425        let dim = dim.into_dimension();
2426
2427        // Note: zero strides are safe precisely because we return an read-only view
2428        let broadcast_strides = upcast(&dim, self._dim(), self._strides())?;
2429        unsafe { Some(ArrayView::new(*self._ptr(), dim, broadcast_strides)) }
2430    }
2431
2432    /// For two arrays or views, find their common shape if possible and
2433    /// broadcast them as array views into that shape.
2434    ///
2435    /// Return `ShapeError` if their shapes can not be broadcast together.
2436    #[allow(clippy::type_complexity)]
2437    pub(crate) fn broadcast_with<'a, 'b, B, E>(
2438        &'a self, other: &'b ArrayRef<B, E>,
2439    ) -> Result<(ArrayView<'a, A, DimMaxOf<D, E>>, ArrayView<'b, B, DimMaxOf<D, E>>), ShapeError>
2440    where
2441        D: Dimension + DimMax<E>,
2442        E: Dimension,
2443    {
2444        let shape = co_broadcast::<D, E, <D as DimMax<E>>::Output>(self._dim(), other._dim())?;
2445        let view1 = if shape.slice() == self._dim().slice() {
2446            self.view()
2447                .into_dimensionality::<<D as DimMax<E>>::Output>()
2448                .unwrap()
2449        } else if let Some(view1) = self.broadcast(shape.clone()) {
2450            view1
2451        } else {
2452            return Err(from_kind(ErrorKind::IncompatibleShape));
2453        };
2454        let view2 = if shape.slice() == other._dim().slice() {
2455            other
2456                .view()
2457                .into_dimensionality::<<D as DimMax<E>>::Output>()
2458                .unwrap()
2459        } else if let Some(view2) = other.broadcast(shape) {
2460            view2
2461        } else {
2462            return Err(from_kind(ErrorKind::IncompatibleShape));
2463        };
2464        Ok((view1, view2))
2465    }
2466}
2467
2468impl<A, D: Dimension> LayoutRef<A, D>
2469{
2470    /// Swap axes `ax` and `bx`.
2471    ///
2472    /// This does not move any data, it just adjusts the array’s dimensions
2473    /// and strides.
2474    ///
2475    /// **Panics** if the axes are out of bounds.
2476    ///
2477    /// ```
2478    /// use ndarray::arr2;
2479    ///
2480    /// let mut a = arr2(&[[1., 2., 3.]]);
2481    /// a.swap_axes(0, 1);
2482    /// assert!(
2483    ///     a == arr2(&[[1.], [2.], [3.]])
2484    /// );
2485    /// ```
2486    #[track_caller]
2487    pub fn swap_axes(&mut self, ax: usize, bx: usize)
2488    {
2489        self.0.dim.slice_mut().swap(ax, bx);
2490        self.0.strides.slice_mut().swap(ax, bx);
2491    }
2492}
2493
2494impl<A, S, D> ArrayBase<S, D>
2495where
2496    S: RawData<Elem = A>,
2497    D: Dimension,
2498{
2499    /// Permute the axes.
2500    ///
2501    /// This does not move any data, it just adjusts the array’s dimensions
2502    /// and strides.
2503    ///
2504    /// *i* in the *j*-th place in the axes sequence means `self`'s *i*-th axis
2505    /// becomes `self.permuted_axes()`'s *j*-th axis
2506    ///
2507    /// **Panics** if any of the axes are out of bounds, if an axis is missing,
2508    /// or if an axis is repeated more than once.
2509    ///
2510    /// # Examples
2511    ///
2512    /// ```
2513    /// use ndarray::{arr2, Array3};
2514    ///
2515    /// let a = arr2(&[[0, 1], [2, 3]]);
2516    /// assert_eq!(a.view().permuted_axes([1, 0]), a.t());
2517    ///
2518    /// let b = Array3::<u8>::zeros((1, 2, 3));
2519    /// assert_eq!(b.permuted_axes([1, 0, 2]).shape(), &[2, 1, 3]);
2520    /// ```
2521    #[track_caller]
2522    pub fn permuted_axes<T>(self, axes: T) -> ArrayBase<S, D>
2523    where T: IntoDimension<Dim = D>
2524    {
2525        let axes = axes.into_dimension();
2526        // Ensure that each axis is used exactly once.
2527        let mut usage_counts = D::zeros(self.ndim());
2528        for axis in axes.slice() {
2529            usage_counts[*axis] += 1;
2530        }
2531        for count in usage_counts.slice() {
2532            assert_eq!(*count, 1, "each axis must be listed exactly once");
2533        }
2534        // Determine the new shape and strides.
2535        let mut new_dim = usage_counts; // reuse to avoid an allocation
2536        let mut new_strides = D::zeros(self.ndim());
2537        {
2538            let dim = self.parts.dim.slice();
2539            let strides = self.parts.strides.slice();
2540            for (new_axis, &axis) in axes.slice().iter().enumerate() {
2541                new_dim[new_axis] = dim[axis];
2542                new_strides[new_axis] = strides[axis];
2543            }
2544        }
2545        // safe because axis invariants are checked above; they are a permutation of the old
2546        unsafe { self.with_strides_dim(new_strides, new_dim) }
2547    }
2548
2549    /// Permute the axes in-place.
2550    ///
2551    /// This does not move any data, it just adjusts the array's dimensions
2552    /// and strides.
2553    ///
2554    /// *i* in the *j*-th place in the axes sequence means `self`'s *i*-th axis
2555    /// becomes `self`'s *j*-th axis
2556    ///
2557    /// **Panics** if any of the axes are out of bounds, if an axis is missing,
2558    /// or if an axis is repeated more than once.    
2559    ///
2560    /// # Example
2561    /// ```rust
2562    /// use ndarray::{arr2, Array3};
2563    ///
2564    /// let mut a = arr2(&[[0, 1], [2, 3]]);
2565    /// a.permute_axes([1, 0]);
2566    /// assert_eq!(a, arr2(&[[0, 2], [1, 3]]));
2567    ///
2568    /// let mut b = Array3::<u8>::zeros((1, 2, 3));
2569    /// b.permute_axes([1, 0, 2]);
2570    /// assert_eq!(b.shape(), &[2, 1, 3]);
2571    /// ```
2572    #[track_caller]
2573    pub fn permute_axes<T>(&mut self, axes: T)
2574    where T: IntoDimension<Dim = D>
2575    {
2576        let axes = axes.into_dimension();
2577        // Ensure that each axis is used exactly once.
2578        let mut usage_counts = D::zeros(self.ndim());
2579        for axis in axes.slice() {
2580            usage_counts[*axis] += 1;
2581        }
2582        for count in usage_counts.slice() {
2583            assert_eq!(*count, 1, "each axis must be listed exactly once");
2584        }
2585
2586        let dim = self.parts.dim.slice_mut();
2587        let strides = self.parts.strides.slice_mut();
2588        let axes = axes.slice();
2589
2590        // The cycle detection is done using a bitmask to track visited positions.
2591        // For example, axes from [0,1,2] to [2, 0, 1]
2592        // For axis values [1, 0, 2]:
2593        // 1 << 1  // 0b0001 << 1 = 0b0010 (decimal 2)
2594        // 1 << 0  // 0b0001 << 0 = 0b0001 (decimal 1)
2595        // 1 << 2  // 0b0001 << 2 = 0b0100 (decimal 4)
2596        //
2597        // Each axis gets its own unique bit position in the bitmask:
2598        // - Axis 0: bit 0 (rightmost)
2599        // - Axis 1: bit 1
2600        // - Axis 2: bit 2
2601        //
2602        let mut visited = 0usize;
2603        for (new_axis, &axis) in axes.iter().enumerate() {
2604            if (visited & (1 << axis)) != 0 {
2605                continue;
2606            }
2607
2608            dim.swap(axis, new_axis);
2609            strides.swap(axis, new_axis);
2610
2611            visited |= (1 << axis) | (1 << new_axis);
2612        }
2613    }
2614
2615    /// Transpose the array by reversing axes.
2616    ///
2617    /// Transposition reverses the order of the axes (dimensions and strides)
2618    /// while retaining the same data.
2619    pub fn reversed_axes(mut self) -> ArrayBase<S, D>
2620    {
2621        self.parts.dim.slice_mut().reverse();
2622        self.parts.strides.slice_mut().reverse();
2623        self
2624    }
2625
2626    /// Reverse the axes of the array in-place.
2627    ///
2628    /// This does not move any data, it just adjusts the array's dimensions
2629    /// and strides.
2630    pub fn reverse_axes(&mut self)
2631    {
2632        self.parts.dim.slice_mut().reverse();
2633        self.parts.strides.slice_mut().reverse();
2634    }
2635}
2636
2637impl<A, D: Dimension> ArrayRef<A, D>
2638{
2639    /// Return a transposed view of the array.
2640    ///
2641    /// This is a shorthand for `self.view().reversed_axes()`.
2642    ///
2643    /// See also the more general methods `.reversed_axes()` and `.swap_axes()`.
2644    pub fn t(&self) -> ArrayView<'_, A, D>
2645    {
2646        self.view().reversed_axes()
2647    }
2648}
2649
2650impl<A, D: Dimension> LayoutRef<A, D>
2651{
2652    /// Return an iterator over the length and stride of each axis.
2653    pub fn axes(&self) -> Axes<'_, D>
2654    {
2655        axes_of(self._dim(), self._strides())
2656    }
2657
2658    /*
2659    /// Return the axis with the least stride (by absolute value)
2660    pub fn min_stride_axis(&self) -> Axis {
2661        self._dim().min_stride_axis(self._strides())
2662    }
2663    */
2664
2665    /// Return the axis with the greatest stride (by absolute value),
2666    /// preferring axes with len > 1.
2667    pub fn max_stride_axis(&self) -> Axis
2668    {
2669        self._dim().max_stride_axis(self._strides())
2670    }
2671
2672    /// Reverse the stride of `axis`.
2673    ///
2674    /// ***Panics*** if the axis is out of bounds.
2675    #[track_caller]
2676    pub fn invert_axis(&mut self, axis: Axis)
2677    {
2678        unsafe {
2679            let s = self._strides().axis(axis) as Ixs;
2680            let m = self._dim().axis(axis);
2681            if m != 0 {
2682                self.0.ptr = self._ptr().offset(stride_offset(m - 1, s as Ix));
2683            }
2684            self.0.strides.set_axis(axis, (-s) as Ix);
2685        }
2686    }
2687
2688    /// If possible, merge in the axis `take` to `into`.
2689    ///
2690    /// Returns `true` iff the axes are now merged.
2691    ///
2692    /// This method merges the axes if movement along the two original axes
2693    /// (moving fastest along the `into` axis) can be equivalently represented
2694    /// as movement along one (merged) axis. Merging the axes preserves this
2695    /// order in the merged axis. If `take` and `into` are the same axis, then
2696    /// the axis is "merged" if its length is ≤ 1.
2697    ///
2698    /// If the return value is `true`, then the following hold:
2699    ///
2700    /// * The new length of the `into` axis is the product of the original
2701    ///   lengths of the two axes.
2702    ///
2703    /// * The new length of the `take` axis is 0 if the product of the original
2704    ///   lengths of the two axes is 0, and 1 otherwise.
2705    ///
2706    /// If the return value is `false`, then merging is not possible, and the
2707    /// original shape and strides have been preserved.
2708    ///
2709    /// Note that the ordering constraint means that if it's possible to merge
2710    /// `take` into `into`, it's usually not possible to merge `into` into
2711    /// `take`, and vice versa.
2712    ///
2713    /// ```
2714    /// use ndarray::Array3;
2715    /// use ndarray::Axis;
2716    ///
2717    /// let mut a = Array3::<f64>::zeros((2, 3, 4));
2718    /// assert!(a.merge_axes(Axis(1), Axis(2)));
2719    /// assert_eq!(a.shape(), &[2, 1, 12]);
2720    /// ```
2721    ///
2722    /// ***Panics*** if an axis is out of bounds.
2723    #[track_caller]
2724    pub fn merge_axes(&mut self, take: Axis, into: Axis) -> bool
2725    {
2726        let parts = &mut self.0;
2727        merge_axes(&mut parts.dim, &mut parts.strides, take, into)
2728    }
2729}
2730
2731impl<A, S, D> ArrayBase<S, D>
2732where
2733    S: RawData<Elem = A>,
2734    D: Dimension,
2735{
2736    /// Insert new array axis at `axis` and return the result.
2737    ///
2738    /// ```
2739    /// use ndarray::{Array3, Axis, arr1, arr2};
2740    ///
2741    /// // Convert a 1-D array into a row vector (2-D).
2742    /// let a = arr1(&[1, 2, 3]);
2743    /// let row = a.insert_axis(Axis(0));
2744    /// assert_eq!(row, arr2(&[[1, 2, 3]]));
2745    ///
2746    /// // Convert a 1-D array into a column vector (2-D).
2747    /// let b = arr1(&[1, 2, 3]);
2748    /// let col = b.insert_axis(Axis(1));
2749    /// assert_eq!(col, arr2(&[[1], [2], [3]]));
2750    ///
2751    /// // The new axis always has length 1.
2752    /// let b = Array3::<f64>::zeros((3, 4, 5));
2753    /// assert_eq!(b.insert_axis(Axis(2)).shape(), &[3, 4, 1, 5]);
2754    /// ```
2755    ///
2756    /// ***Panics*** if the axis is out of bounds.
2757    #[track_caller]
2758    pub fn insert_axis(self, axis: Axis) -> ArrayBase<S, D::Larger>
2759    {
2760        assert!(axis.index() <= self.ndim());
2761        // safe because a new axis of length one does not affect memory layout
2762        unsafe {
2763            let strides = self.parts.strides.insert_axis(axis);
2764            let dim = self.parts.dim.insert_axis(axis);
2765            self.with_strides_dim(strides, dim)
2766        }
2767    }
2768
2769    /// Remove array axis `axis` and return the result.
2770    ///
2771    /// This is equivalent to `.index_axis_move(axis, 0)` and makes most sense to use if the
2772    /// axis to remove is of length 1.
2773    ///
2774    /// **Panics** if the axis is out of bounds or its length is zero.
2775    #[track_caller]
2776    pub fn remove_axis(self, axis: Axis) -> ArrayBase<S, D::Smaller>
2777    where D: RemoveAxis
2778    {
2779        self.index_axis_move(axis, 0)
2780    }
2781
2782    pub(crate) fn pointer_is_inbounds(&self) -> bool
2783    {
2784        self.data._is_pointer_inbounds(self.as_ptr())
2785    }
2786}
2787
2788impl<A, D: Dimension> ArrayRef<A, D>
2789{
2790    /// Perform an elementwise assignment to `self` from `rhs`.
2791    ///
2792    /// If their shapes disagree, `rhs` is broadcast to the shape of `self`.
2793    ///
2794    /// **Panics** if broadcasting isn’t possible.
2795    #[track_caller]
2796    pub fn assign<E: Dimension>(&mut self, rhs: &ArrayRef<A, E>)
2797    where A: Clone
2798    {
2799        self.zip_mut_with(rhs, |x, y| x.clone_from(y));
2800    }
2801
2802    /// Perform an elementwise assignment of values cloned from `self` into array or producer `to`.
2803    ///
2804    /// The destination `to` can be another array or a producer of assignable elements.
2805    /// [`AssignElem`] determines how elements are assigned.
2806    ///
2807    /// **Panics** if shapes disagree.
2808    #[track_caller]
2809    pub fn assign_to<P>(&self, to: P)
2810    where
2811        P: IntoNdProducer<Dim = D>,
2812        P::Item: AssignElem<A>,
2813        A: Clone,
2814    {
2815        Zip::from(self).map_assign_into(to, A::clone);
2816    }
2817
2818    /// Perform an elementwise assignment to `self` from element `x`.
2819    pub fn fill(&mut self, x: A)
2820    where A: Clone
2821    {
2822        self.map_inplace(move |elt| elt.clone_from(&x));
2823    }
2824
2825    pub(crate) fn zip_mut_with_same_shape<B, E, F>(&mut self, rhs: &ArrayRef<B, E>, mut f: F)
2826    where
2827        E: Dimension,
2828        F: FnMut(&mut A, &B),
2829    {
2830        debug_assert_eq!(self.shape(), rhs.shape());
2831
2832        if self
2833            ._dim()
2834            .strides_equivalent(self._strides(), rhs._strides())
2835        {
2836            if let Some(self_s) = self.as_slice_memory_order_mut() {
2837                if let Some(rhs_s) = rhs.as_slice_memory_order() {
2838                    for (s, r) in self_s.iter_mut().zip(rhs_s) {
2839                        f(s, r);
2840                    }
2841                    return;
2842                }
2843            }
2844        }
2845
2846        // Otherwise, fall back to the outer iter
2847        self.zip_mut_with_by_rows(rhs, f);
2848    }
2849
2850    // zip two arrays where they have different layout or strides
2851    #[inline(always)]
2852    fn zip_mut_with_by_rows<B, E, F>(&mut self, rhs: &ArrayRef<B, E>, mut f: F)
2853    where
2854        E: Dimension,
2855        F: FnMut(&mut A, &B),
2856    {
2857        debug_assert_eq!(self.shape(), rhs.shape());
2858        debug_assert_ne!(self.ndim(), 0);
2859
2860        // break the arrays up into their inner rows
2861        let n = self.ndim();
2862        let dim = self.raw_dim();
2863        Zip::from(LanesMut::new(self.view_mut(), Axis(n - 1)))
2864            .and(Lanes::new(rhs.broadcast_assume(dim), Axis(n - 1)))
2865            .for_each(move |s_row, r_row| Zip::from(s_row).and(r_row).for_each(&mut f));
2866    }
2867
2868    fn zip_mut_with_elem<B, F>(&mut self, rhs_elem: &B, mut f: F)
2869    where F: FnMut(&mut A, &B)
2870    {
2871        self.map_inplace(move |elt| f(elt, rhs_elem));
2872    }
2873
2874    /// Traverse two arrays in unspecified order, in lock step,
2875    /// calling the closure `f` on each element pair.
2876    ///
2877    /// If their shapes disagree, `rhs` is broadcast to the shape of `self`.
2878    ///
2879    /// **Panics** if broadcasting isn’t possible.
2880    #[track_caller]
2881    #[inline]
2882    pub fn zip_mut_with<B, E, F>(&mut self, rhs: &ArrayRef<B, E>, f: F)
2883    where
2884        E: Dimension,
2885        F: FnMut(&mut A, &B),
2886    {
2887        if rhs._dim().ndim() == 0 {
2888            // Skip broadcast from 0-dim array
2889            self.zip_mut_with_elem(rhs.get_0d(), f);
2890        } else if self._dim().ndim() == rhs._dim().ndim() && self.shape() == rhs.shape() {
2891            self.zip_mut_with_same_shape(rhs, f);
2892        } else {
2893            let rhs_broadcast = rhs.broadcast_unwrap(self.raw_dim());
2894            self.zip_mut_with_by_rows(&rhs_broadcast, f);
2895        }
2896    }
2897
2898    /// Traverse the array elements and apply a fold,
2899    /// returning the resulting value.
2900    ///
2901    /// Elements are visited in arbitrary order.
2902    pub fn fold<'a, F, B>(&'a self, init: B, f: F) -> B
2903    where
2904        F: FnMut(B, &'a A) -> B,
2905        A: 'a,
2906    {
2907        if let Some(slc) = self.as_slice_memory_order() {
2908            slc.iter().fold(init, f)
2909        } else {
2910            let mut v = self.view();
2911            move_min_stride_axis_to_last(&mut v.parts.dim, &mut v.parts.strides);
2912            v.into_elements_base().fold(init, f)
2913        }
2914    }
2915
2916    /// Call `f` by reference on each element and create a new array
2917    /// with the new values.
2918    ///
2919    /// Elements are visited in arbitrary order.
2920    ///
2921    /// Return an array with the same shape as `self`.
2922    ///
2923    /// ```
2924    /// use ndarray::arr2;
2925    ///
2926    /// let a = arr2(&[[ 0., 1.],
2927    ///                [-1., 2.]]);
2928    /// assert!(
2929    ///     a.map(|x| *x >= 1.0)
2930    ///     == arr2(&[[false, true],
2931    ///               [false, true]])
2932    /// );
2933    /// ```
2934    pub fn map<'a, B, F>(&'a self, f: F) -> Array<B, D>
2935    where
2936        F: FnMut(&'a A) -> B,
2937        A: 'a,
2938    {
2939        unsafe {
2940            if let Some(slc) = self.as_slice_memory_order() {
2941                ArrayBase::from_shape_trusted_iter_unchecked(
2942                    self._dim().clone().strides(self._strides().clone()),
2943                    slc.iter(),
2944                    f,
2945                )
2946            } else {
2947                ArrayBase::from_shape_trusted_iter_unchecked(self._dim().clone(), self.iter(), f)
2948            }
2949        }
2950    }
2951
2952    /// Call `f` on a mutable reference of each element and create a new array
2953    /// with the new values.
2954    ///
2955    /// Elements are visited in arbitrary order.
2956    ///
2957    /// Return an array with the same shape as `self`.
2958    pub fn map_mut<'a, B, F>(&'a mut self, f: F) -> Array<B, D>
2959    where
2960        F: FnMut(&'a mut A) -> B,
2961        A: 'a,
2962    {
2963        let dim = self._dim().clone();
2964        if self.is_contiguous() {
2965            let strides = self._strides().clone();
2966            let slc = self.as_slice_memory_order_mut().unwrap();
2967            unsafe { ArrayBase::from_shape_trusted_iter_unchecked(dim.strides(strides), slc.iter_mut(), f) }
2968        } else {
2969            unsafe { ArrayBase::from_shape_trusted_iter_unchecked(dim, self.iter_mut(), f) }
2970        }
2971    }
2972
2973    /// Call `f` by **v**alue on each element and create a new array
2974    /// with the new values.
2975    ///
2976    /// Elements are visited in arbitrary order.
2977    ///
2978    /// Return an array with the same shape as `self`.
2979    ///
2980    /// ```
2981    /// use ndarray::arr2;
2982    ///
2983    /// let a = arr2(&[[ 0., 1.],
2984    ///                [-1., 2.]]);
2985    /// assert!(
2986    ///     a.mapv(f32::abs) == arr2(&[[0., 1.],
2987    ///                                [1., 2.]])
2988    /// );
2989    /// ```
2990    pub fn mapv<B, F>(&self, mut f: F) -> Array<B, D>
2991    where
2992        F: FnMut(A) -> B,
2993        A: Clone,
2994    {
2995        self.map(move |x| f(x.clone()))
2996    }
2997}
2998
2999impl<A, S, D> ArrayBase<S, D>
3000where
3001    S: RawData<Elem = A>,
3002    D: Dimension,
3003{
3004    /// Call `f` by **v**alue on each element, update the array with the new values
3005    /// and return it.
3006    ///
3007    /// Elements are visited in arbitrary order.
3008    pub fn mapv_into<F>(mut self, f: F) -> Self
3009    where
3010        S: DataMut,
3011        F: FnMut(A) -> A,
3012        A: Clone,
3013    {
3014        self.mapv_inplace(f);
3015        self
3016    }
3017
3018    /// Consume the array, call `f` by **v**alue on each element, and return an
3019    /// owned array with the new values. Works for **any** `F: FnMut(A)->B`.
3020    ///
3021    /// If `A` and `B` are the same type then the map is performed by delegating
3022    /// to [`mapv_into`] and then converting into an owned array. This avoids
3023    /// unnecessary memory allocations in [`mapv`].
3024    ///
3025    /// If `A` and `B` are different types then a new array is allocated and the
3026    /// map is performed as in [`mapv`].
3027    ///
3028    /// Elements are visited in arbitrary order.
3029    ///
3030    /// [`mapv_into`]: ArrayBase::mapv_into
3031    /// [`mapv`]: ArrayRef::mapv
3032    pub fn mapv_into_any<B, F>(self, mut f: F) -> Array<B, D>
3033    where
3034        S: DataMut,
3035        F: FnMut(A) -> B,
3036        A: Clone + 'static,
3037        B: 'static,
3038    {
3039        if core::any::TypeId::of::<A>() == core::any::TypeId::of::<B>() {
3040            // A and B are the same type.
3041            // Wrap f in a closure of type FnMut(A) -> A .
3042            let f = |a| {
3043                let b = f(a);
3044                // Safe because A and B are the same type.
3045                unsafe { unlimited_transmute::<B, A>(b) }
3046            };
3047            // Delegate to mapv_into() using the wrapped closure.
3048            // Convert output to a uniquely owned array of type Array<A, D>.
3049            let output = self.mapv_into(f).into_owned();
3050            // Change the return type from Array<A, D> to Array<B, D>.
3051            // Again, safe because A and B are the same type.
3052            unsafe { unlimited_transmute::<Array<A, D>, Array<B, D>>(output) }
3053        } else {
3054            // A and B are not the same type.
3055            // Fallback to mapv().
3056            self.mapv(f)
3057        }
3058    }
3059}
3060
3061impl<A, D: Dimension> ArrayRef<A, D>
3062{
3063    /// Modify the array in place by calling `f` by mutable reference on each element.
3064    ///
3065    /// Elements are visited in arbitrary order.
3066    pub fn map_inplace<'a, F>(&'a mut self, f: F)
3067    where
3068        A: 'a,
3069        F: FnMut(&'a mut A),
3070    {
3071        match self.try_as_slice_memory_order_mut() {
3072            Ok(slc) => slc.iter_mut().for_each(f),
3073            Err(arr) => {
3074                let mut v = arr.view_mut();
3075                move_min_stride_axis_to_last(&mut v.parts.dim, &mut v.parts.strides);
3076                v.into_elements_base().for_each(f);
3077            }
3078        }
3079    }
3080
3081    /// Modify the array in place by calling `f` by **v**alue on each element.
3082    /// The array is updated with the new values.
3083    ///
3084    /// Elements are visited in arbitrary order.
3085    ///
3086    /// ```
3087    /// # #[cfg(feature = "approx")] {
3088    /// use approx::assert_abs_diff_eq;
3089    /// use ndarray::arr2;
3090    ///
3091    /// let mut a = arr2(&[[ 0., 1.],
3092    ///                    [-1., 2.]]);
3093    /// a.mapv_inplace(f32::exp);
3094    /// assert_abs_diff_eq!(
3095    ///     a,
3096    ///     arr2(&[[1.00000, 2.71828],
3097    ///            [0.36788, 7.38906]]),
3098    ///     epsilon = 1e-5,
3099    /// );
3100    /// # }
3101    /// ```
3102    pub fn mapv_inplace<F>(&mut self, mut f: F)
3103    where
3104        F: FnMut(A) -> A,
3105        A: Clone,
3106    {
3107        self.map_inplace(move |x| *x = f(x.clone()));
3108    }
3109
3110    /// Call `f` for each element in the array.
3111    ///
3112    /// Elements are visited in arbitrary order.
3113    pub fn for_each<'a, F>(&'a self, mut f: F)
3114    where
3115        F: FnMut(&'a A),
3116        A: 'a,
3117    {
3118        self.fold((), move |(), elt| f(elt))
3119    }
3120
3121    /// Fold along an axis.
3122    ///
3123    /// Combine the elements of each subview with the previous using the `fold`
3124    /// function and initial value `init`.
3125    ///
3126    /// Return the result as an `Array`.
3127    ///
3128    /// **Panics** if `axis` is out of bounds.
3129    #[track_caller]
3130    pub fn fold_axis<B, F>(&self, axis: Axis, init: B, mut fold: F) -> Array<B, D::Smaller>
3131    where
3132        D: RemoveAxis,
3133        F: FnMut(&B, &A) -> B,
3134        B: Clone,
3135    {
3136        let mut res = Array::from_elem(self.raw_dim().remove_axis(axis), init);
3137        for subview in self.axis_iter(axis) {
3138            res.zip_mut_with(&subview, |x, y| *x = fold(x, y));
3139        }
3140        res
3141    }
3142
3143    /// Reduce the values along an axis into just one value, producing a new
3144    /// array with one less dimension.
3145    ///
3146    /// Elements are visited in arbitrary order.
3147    ///
3148    /// Return the result as an `Array`.
3149    ///
3150    /// **Panics** if `axis` is out of bounds.
3151    #[track_caller]
3152    pub fn map_axis<'a, B, F>(&'a self, axis: Axis, mut mapping: F) -> Array<B, D::Smaller>
3153    where
3154        D: RemoveAxis,
3155        F: FnMut(ArrayView1<'a, A>) -> B,
3156        A: 'a,
3157    {
3158        if self.len_of(axis) == 0 {
3159            let new_dim = self._dim().remove_axis(axis);
3160            Array::from_shape_simple_fn(new_dim, move || mapping(ArrayView::from(&[])))
3161        } else {
3162            Zip::from(self.lanes(axis)).map_collect(mapping)
3163        }
3164    }
3165
3166    /// Reduce the values along an axis into just one value, producing a new
3167    /// array with one less dimension.
3168    /// 1-dimensional lanes are passed as mutable references to the reducer,
3169    /// allowing for side-effects.
3170    ///
3171    /// Elements are visited in arbitrary order.
3172    ///
3173    /// Return the result as an `Array`.
3174    ///
3175    /// **Panics** if `axis` is out of bounds.
3176    #[track_caller]
3177    pub fn map_axis_mut<'a, B, F>(&'a mut self, axis: Axis, mut mapping: F) -> Array<B, D::Smaller>
3178    where
3179        D: RemoveAxis,
3180        F: FnMut(ArrayViewMut1<'a, A>) -> B,
3181        A: 'a,
3182    {
3183        if self.len_of(axis) == 0 {
3184            let new_dim = self._dim().remove_axis(axis);
3185            Array::from_shape_simple_fn(new_dim, move || mapping(ArrayViewMut::from(&mut [])))
3186        } else {
3187            Zip::from(self.lanes_mut(axis)).map_collect(mapping)
3188        }
3189    }
3190
3191    /// Remove the `index`th elements along `axis` and shift down elements from higher indexes.
3192    ///
3193    /// Note that this "removes" the elements by swapping them around to the end of the axis and
3194    /// shortening the length of the axis; the elements are not deinitialized or dropped by this,
3195    /// just moved out of view (this only matters for elements with ownership semantics). It's
3196    /// similar to slicing an owned array in place.
3197    ///
3198    /// Decreases the length of `axis` by one.
3199    ///
3200    /// ***Panics*** if `axis` is out of bounds<br>
3201    /// ***Panics*** if not `index < self.len_of(axis)`.
3202    pub fn remove_index(&mut self, axis: Axis, index: usize)
3203    {
3204        assert!(index < self.len_of(axis), "index {} must be less than length of Axis({})", index, axis.index());
3205        let (_, mut tail) = self.view_mut().split_at(axis, index);
3206        // shift elements to the front
3207        Zip::from(tail.lanes_mut(axis)).for_each(|mut lane| lane.rotate1_front());
3208        // then slice the axis in place to cut out the removed final element
3209        self.slice_axis_inplace(axis, Slice::new(0, Some(-1), 1));
3210    }
3211}
3212
3213impl<A, D: Dimension> ArrayRef<A, D>
3214{
3215    /// Iterates over pairs of consecutive elements along the axis.
3216    ///
3217    /// The first argument to the closure is an element, and the second
3218    /// argument is the next element along the axis. Iteration is guaranteed to
3219    /// proceed in order along the specified axis, but in all other respects
3220    /// the iteration order is unspecified.
3221    ///
3222    /// # Example
3223    ///
3224    /// For example, this can be used to compute the cumulative sum along an
3225    /// axis:
3226    ///
3227    /// ```
3228    /// use ndarray::{array, Axis};
3229    ///
3230    /// let mut arr = array![
3231    ///     [[1, 2], [3, 4], [5, 6]],
3232    ///     [[7, 8], [9, 10], [11, 12]],
3233    /// ];
3234    /// arr.accumulate_axis_inplace(Axis(1), |&prev, curr| *curr += prev);
3235    /// assert_eq!(
3236    ///     arr,
3237    ///     array![
3238    ///         [[1, 2], [4, 6], [9, 12]],
3239    ///         [[7, 8], [16, 18], [27, 30]],
3240    ///     ],
3241    /// );
3242    /// ```
3243    pub fn accumulate_axis_inplace<F>(&mut self, axis: Axis, mut f: F)
3244    where F: FnMut(&A, &mut A)
3245    {
3246        if self.len_of(axis) <= 1 {
3247            return;
3248        }
3249        let mut curr = self.raw_view_mut(); // mut borrow of the array here
3250        let mut prev = curr.raw_view(); // derive further raw views from the same borrow
3251        prev.slice_axis_inplace(axis, Slice::from(..-1));
3252        curr.slice_axis_inplace(axis, Slice::from(1..));
3253        // This implementation relies on `Zip` iterating along `axis` in order.
3254        Zip::from(prev).and(curr).for_each(|prev, curr| unsafe {
3255            // These pointer dereferences and borrows are safe because:
3256            //
3257            // 1. They're pointers to elements in the array.
3258            //
3259            // 2. `S: DataMut` guarantees that elements are safe to borrow
3260            //    mutably and that they don't alias.
3261            //
3262            // 3. The lifetimes of the borrows last only for the duration
3263            //    of the call to `f`, so aliasing across calls to `f`
3264            //    cannot occur.
3265            f(&*prev, &mut *curr)
3266        });
3267    }
3268
3269    /// Return a partitioned copy of the array.
3270    ///
3271    /// Creates a copy of the array and partially sorts it around the k-th element along the given axis.
3272    /// The k-th element will be in its sorted position, with:
3273    /// - All elements smaller than the k-th element to its left
3274    /// - All elements equal or greater than the k-th element to its right
3275    /// - The ordering within each partition is undefined
3276    ///
3277    /// Empty arrays (i.e., those with any zero-length axes) are considered partitioned already,
3278    /// and will be returned unchanged.
3279    ///
3280    /// **Panics** if `k` is out of bounds for a non-zero axis length.
3281    ///
3282    /// # Parameters
3283    ///
3284    /// * `kth` - Index to partition by. The k-th element will be in its sorted position.
3285    /// * `axis` - Axis along which to partition.
3286    ///
3287    /// # Examples
3288    ///
3289    /// ```
3290    /// use ndarray::prelude::*;
3291    ///
3292    /// let a = array![7, 1, 5, 2, 6, 0, 3, 4];
3293    /// let p = a.partition(3, Axis(0));
3294    ///
3295    /// // The element at position 3 is now 3, with smaller elements to the left
3296    /// // and greater elements to the right
3297    /// assert_eq!(p[3], 3);
3298    /// assert!(p.slice(s![..3]).iter().all(|&x| x <= 3));
3299    /// assert!(p.slice(s![4..]).iter().all(|&x| x >= 3));
3300    /// ```
3301    pub fn partition(&self, kth: usize, axis: Axis) -> Array<A, D>
3302    where
3303        A: Clone + Ord + num_traits::Zero,
3304        D: Dimension,
3305    {
3306        let mut result = self.to_owned();
3307
3308        // Return early if the array has zero-length dimensions
3309        if result.shape().contains(&0) {
3310            return result;
3311        }
3312
3313        // Bounds checking. Panics if kth is out of bounds
3314        let axis_len = self.len_of(axis);
3315        if kth >= axis_len {
3316            panic!("Partition index {} is out of bounds for axis {} of length {}", kth, axis.0, axis_len);
3317        }
3318
3319        // Check if the first lane is contiguous
3320        let is_contiguous = result
3321            .lanes_mut(axis)
3322            .into_iter()
3323            .next()
3324            // This unwrap shouldn't cause panics because the array isn't empty
3325            .unwrap()
3326            .is_contiguous();
3327
3328        if is_contiguous {
3329            result.lanes_mut(axis).into_iter().for_each(|mut lane| {
3330                lane.as_slice_mut().unwrap().select_nth_unstable(kth);
3331            });
3332        } else {
3333            let mut temp_vec = vec![A::zero(); axis_len];
3334
3335            Zip::from(result.lanes_mut(axis)).for_each(|mut lane| {
3336                Zip::from(&mut temp_vec).and(&lane).for_each(|dest, src| {
3337                    *dest = src.clone();
3338                });
3339
3340                temp_vec.select_nth_unstable(kth);
3341
3342                Zip::from(&mut lane).and(&temp_vec).for_each(|dest, src| {
3343                    *dest = src.clone();
3344                });
3345            });
3346        }
3347
3348        result
3349    }
3350}
3351
3352/// Transmute from A to B.
3353///
3354/// Like transmute, but does not have the compile-time size check which blocks
3355/// using regular transmute in some cases.
3356///
3357/// **Panics** if the size of A and B are different.
3358#[track_caller]
3359#[inline]
3360unsafe fn unlimited_transmute<A, B>(data: A) -> B
3361{
3362    // safe when sizes are equal and caller guarantees that representations are equal
3363    assert_eq!(size_of::<A>(), size_of::<B>());
3364    let old_data = ManuallyDrop::new(data);
3365    (&*old_data as *const A as *const B).read()
3366}
3367
3368type DimMaxOf<A, B> = <A as DimMax<B>>::Output;
3369
3370#[cfg(test)]
3371mod tests
3372{
3373    use super::*;
3374    use crate::arr3;
3375    use defmac::defmac;
3376
3377    #[test]
3378    fn test_flatten()
3379    {
3380        let array = arr3(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
3381        let flattened = array.flatten();
3382        assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
3383    }
3384
3385    #[test]
3386    fn test_flatten_with_order()
3387    {
3388        let array = arr2(&[[1, 2], [3, 4], [5, 6], [7, 8]]);
3389        let flattened = array.flatten_with_order(Order::RowMajor);
3390        assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
3391        let flattened = array.flatten_with_order(Order::ColumnMajor);
3392        assert_eq!(flattened, arr1(&[1, 3, 5, 7, 2, 4, 6, 8]));
3393    }
3394
3395    #[test]
3396    fn test_into_flat()
3397    {
3398        let array = arr3(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
3399        let flattened = array.into_flat();
3400        assert_eq!(flattened, arr1(&[1, 2, 3, 4, 5, 6, 7, 8]));
3401    }
3402
3403    #[test]
3404    fn test_first_last()
3405    {
3406        let first = 2;
3407        let last = 3;
3408
3409        defmac!(assert_first mut array => {
3410            assert_eq!(array.first().copied(), Some(first));
3411            assert_eq!(array.first_mut().copied(), Some(first));
3412        });
3413        defmac!(assert_last mut array => {
3414            assert_eq!(array.last().copied(), Some(last));
3415            assert_eq!(array.last_mut().copied(), Some(last));
3416        });
3417
3418        let base = Array::from_vec(vec![first, last]);
3419        let a = base.clone();
3420        assert_first!(a);
3421
3422        let a = base.clone();
3423        assert_last!(a);
3424
3425        let a = CowArray::from(base.view());
3426        assert_first!(a);
3427        let a = CowArray::from(base.view());
3428        assert_last!(a);
3429
3430        let a = CowArray::from(base.clone());
3431        assert_first!(a);
3432        let a = CowArray::from(base.clone());
3433        assert_last!(a);
3434
3435        let a = ArcArray::from(base.clone());
3436        let _a2 = a.clone();
3437        assert_last!(a);
3438
3439        let a = ArcArray::from(base.clone());
3440        let _a2 = a.clone();
3441        assert_first!(a);
3442    }
3443
3444    #[test]
3445    fn test_partition_1d()
3446    {
3447        // Test partitioning a 1D array
3448        let array = arr1(&[3, 1, 4, 1, 5, 9, 2, 6]);
3449        let result = array.partition(3, Axis(0));
3450        // After partitioning, the element at index 3 should be in its final sorted position
3451        assert!(result.slice(s![..3]).iter().all(|&x| x <= result[3]));
3452        assert!(result.slice(s![4..]).iter().all(|&x| x >= result[3]));
3453    }
3454
3455    #[test]
3456    fn test_partition_2d()
3457    {
3458        // Test partitioning a 2D array along both axes
3459        let array = arr2(&[[3, 1, 4], [1, 5, 9], [2, 6, 5]]);
3460
3461        // Partition along axis 0 (rows)
3462        let result0 = array.partition(1, Axis(0));
3463        // After partitioning along axis 0, each column should have its middle element in the correct position
3464        assert!(result0[[0, 0]] <= result0[[1, 0]] && result0[[2, 0]] >= result0[[1, 0]]);
3465        assert!(result0[[0, 1]] <= result0[[1, 1]] && result0[[2, 1]] >= result0[[1, 1]]);
3466        assert!(result0[[0, 2]] <= result0[[1, 2]] && result0[[2, 2]] >= result0[[1, 2]]);
3467
3468        // Partition along axis 1 (columns)
3469        let result1 = array.partition(1, Axis(1));
3470        // After partitioning along axis 1, each row should have its middle element in the correct position
3471        assert!(result1[[0, 0]] <= result1[[0, 1]] && result1[[0, 2]] >= result1[[0, 1]]);
3472        assert!(result1[[1, 0]] <= result1[[1, 1]] && result1[[1, 2]] >= result1[[1, 1]]);
3473        assert!(result1[[2, 0]] <= result1[[2, 1]] && result1[[2, 2]] >= result1[[2, 1]]);
3474    }
3475
3476    #[test]
3477    fn test_partition_3d()
3478    {
3479        // Test partitioning a 3D array
3480        let array = arr3(&[[[3, 1], [4, 1]], [[5, 9], [2, 6]]]);
3481
3482        // Partition along axis 0
3483        let result = array.partition(0, Axis(0));
3484        // After partitioning, each 2x2 slice should have its first element in the correct position
3485        assert!(result[[0, 0, 0]] <= result[[1, 0, 0]]);
3486        assert!(result[[0, 0, 1]] <= result[[1, 0, 1]]);
3487        assert!(result[[0, 1, 0]] <= result[[1, 1, 0]]);
3488        assert!(result[[0, 1, 1]] <= result[[1, 1, 1]]);
3489    }
3490
3491    #[test]
3492    #[should_panic]
3493    fn test_partition_invalid_kth()
3494    {
3495        let a = array![1, 2, 3, 4];
3496        // This should panic because kth=4 is out of bounds
3497        let _ = a.partition(4, Axis(0));
3498    }
3499
3500    #[test]
3501    #[should_panic]
3502    fn test_partition_invalid_axis()
3503    {
3504        let a = array![1, 2, 3, 4];
3505        // This should panic because axis=1 is out of bounds for a 1D array
3506        let _ = a.partition(0, Axis(1));
3507    }
3508
3509    #[test]
3510    fn test_partition_contiguous_or_not()
3511    {
3512        // Test contiguous case (C-order)
3513        let a = array![[7, 1, 5], [2, 6, 0], [3, 4, 8]];
3514
3515        // Partition along axis 0 (contiguous)
3516        let p_axis0 = a.partition(1, Axis(0));
3517
3518        // For each column, verify the partitioning:
3519        // - First row should be <= middle row (kth element)
3520        // - Last row should be >= middle row (kth element)
3521        for col in 0..3 {
3522            let kth = p_axis0[[1, col]];
3523            assert!(
3524                p_axis0[[0, col]] <= kth,
3525                "Column {}: First row {} should be <= middle row {}",
3526                col,
3527                p_axis0[[0, col]],
3528                kth
3529            );
3530            assert!(
3531                p_axis0[[2, col]] >= kth,
3532                "Column {}: Last row {} should be >= middle row {}",
3533                col,
3534                p_axis0[[2, col]],
3535                kth
3536            );
3537        }
3538
3539        // Test non-contiguous case (F-order)
3540        let a = array![[7, 1, 5], [2, 6, 0], [3, 4, 8]];
3541
3542        // Make array non-contiguous by transposing
3543        let a = a.t().to_owned();
3544
3545        // Partition along axis 1 (non-contiguous)
3546        let p_axis1 = a.partition(1, Axis(1));
3547
3548        // For each row, verify the partitioning:
3549        // - First column should be <= middle column
3550        // - Last column should be >= middle column
3551        for row in 0..3 {
3552            assert!(
3553                p_axis1[[row, 0]] <= p_axis1[[row, 1]],
3554                "Row {}: First column {} should be <= middle column {}",
3555                row,
3556                p_axis1[[row, 0]],
3557                p_axis1[[row, 1]]
3558            );
3559            assert!(
3560                p_axis1[[row, 2]] >= p_axis1[[row, 1]],
3561                "Row {}: Last column {} should be >= middle column {}",
3562                row,
3563                p_axis1[[row, 2]],
3564                p_axis1[[row, 1]]
3565            );
3566        }
3567    }
3568
3569    #[test]
3570    fn test_partition_empty()
3571    {
3572        // Test 1D empty array
3573        let empty1d = Array1::<i32>::zeros(0);
3574        let result1d = empty1d.partition(0, Axis(0));
3575        assert_eq!(result1d.len(), 0);
3576
3577        // Test 1D empty array with kth out of bounds
3578        let result1d_out_of_bounds = empty1d.partition(1, Axis(0));
3579        assert_eq!(result1d_out_of_bounds.len(), 0);
3580
3581        // Test 2D empty array
3582        let empty2d = Array2::<i32>::zeros((0, 3));
3583        let result2d = empty2d.partition(0, Axis(0));
3584        assert_eq!(result2d.shape(), &[0, 3]);
3585
3586        // Test 2D empty array with zero columns
3587        let empty2d_cols = Array2::<i32>::zeros((2, 0));
3588        let result2d_cols = empty2d_cols.partition(0, Axis(1));
3589        assert_eq!(result2d_cols.shape(), &[2, 0]);
3590
3591        // Test 3D empty array
3592        let empty3d = Array3::<i32>::zeros((0, 2, 3));
3593        let result3d = empty3d.partition(0, Axis(0));
3594        assert_eq!(result3d.shape(), &[0, 2, 3]);
3595
3596        // Test 3D empty array with zero in middle dimension
3597        let empty3d_mid = Array3::<i32>::zeros((2, 0, 3));
3598        let result3d_mid = empty3d_mid.partition(0, Axis(1));
3599        assert_eq!(result3d_mid.shape(), &[2, 0, 3]);
3600
3601        // Test 4D empty array
3602        let empty4d = Array4::<i32>::zeros((0, 2, 3, 4));
3603        let result4d = empty4d.partition(0, Axis(0));
3604        assert_eq!(result4d.shape(), &[0, 2, 3, 4]);
3605
3606        // Test empty array with non-zero dimensions in other axes
3607        let empty_mixed = Array2::<i32>::zeros((0, 5));
3608        let result_mixed = empty_mixed.partition(0, Axis(0));
3609        assert_eq!(result_mixed.shape(), &[0, 5]);
3610
3611        // Test empty array with negative strides
3612        let arr = Array2::<i32>::zeros((3, 3));
3613        let empty_slice = arr.slice(s![0..0, ..]);
3614        let result_slice = empty_slice.partition(0, Axis(0));
3615        assert_eq!(result_slice.shape(), &[0, 3]);
3616    }
3617}