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 std::mem::{size_of, ManuallyDrop};
10use alloc::slice;
11use alloc::vec;
12use alloc::vec::Vec;
13use rawpointer::PointerExt;
14
15use crate::imp_prelude::*;
16
17use crate::{arraytraits, DimMax};
18use crate::argument_traits::AssignElem;
19use crate::dimension;
20use crate::dimension::IntoDimension;
21use crate::dimension::{
22    abs_index, axes_of, do_slice, merge_axes, move_min_stride_axis_to_last,
23    offset_from_ptr_to_memory, size_of_shape_checked, stride_offset, Axes,
24};
25use crate::dimension::broadcast::co_broadcast;
26use crate::error::{self, ErrorKind, ShapeError, from_kind};
27use crate::math_cell::MathCell;
28use crate::itertools::zip;
29use crate::zip::{IntoNdProducer, Zip};
30use crate::AxisDescription;
31
32use crate::iter::{
33    AxisChunksIter, AxisChunksIterMut, AxisIter, AxisIterMut, ExactChunks, ExactChunksMut,
34    IndexedIter, IndexedIterMut, Iter, IterMut, Lanes, LanesMut, Windows,
35};
36use crate::slice::{MultiSliceArg, SliceArg};
37use crate::stacking::concatenate;
38use crate::{NdIndex, Slice, SliceInfoElem};
39
40/// # Methods For All Array Types
41impl<A, S, D> ArrayBase<S, D>
42where
43    S: RawData<Elem = A>,
44    D: Dimension,
45{
46    /// Return the total number of elements in the array.
47    pub fn len(&self) -> usize {
48        self.dim.size()
49    }
50
51    /// Return the length of `axis`.
52    ///
53    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
54    /// number of dimensions (axes) of the array.
55    ///
56    /// ***Panics*** if the axis is out of bounds.
57    pub fn len_of(&self, axis: Axis) -> usize {
58        self.dim[axis.index()]
59    }
60
61    /// Return whether the array has any elements
62    pub fn is_empty(&self) -> bool {
63        self.len() == 0
64    }
65
66    /// Return the number of dimensions (axes) in the array
67    pub fn ndim(&self) -> usize {
68        self.dim.ndim()
69    }
70
71    /// Return the shape of the array in its “pattern” form,
72    /// an integer in the one-dimensional case, tuple in the n-dimensional cases
73    /// and so on.
74    pub fn dim(&self) -> D::Pattern {
75        self.dim.clone().into_pattern()
76    }
77
78    /// Return the shape of the array as it's stored in the array.
79    ///
80    /// This is primarily useful for passing to other `ArrayBase`
81    /// functions, such as when creating another array of the same
82    /// shape and dimensionality.
83    ///
84    /// ```
85    /// use ndarray::Array;
86    ///
87    /// let a = Array::from_elem((2, 3), 5.);
88    ///
89    /// // Create an array of zeros that's the same shape and dimensionality as `a`.
90    /// let b = Array::<f64, _>::zeros(a.raw_dim());
91    /// ```
92    pub fn raw_dim(&self) -> D {
93        self.dim.clone()
94    }
95
96    /// Return the shape of the array as a slice.
97    ///
98    /// Note that you probably don't want to use this to create an array of the
99    /// same shape as another array because creating an array with e.g.
100    /// [`Array::zeros()`](ArrayBase::zeros) using a shape of type `&[usize]`
101    /// results in a dynamic-dimensional array. If you want to create an array
102    /// that has the same shape and dimensionality as another array, use
103    /// [`.raw_dim()`](ArrayBase::raw_dim) instead:
104    ///
105    /// ```rust
106    /// use ndarray::{Array, Array2};
107    ///
108    /// let a = Array2::<i32>::zeros((3, 4));
109    /// let shape = a.shape();
110    /// assert_eq!(shape, &[3, 4]);
111    ///
112    /// // Since `a.shape()` returned `&[usize]`, we get an `ArrayD` instance:
113    /// let b = Array::zeros(shape);
114    /// assert_eq!(a.clone().into_dyn(), b);
115    ///
116    /// // To get the same dimension type, use `.raw_dim()` instead:
117    /// let c = Array::zeros(a.raw_dim());
118    /// assert_eq!(a, c);
119    /// ```
120    pub fn shape(&self) -> &[usize] {
121        self.dim.slice()
122    }
123
124    /// Return the strides of the array as a slice.
125    pub fn strides(&self) -> &[isize] {
126        let s = self.strides.slice();
127        // reinterpret unsigned integer as signed
128        unsafe { slice::from_raw_parts(s.as_ptr() as *const _, s.len()) }
129    }
130
131    /// Return the stride of `axis`.
132    ///
133    /// The axis should be in the range `Axis(` 0 .. *n* `)` where *n* is the
134    /// number of dimensions (axes) of the array.
135    ///
136    /// ***Panics*** if the axis is out of bounds.
137    pub fn stride_of(&self, axis: Axis) -> isize {
138        // strides are reinterpreted as isize
139        self.strides[axis.index()] as isize
140    }
141
142    /// Return a read-only view of the array
143    pub fn view(&self) -> ArrayView<'_, A, D>
144    where
145        S: Data,
146    {
147        debug_assert!(self.pointer_is_inbounds());
148        unsafe { ArrayView::new(self.ptr, self.dim.clone(), self.strides.clone()) }
149    }
150
151    /// Return a read-write view of the array
152    pub fn view_mut(&mut self) -> ArrayViewMut<'_, A, D>
153    where
154        S: DataMut,
155    {
156        self.ensure_unique();
157        unsafe { ArrayViewMut::new(self.ptr, self.dim.clone(), self.strides.clone()) }
158    }
159
160    /// Return a shared view of the array with elements as if they were embedded in cells.
161    ///
162    /// The cell view requires a mutable borrow of the array. Once borrowed the
163    /// cell view itself can be copied and accessed without exclusivity.
164    ///
165    /// The view acts "as if" the elements are temporarily in cells, and elements
166    /// can be changed through shared references using the regular cell methods.
167    pub fn cell_view(&mut self) -> ArrayView<'_, MathCell<A>, D>
168    where
169        S: DataMut,
170    {
171        self.view_mut().into_cell_view()
172    }
173
174    /// Return an uniquely owned copy of the array.
175    ///
176    /// If the input array is contiguous, then the output array will have the same
177    /// memory layout. Otherwise, the layout of the output array is unspecified.
178    /// If you need a particular layout, you can allocate a new array with the
179    /// desired memory layout and [`.assign()`](#method.assign) the data.
180    /// Alternatively, you can collectan iterator, like this for a result in
181    /// standard layout:
182    ///
183    /// ```
184    /// # use ndarray::prelude::*;
185    /// # let arr = Array::from_shape_vec((2, 2).f(), vec![1, 2, 3, 4]).unwrap();
186    /// # let owned = {
187    /// Array::from_shape_vec(arr.raw_dim(), arr.iter().cloned().collect()).unwrap()
188    /// # };
189    /// # assert!(owned.is_standard_layout());
190    /// # assert_eq!(arr, owned);
191    /// ```
192    ///
193    /// or this for a result in column-major (Fortran) layout:
194    ///
195    /// ```
196    /// # use ndarray::prelude::*;
197    /// # let arr = Array::from_shape_vec((2, 2), vec![1, 2, 3, 4]).unwrap();
198    /// # let owned = {
199    /// Array::from_shape_vec(arr.raw_dim().f(), arr.t().iter().cloned().collect()).unwrap()
200    /// # };
201    /// # assert!(owned.t().is_standard_layout());
202    /// # assert_eq!(arr, owned);
203    /// ```
204    pub fn to_owned(&self) -> Array<A, D>
205    where
206        A: Clone,
207        S: Data,
208    {
209        if let Some(slc) = self.as_slice_memory_order() {
210            unsafe {
211                Array::from_shape_vec_unchecked(
212                    self.dim.clone().strides(self.strides.clone()),
213                    slc.to_vec(),
214                )
215            }
216        } else {
217            self.map(|x| x.clone())
218        }
219    }
220
221    /// Return a shared ownership (copy on write) array, cloning the array
222    /// elements if necessary.
223    pub fn to_shared(&self) -> ArcArray<A, D>
224    where
225        A: Clone,
226        S: Data,
227    {
228        S::to_shared(self)
229    }
230
231    /// Turn the array into a uniquely owned array, cloning the array elements
232    /// if necessary.
233    pub fn into_owned(self) -> Array<A, D>
234    where
235        A: Clone,
236        S: Data,
237    {
238        S::into_owned(self)
239    }
240
241    /// Turn the array into a shared ownership (copy on write) array,
242    /// without any copying.
243    pub fn into_shared(self) -> ArcArray<A, D>
244    where
245        S: DataOwned,
246    {
247        let data = self.data.into_shared();
248        // safe because: equivalent unmoved data, ptr and dims remain valid
249        unsafe {
250            ArrayBase::from_data_ptr(data, self.ptr).with_strides_dim(self.strides, self.dim)
251        }
252    }
253
254    /// Returns a reference to the first element of the array, or `None` if it
255    /// is empty.
256    pub fn first(&self) -> Option<&A>
257    where
258        S: Data,
259    {
260        if self.is_empty() {
261            None
262        } else {
263            Some(unsafe { &*self.as_ptr() })
264        }
265    }
266
267    /// Returns a mutable reference to the first element of the array, or
268    /// `None` if it is empty.
269    pub fn first_mut(&mut self) -> Option<&mut A>
270    where
271        S: DataMut,
272    {
273        if self.is_empty() {
274            None
275        } else {
276            Some(unsafe { &mut *self.as_mut_ptr() })
277        }
278    }
279
280    /// Return an iterator of references to the elements of the array.
281    ///
282    /// Elements are visited in the *logical order* of the array, which
283    /// is where the rightmost index is varying the fastest.
284    ///
285    /// Iterator element type is `&A`.
286    pub fn iter(&self) -> Iter<'_, A, D>
287    where
288        S: Data,
289    {
290        debug_assert!(self.pointer_is_inbounds());
291        self.view().into_iter_()
292    }
293
294    /// Return an iterator of mutable references to the elements of the array.
295    ///
296    /// Elements are visited in the *logical order* of the array, which
297    /// is where the rightmost index is varying the fastest.
298    ///
299    /// Iterator element type is `&mut A`.
300    pub fn iter_mut(&mut self) -> IterMut<'_, A, D>
301    where
302        S: DataMut,
303    {
304        self.view_mut().into_iter_()
305    }
306
307    /// Return an iterator of indexes and references to the elements of the array.
308    ///
309    /// Elements are visited in the *logical order* of the array, which
310    /// is where the rightmost index is varying the fastest.
311    ///
312    /// Iterator element type is `(D::Pattern, &A)`.
313    ///
314    /// See also [`Zip::indexed`](struct.Zip.html)
315    pub fn indexed_iter(&self) -> IndexedIter<'_, A, D>
316    where
317        S: Data,
318    {
319        IndexedIter::new(self.view().into_elements_base())
320    }
321
322    /// Return an iterator of indexes and mutable references to the elements of the array.
323    ///
324    /// Elements are visited in the *logical order* of the array, which
325    /// is where the rightmost index is varying the fastest.
326    ///
327    /// Iterator element type is `(D::Pattern, &mut A)`.
328    pub fn indexed_iter_mut(&mut self) -> IndexedIterMut<'_, A, D>
329    where
330        S: DataMut,
331    {
332        IndexedIterMut::new(self.view_mut().into_elements_base())
333    }
334
335    /// Return a sliced view of the array.
336    ///
337    /// See [*Slicing*](#slicing) for full documentation.
338    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
339    ///
340    /// **Panics** if an index is out of bounds or step size is zero.<br>
341    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
342    pub fn slice<I>(&self, info: I) -> ArrayView<'_, A, I::OutDim>
343    where
344        I: SliceArg<D>,
345        S: Data,
346    {
347        self.view().slice_move(info)
348    }
349
350    /// Return a sliced read-write view of the array.
351    ///
352    /// See [*Slicing*](#slicing) for full documentation.
353    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
354    ///
355    /// **Panics** if an index is out of bounds or step size is zero.<br>
356    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
357    pub fn slice_mut<I>(&mut self, info: I) -> ArrayViewMut<'_, A, I::OutDim>
358    where
359        I: SliceArg<D>,
360        S: DataMut,
361    {
362        self.view_mut().slice_move(info)
363    }
364
365    /// Return multiple disjoint, sliced, mutable views of the array.
366    ///
367    /// See [*Slicing*](#slicing) for full documentation. See also
368    /// [`MultiSliceArg`], [`s!`], [`SliceArg`], and
369    /// [`SliceInfo`](crate::SliceInfo).
370    ///
371    /// **Panics** if any of the following occur:
372    ///
373    /// * if any of the views would intersect (i.e. if any element would appear in multiple slices)
374    /// * if an index is out of bounds or step size is zero
375    /// * if `D` is `IxDyn` and `info` does not match the number of array axes
376    ///
377    /// # Example
378    ///
379    /// ```
380    /// use ndarray::{arr2, s};
381    ///
382    /// let mut a = arr2(&[[1, 2, 3], [4, 5, 6]]);
383    /// let (mut edges, mut middle) = a.multi_slice_mut((s![.., ..;2], s![.., 1]));
384    /// edges.fill(1);
385    /// middle.fill(0);
386    /// assert_eq!(a, arr2(&[[1, 0, 1], [1, 0, 1]]));
387    /// ```
388    pub fn multi_slice_mut<'a, M>(&'a mut self, info: M) -> M::Output
389    where
390        M: MultiSliceArg<'a, A, D>,
391        S: DataMut,
392    {
393        info.multi_slice_move(self.view_mut())
394    }
395
396    /// Slice the array, possibly changing the number of dimensions.
397    ///
398    /// See [*Slicing*](#slicing) for full documentation.
399    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
400    ///
401    /// **Panics** if an index is out of bounds or step size is zero.<br>
402    /// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
403    pub fn slice_move<I>(mut self, info: I) -> ArrayBase<S, I::OutDim>
404    where
405        I: SliceArg<D>,
406    {
407        assert_eq!(
408            info.in_ndim(),
409            self.ndim(),
410            "The input dimension of `info` must match the array to be sliced.",
411        );
412        let out_ndim = info.out_ndim();
413        let mut new_dim = I::OutDim::zeros(out_ndim);
414        let mut new_strides = I::OutDim::zeros(out_ndim);
415
416        let mut old_axis = 0;
417        let mut new_axis = 0;
418        info.as_ref().iter().for_each(|&ax_info| match ax_info {
419            SliceInfoElem::Slice { start, end, step } => {
420                // Slice the axis in-place to update the `dim`, `strides`, and `ptr`.
421                self.slice_axis_inplace(Axis(old_axis), Slice { start, end, step });
422                // Copy the sliced dim and stride to corresponding axis.
423                new_dim[new_axis] = self.dim[old_axis];
424                new_strides[new_axis] = self.strides[old_axis];
425                old_axis += 1;
426                new_axis += 1;
427            }
428            SliceInfoElem::Index(index) => {
429                // Collapse the axis in-place to update the `ptr`.
430                let i_usize = abs_index(self.len_of(Axis(old_axis)), index);
431                self.collapse_axis(Axis(old_axis), i_usize);
432                // Skip copying the axis since it should be removed. Note that
433                // removing this axis is safe because `.collapse_axis()` panics
434                // if the index is out-of-bounds, so it will panic if the axis
435                // is zero length.
436                old_axis += 1;
437            }
438            SliceInfoElem::NewAxis => {
439                // Set the dim and stride of the new axis.
440                new_dim[new_axis] = 1;
441                new_strides[new_axis] = 0;
442                new_axis += 1;
443            }
444        });
445        debug_assert_eq!(old_axis, self.ndim());
446        debug_assert_eq!(new_axis, out_ndim);
447
448        // safe because new dimension, strides allow access to a subset of old data
449        unsafe { self.with_strides_dim(new_strides, new_dim) }
450    }
451
452    /// Slice the array in place without changing the number of dimensions.
453    ///
454    /// In particular, if an axis is sliced with an index, the axis is
455    /// collapsed, as in [`.collapse_axis()`], rather than removed, as in
456    /// [`.slice_move()`] or [`.index_axis_move()`].
457    ///
458    /// [`.collapse_axis()`]: #method.collapse_axis
459    /// [`.slice_move()`]: #method.slice_move
460    /// [`.index_axis_move()`]: #method.index_axis_move
461    ///
462    /// See [*Slicing*](#slicing) for full documentation.
463    /// See also [`s!`], [`SliceArg`], and [`SliceInfo`](crate::SliceInfo).
464    ///
465    /// **Panics** in the following cases:
466    ///
467    /// - if an index is out of bounds
468    /// - if a step size is zero
469    /// - if [`SliceInfoElem::NewAxis`] is in `info`, e.g. if [`NewAxis`] was
470    ///   used in the [`s!`] macro
471    /// - if `D` is `IxDyn` and `info` does not match the number of array axes
472    pub fn slice_collapse<I>(&mut self, info: I)
473    where
474        I: SliceArg<D>,
475    {
476        assert_eq!(
477            info.in_ndim(),
478            self.ndim(),
479            "The input dimension of `info` must match the array to be sliced.",
480        );
481        let mut axis = 0;
482        info.as_ref().iter().for_each(|&ax_info| match ax_info {
483                SliceInfoElem::Slice { start, end, step } => {
484                    self.slice_axis_inplace(Axis(axis), Slice { start, end, step });
485                    axis += 1;
486                }
487                SliceInfoElem::Index(index) => {
488                    let i_usize = abs_index(self.len_of(Axis(axis)), index);
489                    self.collapse_axis(Axis(axis), i_usize);
490                    axis += 1;
491                }
492                SliceInfoElem::NewAxis => panic!("`slice_collapse` does not support `NewAxis`."),
493            });
494        debug_assert_eq!(axis, self.ndim());
495    }
496
497    /// Return a view of the array, sliced along the specified axis.
498    ///
499    /// **Panics** if an index is out of bounds or step size is zero.<br>
500    /// **Panics** if `axis` is out of bounds.
501    pub fn slice_axis(&self, axis: Axis, indices: Slice) -> ArrayView<'_, A, D>
502    where
503        S: Data,
504    {
505        let mut view = self.view();
506        view.slice_axis_inplace(axis, indices);
507        view
508    }
509
510    /// Return a mutable view of the array, sliced along the specified axis.
511    ///
512    /// **Panics** if an index is out of bounds or step size is zero.<br>
513    /// **Panics** if `axis` is out of bounds.
514    pub fn slice_axis_mut(&mut self, axis: Axis, indices: Slice) -> ArrayViewMut<'_, A, D>
515    where
516        S: DataMut,
517    {
518        let mut view_mut = self.view_mut();
519        view_mut.slice_axis_inplace(axis, indices);
520        view_mut
521    }
522
523    /// Slice the array in place along the specified axis.
524    ///
525    /// **Panics** if an index is out of bounds or step size is zero.<br>
526    /// **Panics** if `axis` is out of bounds.
527    pub fn slice_axis_inplace(&mut self, axis: Axis, indices: Slice) {
528        let offset = do_slice(
529            &mut self.dim.slice_mut()[axis.index()],
530            &mut self.strides.slice_mut()[axis.index()],
531            indices,
532        );
533        unsafe {
534            self.ptr = self.ptr.offset(offset);
535        }
536        debug_assert!(self.pointer_is_inbounds());
537    }
538
539    /// Return a view of a slice of the array, with a closure specifying the
540    /// slice for each axis.
541    ///
542    /// This is especially useful for code which is generic over the
543    /// dimensionality of the array.
544    ///
545    /// **Panics** if an index is out of bounds or step size is zero.
546    pub fn slice_each_axis<F>(&self, f: F) -> ArrayView<'_, A, D>
547    where
548        F: FnMut(AxisDescription) -> Slice,
549        S: Data,
550    {
551        let mut view = self.view();
552        view.slice_each_axis_inplace(f);
553        view
554    }
555
556    /// Return a mutable view of a slice of the array, with a closure
557    /// specifying the slice for each axis.
558    ///
559    /// This is especially useful for code which is generic over the
560    /// dimensionality of the array.
561    ///
562    /// **Panics** if an index is out of bounds or step size is zero.
563    pub fn slice_each_axis_mut<F>(&mut self, f: F) -> ArrayViewMut<'_, A, D>
564    where
565        F: FnMut(AxisDescription) -> Slice,
566        S: DataMut,
567    {
568        let mut view = self.view_mut();
569        view.slice_each_axis_inplace(f);
570        view
571    }
572
573    /// Slice the array in place, with a closure specifying the slice for each
574    /// axis.
575    ///
576    /// This is especially useful for code which is generic over the
577    /// dimensionality of the array.
578    ///
579    /// **Panics** if an index is out of bounds or step size is zero.
580    pub fn slice_each_axis_inplace<F>(&mut self, mut f: F)
581    where
582        F: FnMut(AxisDescription) -> Slice,
583    {
584        for ax in 0..self.ndim() {
585            self.slice_axis_inplace(
586                Axis(ax),
587                f(AxisDescription {
588                    axis: Axis(ax),
589                    len: self.dim[ax],
590                    stride: self.strides[ax] as isize,
591                }),
592            )
593        }
594    }
595
596    /// Return a reference to the element at `index`, or return `None`
597    /// if the index is out of bounds.
598    ///
599    /// Arrays also support indexing syntax: `array[index]`.
600    ///
601    /// ```
602    /// use ndarray::arr2;
603    ///
604    /// let a = arr2(&[[1., 2.],
605    ///                [3., 4.]]);
606    ///
607    /// assert!(
608    ///     a.get((0, 1)) == Some(&2.) &&
609    ///     a.get((0, 2)) == None &&
610    ///     a[(0, 1)] == 2. &&
611    ///     a[[0, 1]] == 2.
612    /// );
613    /// ```
614    pub fn get<I>(&self, index: I) -> Option<&A>
615    where
616        I: NdIndex<D>,
617        S: Data,
618    {
619        unsafe { self.get_ptr(index).map(|ptr| &*ptr) }
620    }
621
622    pub(crate) fn get_ptr<I>(&self, index: I) -> Option<*const A>
623    where
624        I: NdIndex<D>,
625    {
626        let ptr = self.ptr;
627        index
628            .index_checked(&self.dim, &self.strides)
629            .map(move |offset| unsafe { ptr.as_ptr().offset(offset) as *const _ })
630    }
631
632    /// Return a mutable reference to the element at `index`, or return `None`
633    /// if the index is out of bounds.
634    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut A>
635    where
636        S: DataMut,
637        I: NdIndex<D>,
638    {
639        unsafe { self.get_ptr_mut(index).map(|ptr| &mut *ptr) }
640    }
641
642    pub(crate) fn get_ptr_mut<I>(&mut self, index: I) -> Option<*mut A>
643    where
644        S: RawDataMut,
645        I: NdIndex<D>,
646    {
647        // const and mut are separate to enforce &mutness as well as the
648        // extra code in as_mut_ptr
649        let ptr = self.as_mut_ptr();
650        index
651            .index_checked(&self.dim, &self.strides)
652            .map(move |offset| unsafe { ptr.offset(offset) })
653    }
654
655    /// Perform *unchecked* array indexing.
656    ///
657    /// Return a reference to the element at `index`.
658    ///
659    /// **Note:** only unchecked for non-debug builds of ndarray.
660    ///
661    /// # Safety
662    ///
663    /// The caller must ensure that the index is in-bounds.
664    #[inline]
665    pub unsafe fn uget<I>(&self, index: I) -> &A
666    where
667        S: Data,
668        I: NdIndex<D>,
669    {
670        arraytraits::debug_bounds_check(self, &index);
671        let off = index.index_unchecked(&self.strides);
672        &*self.ptr.as_ptr().offset(off)
673    }
674
675    /// Perform *unchecked* array indexing.
676    ///
677    /// Return a mutable reference to the element at `index`.
678    ///
679    /// **Note:** Only unchecked for non-debug builds of ndarray.
680    ///
681    /// # Safety
682    ///
683    /// The caller must ensure that:
684    ///
685    /// 1. the index is in-bounds and
686    ///
687    /// 2. the data is uniquely held by the array. (This property is guaranteed
688    ///    for `Array` and `ArrayViewMut`, but not for `ArcArray` or `CowArray`.)
689    #[inline]
690    pub unsafe fn uget_mut<I>(&mut self, index: I) -> &mut A
691    where
692        S: DataMut,
693        I: NdIndex<D>,
694    {
695        debug_assert!(self.data.is_unique());
696        arraytraits::debug_bounds_check(self, &index);
697        let off = index.index_unchecked(&self.strides);
698        &mut *self.ptr.as_ptr().offset(off)
699    }
700
701    /// Swap elements at indices `index1` and `index2`.
702    ///
703    /// Indices may be equal.
704    ///
705    /// ***Panics*** if an index is out of bounds.
706    pub fn swap<I>(&mut self, index1: I, index2: I)
707    where
708        S: DataMut,
709        I: NdIndex<D>,
710    {
711        let ptr = self.as_mut_ptr();
712        let offset1 = index1.index_checked(&self.dim, &self.strides);
713        let offset2 = index2.index_checked(&self.dim, &self.strides);
714        if let Some(offset1) = offset1 {
715            if let Some(offset2) = offset2 {
716                unsafe {
717                    std::ptr::swap(ptr.offset(offset1), ptr.offset(offset2));
718                }
719                return;
720            }
721        }
722        panic!("swap: index out of bounds for indices {:?} {:?}", index1, index2);
723    }
724
725    /// Swap elements *unchecked* at indices `index1` and `index2`.
726    ///
727    /// Indices may be equal.
728    ///
729    /// **Note:** only unchecked for non-debug builds of ndarray.
730    ///
731    /// # Safety
732    ///
733    /// The caller must ensure that:
734    ///
735    /// 1. both `index1` and `index2` are in-bounds and
736    ///
737    /// 2. the data is uniquely held by the array. (This property is guaranteed
738    ///    for `Array` and `ArrayViewMut`, but not for `ArcArray` or `CowArray`.)
739    pub unsafe fn uswap<I>(&mut self, index1: I, index2: I)
740    where
741        S: DataMut,
742        I: NdIndex<D>,
743    {
744        debug_assert!(self.data.is_unique());
745        arraytraits::debug_bounds_check(self, &index1);
746        arraytraits::debug_bounds_check(self, &index2);
747        let off1 = index1.index_unchecked(&self.strides);
748        let off2 = index2.index_unchecked(&self.strides);
749        std::ptr::swap(
750            self.ptr.as_ptr().offset(off1),
751            self.ptr.as_ptr().offset(off2),
752        );
753    }
754
755    // `get` for zero-dimensional arrays
756    // panics if dimension is not zero. otherwise an element is always present.
757    fn get_0d(&self) -> &A
758    where
759        S: Data,
760    {
761        assert!(self.ndim() == 0);
762        unsafe { &*self.as_ptr() }
763    }
764
765    /// Returns a view restricted to `index` along the axis, with the axis
766    /// removed.
767    ///
768    /// See [*Subviews*](#subviews) for full documentation.
769    ///
770    /// **Panics** if `axis` or `index` is out of bounds.
771    ///
772    /// ```
773    /// use ndarray::{arr2, ArrayView, Axis};
774    ///
775    /// let a = arr2(&[[1., 2. ],    // ... axis 0, row 0
776    ///                [3., 4. ],    // --- axis 0, row 1
777    ///                [5., 6. ]]);  // ... axis 0, row 2
778    /// //               .   \
779    /// //                .   axis 1, column 1
780    /// //                 axis 1, column 0
781    /// assert!(
782    ///     a.index_axis(Axis(0), 1) == ArrayView::from(&[3., 4.]) &&
783    ///     a.index_axis(Axis(1), 1) == ArrayView::from(&[2., 4., 6.])
784    /// );
785    /// ```
786    pub fn index_axis(&self, axis: Axis, index: usize) -> ArrayView<'_, A, D::Smaller>
787    where
788        S: Data,
789        D: RemoveAxis,
790    {
791        self.view().index_axis_move(axis, index)
792    }
793
794    /// Returns a mutable view restricted to `index` along the axis, with the
795    /// axis removed.
796    ///
797    /// **Panics** if `axis` or `index` is out of bounds.
798    ///
799    /// ```
800    /// use ndarray::{arr2, aview2, Axis};
801    ///
802    /// let mut a = arr2(&[[1., 2. ],
803    ///                    [3., 4. ]]);
804    /// //                   .   \
805    /// //                    .   axis 1, column 1
806    /// //                     axis 1, column 0
807    ///
808    /// {
809    ///     let mut column1 = a.index_axis_mut(Axis(1), 1);
810    ///     column1 += 10.;
811    /// }
812    ///
813    /// assert!(
814    ///     a == aview2(&[[1., 12.],
815    ///                   [3., 14.]])
816    /// );
817    /// ```
818    pub fn index_axis_mut(&mut self, axis: Axis, index: usize) -> ArrayViewMut<'_, A, D::Smaller>
819    where
820        S: DataMut,
821        D: RemoveAxis,
822    {
823        self.view_mut().index_axis_move(axis, index)
824    }
825
826    /// Collapses the array to `index` along the axis and removes the axis.
827    ///
828    /// See [`.index_axis()`](#method.index_axis) and [*Subviews*](#subviews) for full documentation.
829    ///
830    /// **Panics** if `axis` or `index` is out of bounds.
831    pub fn index_axis_move(mut self, axis: Axis, index: usize) -> ArrayBase<S, D::Smaller>
832    where
833        D: RemoveAxis,
834    {
835        self.collapse_axis(axis, index);
836        let dim = self.dim.remove_axis(axis);
837        let strides = self.strides.remove_axis(axis);
838        // safe because new dimension, strides allow access to a subset of old data
839        unsafe {
840            self.with_strides_dim(strides, dim)
841        }
842    }
843
844    /// Selects `index` along the axis, collapsing the axis into length one.
845    ///
846    /// **Panics** if `axis` or `index` is out of bounds.
847    pub fn collapse_axis(&mut self, axis: Axis, index: usize) {
848        let offset = dimension::do_collapse_axis(&mut self.dim, &self.strides, axis.index(), index);
849        self.ptr = unsafe { self.ptr.offset(offset) };
850        debug_assert!(self.pointer_is_inbounds());
851    }
852
853    /// Along `axis`, select arbitrary subviews corresponding to `indices`
854    /// and and copy them into a new array.
855    ///
856    /// **Panics** if `axis` or an element of `indices` is out of bounds.
857    ///
858    /// ```
859    /// use ndarray::{arr2, Axis};
860    ///
861    /// let x = arr2(&[[0., 1.],
862    ///                [2., 3.],
863    ///                [4., 5.],
864    ///                [6., 7.],
865    ///                [8., 9.]]);
866    ///
867    /// let r = x.select(Axis(0), &[0, 4, 3]);
868    /// assert!(
869    ///         r == arr2(&[[0., 1.],
870    ///                     [8., 9.],
871    ///                     [6., 7.]])
872    ///);
873    /// ```
874    pub fn select(&self, axis: Axis, indices: &[Ix]) -> Array<A, D>
875    where
876        A: Copy,
877        S: Data,
878        D: RemoveAxis,
879    {
880        let mut subs = vec![self.view(); indices.len()];
881        for (&i, sub) in zip(indices, &mut subs[..]) {
882            sub.collapse_axis(axis, i);
883        }
884        if subs.is_empty() {
885            let mut dim = self.raw_dim();
886            dim.set_axis(axis, 0);
887            unsafe { Array::from_shape_vec_unchecked(dim, vec![]) }
888        } else {
889            concatenate(axis, &subs).unwrap()
890        }
891    }
892
893    /// Return a producer and iterable that traverses over the *generalized*
894    /// rows of the array. For a 2D array these are the regular rows.
895    ///
896    /// This is equivalent to `.lanes(Axis(n - 1))` where *n* is `self.ndim()`.
897    ///
898    /// For an array of dimensions *a* × *b* × *c* × ... × *l* × *m*
899    /// it has *a* × *b* × *c* × ... × *l* rows each of length *m*.
900    ///
901    /// For example, in a 2 × 2 × 3 array, each row is 3 elements long
902    /// and there are 2 × 2 = 4 rows in total.
903    ///
904    /// Iterator element is `ArrayView1<A>` (1D array view).
905    ///
906    /// ```
907    /// use ndarray::{arr3, Axis, arr1};
908    ///
909    /// let a = arr3(&[[[ 0,  1,  2],    // -- row 0, 0
910    ///                 [ 3,  4,  5]],   // -- row 0, 1
911    ///                [[ 6,  7,  8],    // -- row 1, 0
912    ///                 [ 9, 10, 11]]]); // -- row 1, 1
913    ///
914    /// // `rows` will yield the four generalized rows of the array.
915    /// for row in a.rows() {
916    ///     /* loop body */
917    /// }
918    /// ```
919    pub fn rows(&self) -> Lanes<'_, A, D::Smaller>
920    where
921        S: Data,
922    {
923        let mut n = self.ndim();
924        if n == 0 {
925            n += 1;
926        }
927        Lanes::new(self.view(), Axis(n - 1))
928    }
929
930    #[deprecated(note="Renamed to .rows()", since="0.15.0")]
931    pub fn genrows(&self) -> Lanes<'_, A, D::Smaller>
932    where
933        S: Data,
934    {
935        self.rows()
936    }
937
938    /// Return a producer and iterable that traverses over the *generalized*
939    /// rows of the array and yields mutable array views.
940    ///
941    /// Iterator element is `ArrayView1<A>` (1D read-write array view).
942    pub fn rows_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
943    where
944        S: DataMut,
945    {
946        let mut n = self.ndim();
947        if n == 0 {
948            n += 1;
949        }
950        LanesMut::new(self.view_mut(), Axis(n - 1))
951    }
952
953    #[deprecated(note="Renamed to .rows_mut()", since="0.15.0")]
954    pub fn genrows_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
955    where
956        S: DataMut,
957    {
958        self.rows_mut()
959    }
960
961    /// Return a producer and iterable that traverses over the *generalized*
962    /// columns of the array. For a 2D array these are the regular columns.
963    ///
964    /// This is equivalent to `.lanes(Axis(0))`.
965    ///
966    /// For an array of dimensions *a* × *b* × *c* × ... × *l* × *m*
967    /// it has *b* × *c* × ... × *l* × *m* columns each of length *a*.
968    ///
969    /// For example, in a 2 × 2 × 3 array, each column is 2 elements long
970    /// and there are 2 × 3 = 6 columns in total.
971    ///
972    /// Iterator element is `ArrayView1<A>` (1D array view).
973    ///
974    /// ```
975    /// use ndarray::{arr3, Axis, arr1};
976    ///
977    /// // The generalized columns of a 3D array:
978    /// // are directed along the 0th axis: 0 and 6, 1 and 7 and so on...
979    /// let a = arr3(&[[[ 0,  1,  2], [ 3,  4,  5]],
980    ///                [[ 6,  7,  8], [ 9, 10, 11]]]);
981    ///
982    /// // Here `columns` will yield the six generalized columns of the array.
983    /// for row in a.columns() {
984    ///     /* loop body */
985    /// }
986    /// ```
987    pub fn columns(&self) -> Lanes<'_, A, D::Smaller>
988    where
989        S: Data,
990    {
991        Lanes::new(self.view(), Axis(0))
992    }
993
994    /// Return a producer and iterable that traverses over the *generalized*
995    /// columns of the array. For a 2D array these are the regular columns.
996    ///
997    /// Renamed to `.columns()`
998    #[deprecated(note="Renamed to .columns()", since="0.15.0")]
999    pub fn gencolumns(&self) -> Lanes<'_, A, D::Smaller>
1000    where
1001        S: Data,
1002    {
1003        self.columns()
1004    }
1005
1006    /// Return a producer and iterable that traverses over the *generalized*
1007    /// columns of the array and yields mutable array views.
1008    ///
1009    /// Iterator element is `ArrayView1<A>` (1D read-write array view).
1010    pub fn columns_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
1011    where
1012        S: DataMut,
1013    {
1014        LanesMut::new(self.view_mut(), Axis(0))
1015    }
1016
1017    /// Return a producer and iterable that traverses over the *generalized*
1018    /// columns of the array and yields mutable array views.
1019    ///
1020    /// Renamed to `.columns_mut()`
1021    #[deprecated(note="Renamed to .columns_mut()", since="0.15.0")]
1022    pub fn gencolumns_mut(&mut self) -> LanesMut<'_, A, D::Smaller>
1023    where
1024        S: DataMut,
1025    {
1026        self.columns_mut()
1027    }
1028
1029    /// Return a producer and iterable that traverses over all 1D lanes
1030    /// pointing in the direction of `axis`.
1031    ///
1032    /// When pointing in the direction of the first axis, they are *columns*,
1033    /// in the direction of the last axis *rows*; in general they are all
1034    /// *lanes* and are one dimensional.
1035    ///
1036    /// Iterator element is `ArrayView1<A>` (1D array view).
1037    ///
1038    /// ```
1039    /// use ndarray::{arr3, aview1, Axis};
1040    ///
1041    /// let a = arr3(&[[[ 0,  1,  2],
1042    ///                 [ 3,  4,  5]],
1043    ///                [[ 6,  7,  8],
1044    ///                 [ 9, 10, 11]]]);
1045    ///
1046    /// let inner0 = a.lanes(Axis(0));
1047    /// let inner1 = a.lanes(Axis(1));
1048    /// let inner2 = a.lanes(Axis(2));
1049    ///
1050    /// // The first lane for axis 0 is [0, 6]
1051    /// assert_eq!(inner0.into_iter().next().unwrap(), aview1(&[0, 6]));
1052    /// // The first lane for axis 1 is [0, 3]
1053    /// assert_eq!(inner1.into_iter().next().unwrap(), aview1(&[0, 3]));
1054    /// // The first lane for axis 2 is [0, 1, 2]
1055    /// assert_eq!(inner2.into_iter().next().unwrap(), aview1(&[0, 1, 2]));
1056    /// ```
1057    pub fn lanes(&self, axis: Axis) -> Lanes<'_, A, D::Smaller>
1058    where
1059        S: Data,
1060    {
1061        Lanes::new(self.view(), axis)
1062    }
1063
1064    /// Return a producer and iterable that traverses over all 1D lanes
1065    /// pointing in the direction of `axis`.
1066    ///
1067    /// Iterator element is `ArrayViewMut1<A>` (1D read-write array view).
1068    pub fn lanes_mut(&mut self, axis: Axis) -> LanesMut<'_, A, D::Smaller>
1069    where
1070        S: DataMut,
1071    {
1072        LanesMut::new(self.view_mut(), axis)
1073    }
1074
1075    /// Return an iterator that traverses over the outermost dimension
1076    /// and yields each subview.
1077    ///
1078    /// This is equivalent to `.axis_iter(Axis(0))`.
1079    ///
1080    /// Iterator element is `ArrayView<A, D::Smaller>` (read-only array view).
1081    #[allow(deprecated)]
1082    pub fn outer_iter(&self) -> AxisIter<'_, A, D::Smaller>
1083    where
1084        S: Data,
1085        D: RemoveAxis,
1086    {
1087        self.view().into_outer_iter()
1088    }
1089
1090    /// Return an iterator that traverses over the outermost dimension
1091    /// and yields each subview.
1092    ///
1093    /// This is equivalent to `.axis_iter_mut(Axis(0))`.
1094    ///
1095    /// Iterator element is `ArrayViewMut<A, D::Smaller>` (read-write array view).
1096    #[allow(deprecated)]
1097    pub fn outer_iter_mut(&mut self) -> AxisIterMut<'_, A, D::Smaller>
1098    where
1099        S: DataMut,
1100        D: RemoveAxis,
1101    {
1102        self.view_mut().into_outer_iter()
1103    }
1104
1105    /// Return an iterator that traverses over `axis`
1106    /// and yields each subview along it.
1107    ///
1108    /// For example, in a 3 × 4 × 5 array, with `axis` equal to `Axis(2)`,
1109    /// the iterator element
1110    /// is a 3 × 4 subview (and there are 5 in total), as shown
1111    /// in the picture below.
1112    ///
1113    /// Iterator element is `ArrayView<A, D::Smaller>` (read-only array view).
1114    ///
1115    /// See [*Subviews*](#subviews) for full documentation.
1116    ///
1117    /// **Panics** if `axis` is out of bounds.
1118    ///
1119    /// <img src="https://rust-ndarray.github.io/ndarray/images/axis_iter_3_4_5.svg" height="250px">
1120    pub fn axis_iter(&self, axis: Axis) -> AxisIter<'_, A, D::Smaller>
1121    where
1122        S: Data,
1123        D: RemoveAxis,
1124    {
1125        AxisIter::new(self.view(), axis)
1126    }
1127
1128    /// Return an iterator that traverses over `axis`
1129    /// and yields each mutable subview along it.
1130    ///
1131    /// Iterator element is `ArrayViewMut<A, D::Smaller>`
1132    /// (read-write array view).
1133    ///
1134    /// **Panics** if `axis` is out of bounds.
1135    pub fn axis_iter_mut(&mut self, axis: Axis) -> AxisIterMut<'_, A, D::Smaller>
1136    where
1137        S: DataMut,
1138        D: RemoveAxis,
1139    {
1140        AxisIterMut::new(self.view_mut(), axis)
1141    }
1142
1143    /// Return an iterator that traverses over `axis` by chunks of `size`,
1144    /// yielding non-overlapping views along that axis.
1145    ///
1146    /// Iterator element is `ArrayView<A, D>`
1147    ///
1148    /// The last view may have less elements if `size` does not divide
1149    /// the axis' dimension.
1150    ///
1151    /// **Panics** if `axis` is out of bounds or if `size` is zero.
1152    ///
1153    /// ```
1154    /// use ndarray::Array;
1155    /// use ndarray::{arr3, Axis};
1156    /// use std::iter::FromIterator;
1157    ///
1158    /// let a = Array::from_iter(0..28).into_shape((2, 7, 2)).unwrap();
1159    /// let mut iter = a.axis_chunks_iter(Axis(1), 2);
1160    ///
1161    /// // first iteration yields a 2 × 2 × 2 view
1162    /// assert_eq!(iter.next().unwrap(),
1163    ///            arr3(&[[[ 0,  1], [ 2, 3]],
1164    ///                   [[14, 15], [16, 17]]]));
1165    ///
1166    /// // however the last element is a 2 × 1 × 2 view since 7 % 2 == 1
1167    /// assert_eq!(iter.next_back().unwrap(), arr3(&[[[12, 13]],
1168    ///                                              [[26, 27]]]));
1169    /// ```
1170    pub fn axis_chunks_iter(&self, axis: Axis, size: usize) -> AxisChunksIter<'_, A, D>
1171    where
1172        S: Data,
1173    {
1174        AxisChunksIter::new(self.view(), axis, size)
1175    }
1176
1177    /// Return an iterator that traverses over `axis` by chunks of `size`,
1178    /// yielding non-overlapping read-write views along that axis.
1179    ///
1180    /// Iterator element is `ArrayViewMut<A, D>`
1181    ///
1182    /// **Panics** if `axis` is out of bounds or if `size` is zero.
1183    pub fn axis_chunks_iter_mut(&mut self, axis: Axis, size: usize) -> AxisChunksIterMut<'_, A, D>
1184    where
1185        S: DataMut,
1186    {
1187        AxisChunksIterMut::new(self.view_mut(), axis, size)
1188    }
1189
1190    /// Return an exact chunks producer (and iterable).
1191    ///
1192    /// It produces the whole chunks of a given n-dimensional chunk size,
1193    /// skipping the remainder along each dimension that doesn't fit evenly.
1194    ///
1195    /// The produced element is a `ArrayView<A, D>` with exactly the dimension
1196    /// `chunk_size`.
1197    ///
1198    /// **Panics** if any dimension of `chunk_size` is zero<br>
1199    /// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
1200    /// number of array axes.)
1201    pub fn exact_chunks<E>(&self, chunk_size: E) -> ExactChunks<'_, A, D>
1202    where
1203        E: IntoDimension<Dim = D>,
1204        S: Data,
1205    {
1206        ExactChunks::new(self.view(), chunk_size)
1207    }
1208
1209    /// Return an exact chunks producer (and iterable).
1210    ///
1211    /// It produces the whole chunks of a given n-dimensional chunk size,
1212    /// skipping the remainder along each dimension that doesn't fit evenly.
1213    ///
1214    /// The produced element is a `ArrayViewMut<A, D>` with exactly
1215    /// the dimension `chunk_size`.
1216    ///
1217    /// **Panics** if any dimension of `chunk_size` is zero<br>
1218    /// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the
1219    /// number of array axes.)
1220    ///
1221    /// ```rust
1222    /// use ndarray::Array;
1223    /// use ndarray::arr2;
1224    /// let mut a = Array::zeros((6, 7));
1225    ///
1226    /// // Fill each 2 × 2 chunk with the index of where it appeared in iteration
1227    /// for (i, mut chunk) in a.exact_chunks_mut((2, 2)).into_iter().enumerate() {
1228    ///     chunk.fill(i);
1229    /// }
1230    ///
1231    /// // The resulting array is:
1232    /// assert_eq!(
1233    ///   a,
1234    ///   arr2(&[[0, 0, 1, 1, 2, 2, 0],
1235    ///          [0, 0, 1, 1, 2, 2, 0],
1236    ///          [3, 3, 4, 4, 5, 5, 0],
1237    ///          [3, 3, 4, 4, 5, 5, 0],
1238    ///          [6, 6, 7, 7, 8, 8, 0],
1239    ///          [6, 6, 7, 7, 8, 8, 0]]));
1240    /// ```
1241    pub fn exact_chunks_mut<E>(&mut self, chunk_size: E) -> ExactChunksMut<'_, A, D>
1242    where
1243        E: IntoDimension<Dim = D>,
1244        S: DataMut,
1245    {
1246        ExactChunksMut::new(self.view_mut(), chunk_size)
1247    }
1248
1249    /// Return a window producer and iterable.
1250    ///
1251    /// The windows are all distinct overlapping views of size `window_size`
1252    /// that fit into the array's shape.
1253    ///
1254    /// This produces no elements if the window size is larger than the actual array size along any
1255    /// axis.
1256    ///
1257    /// The produced element is an `ArrayView<A, D>` with exactly the dimension
1258    /// `window_size`.
1259    ///
1260    /// **Panics** if any dimension of `window_size` is zero.<br>
1261    /// (**Panics** if `D` is `IxDyn` and `window_size` does not match the
1262    /// number of array axes.)
1263    ///
1264    /// This is an illustration of the 2×2 windows in a 3×4 array:
1265    ///
1266    /// ```text
1267    ///          ──▶ Axis(1)
1268    ///
1269    ///      │   ┏━━━━━┳━━━━━┱─────┬─────┐   ┌─────┲━━━━━┳━━━━━┱─────┐   ┌─────┬─────┲━━━━━┳━━━━━┓
1270    ///      ▼   ┃ a₀₀ ┃ a₀₁ ┃     │     │   │     ┃ a₀₁ ┃ a₀₂ ┃     │   │     │     ┃ a₀₂ ┃ a₀₃ ┃
1271    /// Axis(0)  ┣━━━━━╋━━━━━╉─────┼─────┤   ├─────╊━━━━━╋━━━━━╉─────┤   ├─────┼─────╊━━━━━╋━━━━━┫
1272    ///          ┃ a₁₀ ┃ a₁₁ ┃     │     │   │     ┃ a₁₁ ┃ a₁₂ ┃     │   │     │     ┃ a₁₂ ┃ a₁₃ ┃
1273    ///          ┡━━━━━╇━━━━━╃─────┼─────┤   ├─────╄━━━━━╇━━━━━╃─────┤   ├─────┼─────╄━━━━━╇━━━━━┩
1274    ///          │     │     │     │     │   │     │     │     │     │   │     │     │     │     │
1275    ///          └─────┴─────┴─────┴─────┘   └─────┴─────┴─────┴─────┘   └─────┴─────┴─────┴─────┘
1276    ///
1277    ///          ┌─────┬─────┬─────┬─────┐   ┌─────┬─────┬─────┬─────┐   ┌─────┬─────┬─────┬─────┐
1278    ///          │     │     │     │     │   │     │     │     │     │   │     │     │     │     │
1279    ///          ┢━━━━━╈━━━━━╅─────┼─────┤   ├─────╆━━━━━╈━━━━━╅─────┤   ├─────┼─────╆━━━━━╈━━━━━┪
1280    ///          ┃ a₁₀ ┃ a₁₁ ┃     │     │   │     ┃ a₁₁ ┃ a₁₂ ┃     │   │     │     ┃ a₁₂ ┃ a₁₃ ┃
1281    ///          ┣━━━━━╋━━━━━╉─────┼─────┤   ├─────╊━━━━━╋━━━━━╉─────┤   ├─────┼─────╊━━━━━╋━━━━━┫
1282    ///          ┃ a₂₀ ┃ a₂₁ ┃     │     │   │     ┃ a₂₁ ┃ a₂₂ ┃     │   │     │     ┃ a₂₂ ┃ a₂₃ ┃
1283    ///          ┗━━━━━┻━━━━━┹─────┴─────┘   └─────┺━━━━━┻━━━━━┹─────┘   └─────┴─────┺━━━━━┻━━━━━┛
1284    /// ```
1285    pub fn windows<E>(&self, window_size: E) -> Windows<'_, A, D>
1286    where
1287        E: IntoDimension<Dim = D>,
1288        S: Data,
1289    {
1290        Windows::new(self.view(), window_size)
1291    }
1292
1293    // Return (length, stride) for diagonal
1294    fn diag_params(&self) -> (Ix, Ixs) {
1295        /* empty shape has len 1 */
1296        let len = self.dim.slice().iter().cloned().min().unwrap_or(1);
1297        let stride = self.strides().iter().sum();
1298        (len, stride)
1299    }
1300
1301    /// Return a view of the diagonal elements of the array.
1302    ///
1303    /// The diagonal is simply the sequence indexed by *(0, 0, .., 0)*,
1304    /// *(1, 1, ..., 1)* etc as long as all axes have elements.
1305    pub fn diag(&self) -> ArrayView1<'_, A>
1306    where
1307        S: Data,
1308    {
1309        self.view().into_diag()
1310    }
1311
1312    /// Return a read-write view over the diagonal elements of the array.
1313    pub fn diag_mut(&mut self) -> ArrayViewMut1<'_, A>
1314    where
1315        S: DataMut,
1316    {
1317        self.view_mut().into_diag()
1318    }
1319
1320    /// Return the diagonal as a one-dimensional array.
1321    pub fn into_diag(self) -> ArrayBase<S, Ix1> {
1322        let (len, stride) = self.diag_params();
1323        // safe because new len stride allows access to a subset of the current elements
1324        unsafe {
1325            self.with_strides_dim(Ix1(stride as Ix), Ix1(len))
1326        }
1327    }
1328
1329    /// Try to make the array unshared.
1330    ///
1331    /// This is equivalent to `.ensure_unique()` if `S: DataMut`.
1332    ///
1333    /// This method is mostly only useful with unsafe code.
1334    fn try_ensure_unique(&mut self)
1335    where
1336        S: RawDataMut,
1337    {
1338        debug_assert!(self.pointer_is_inbounds());
1339        S::try_ensure_unique(self);
1340        debug_assert!(self.pointer_is_inbounds());
1341    }
1342
1343    /// Make the array unshared.
1344    ///
1345    /// This method is mostly only useful with unsafe code.
1346    fn ensure_unique(&mut self)
1347    where
1348        S: DataMut,
1349    {
1350        debug_assert!(self.pointer_is_inbounds());
1351        S::ensure_unique(self);
1352        debug_assert!(self.pointer_is_inbounds());
1353    }
1354
1355    /// Return `true` if the array data is laid out in contiguous “C order” in
1356    /// memory (where the last index is the most rapidly varying).
1357    ///
1358    /// Return `false` otherwise, i.e. the array is possibly not
1359    /// contiguous in memory, it has custom strides, etc.
1360    pub fn is_standard_layout(&self) -> bool {
1361        fn is_standard_layout<D: Dimension>(dim: &D, strides: &D) -> bool {
1362            if let Some(1) = D::NDIM {
1363                return strides[0] == 1 || dim[0] <= 1;
1364            }
1365            if dim.slice().iter().any(|&d| d == 0) {
1366                return true;
1367            }
1368            let defaults = dim.default_strides();
1369            // check all dimensions -- a dimension of length 1 can have unequal strides
1370            for (&dim, &s, &ds) in izip!(dim.slice(), strides.slice(), defaults.slice()) {
1371                if dim != 1 && s != ds {
1372                    return false;
1373                }
1374            }
1375            true
1376        }
1377        is_standard_layout(&self.dim, &self.strides)
1378    }
1379
1380    /// Return true if the array is known to be contiguous.
1381    pub(crate) fn is_contiguous(&self) -> bool {
1382        D::is_contiguous(&self.dim, &self.strides)
1383    }
1384
1385    /// Return a standard-layout array containing the data, cloning if
1386    /// necessary.
1387    ///
1388    /// If `self` is in standard layout, a COW view of the data is returned
1389    /// without cloning. Otherwise, the data is cloned, and the returned array
1390    /// owns the cloned data.
1391    ///
1392    /// ```
1393    /// use ndarray::Array2;
1394    ///
1395    /// let standard = Array2::<f64>::zeros((3, 4));
1396    /// assert!(standard.is_standard_layout());
1397    /// let cow_view = standard.as_standard_layout();
1398    /// assert!(cow_view.is_view());
1399    /// assert!(cow_view.is_standard_layout());
1400    ///
1401    /// let fortran = standard.reversed_axes();
1402    /// assert!(!fortran.is_standard_layout());
1403    /// let cow_owned = fortran.as_standard_layout();
1404    /// assert!(cow_owned.is_owned());
1405    /// assert!(cow_owned.is_standard_layout());
1406    /// ```
1407    pub fn as_standard_layout(&self) -> CowArray<'_, A, D>
1408    where
1409        S: Data<Elem = A>,
1410        A: Clone,
1411    {
1412        if self.is_standard_layout() {
1413            CowArray::from(self.view())
1414        } else {
1415            let v = crate::iterators::to_vec_mapped(self.iter(), A::clone);
1416            let dim = self.dim.clone();
1417            debug_assert_eq!(v.len(), dim.size());
1418
1419            unsafe {
1420                // Safe because the shape and element type are from the existing array
1421                // and the strides are the default strides.
1422                CowArray::from(Array::from_shape_vec_unchecked(dim, v))
1423            }
1424        }
1425    }
1426
1427    /// Return a pointer to the first element in the array.
1428    ///
1429    /// Raw access to array elements needs to follow the strided indexing
1430    /// scheme: an element at multi-index *I* in an array with strides *S* is
1431    /// located at offset
1432    ///
1433    /// *Σ<sub>0 ≤ k < d</sub> I<sub>k</sub> × S<sub>k</sub>*
1434    ///
1435    /// where *d* is `self.ndim()`.
1436    #[inline(always)]
1437    pub fn as_ptr(&self) -> *const A {
1438        self.ptr.as_ptr() as *const A
1439    }
1440
1441    /// Return a mutable pointer to the first element in the array.
1442    #[inline(always)]
1443    pub fn as_mut_ptr(&mut self) -> *mut A
1444    where
1445        S: RawDataMut,
1446    {
1447        self.try_ensure_unique(); // for ArcArray
1448        self.ptr.as_ptr()
1449    }
1450
1451    /// Return a raw view of the array.
1452    #[inline]
1453    pub fn raw_view(&self) -> RawArrayView<A, D> {
1454        unsafe { RawArrayView::new(self.ptr, self.dim.clone(), self.strides.clone()) }
1455    }
1456
1457    /// Return a raw mutable view of the array.
1458    #[inline]
1459    pub fn raw_view_mut(&mut self) -> RawArrayViewMut<A, D>
1460    where
1461        S: RawDataMut,
1462    {
1463        self.try_ensure_unique(); // for ArcArray
1464        unsafe { RawArrayViewMut::new(self.ptr, self.dim.clone(), self.strides.clone()) }
1465    }
1466
1467    /// Return a raw mutable view of the array.
1468    ///
1469    /// Safety: The caller must ensure that the owned array is unshared when this is called
1470    #[inline]
1471    pub(crate) unsafe fn raw_view_mut_unchecked(&mut self) -> RawArrayViewMut<A, D>
1472    where
1473        S: DataOwned,
1474    {
1475        RawArrayViewMut::new(self.ptr, self.dim.clone(), self.strides.clone())
1476    }
1477
1478    /// Return the array’s data as a slice, if it is contiguous and in standard order.
1479    /// Return `None` otherwise.
1480    ///
1481    /// If this function returns `Some(_)`, then the element order in the slice
1482    /// corresponds to the logical order of the array’s elements.
1483    pub fn as_slice(&self) -> Option<&[A]>
1484    where
1485        S: Data,
1486    {
1487        if self.is_standard_layout() {
1488            unsafe { Some(slice::from_raw_parts(self.ptr.as_ptr(), self.len())) }
1489        } else {
1490            None
1491        }
1492    }
1493
1494    /// Return the array’s data as a slice, if it is contiguous and in standard order.
1495    /// Return `None` otherwise.
1496    pub fn as_slice_mut(&mut self) -> Option<&mut [A]>
1497    where
1498        S: DataMut,
1499    {
1500        if self.is_standard_layout() {
1501            self.ensure_unique();
1502            unsafe { Some(slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len())) }
1503        } else {
1504            None
1505        }
1506    }
1507
1508    /// Return the array’s data as a slice if it is contiguous,
1509    /// return `None` otherwise.
1510    ///
1511    /// If this function returns `Some(_)`, then the elements in the slice
1512    /// have whatever order the elements have in memory.
1513    pub fn as_slice_memory_order(&self) -> Option<&[A]>
1514    where
1515        S: Data,
1516    {
1517        if self.is_contiguous() {
1518            let offset = offset_from_ptr_to_memory(&self.dim, &self.strides);
1519            unsafe {
1520                Some(slice::from_raw_parts(
1521                    self.ptr.offset(offset).as_ptr(),
1522                    self.len(),
1523                ))
1524            }
1525        } else {
1526            None
1527        }
1528    }
1529
1530    /// Return the array’s data as a slice if it is contiguous,
1531    /// return `None` otherwise.
1532    pub fn as_slice_memory_order_mut(&mut self) -> Option<&mut [A]>
1533    where
1534        S: DataMut,
1535    {
1536        self.try_as_slice_memory_order_mut().ok()
1537    }
1538
1539    /// Return the array’s data as a slice if it is contiguous, otherwise
1540    /// return `self` in the `Err` variant.
1541    pub(crate) fn try_as_slice_memory_order_mut(&mut self) -> Result<&mut [A], &mut Self>
1542    where
1543        S: DataMut,
1544    {
1545        if self.is_contiguous() {
1546            self.ensure_unique();
1547            let offset = offset_from_ptr_to_memory(&self.dim, &self.strides);
1548            unsafe {
1549                Ok(slice::from_raw_parts_mut(
1550                    self.ptr.offset(offset).as_ptr(),
1551                    self.len(),
1552                ))
1553            }
1554        } else {
1555            Err(self)
1556        }
1557    }
1558
1559    /// Transform the array into `shape`; any shape with the same number of
1560    /// elements is accepted, but the source array or view must be in standard
1561    /// or column-major (Fortran) layout.
1562    ///
1563    /// **Errors** if the shapes don't have the same number of elements.<br>
1564    /// **Errors** if the input array is not c- or f-contiguous.
1565    ///
1566    /// ```
1567    /// use ndarray::{aview1, aview2};
1568    ///
1569    /// assert!(
1570    ///     aview1(&[1., 2., 3., 4.]).into_shape((2, 2)).unwrap()
1571    ///     == aview2(&[[1., 2.],
1572    ///                 [3., 4.]])
1573    /// );
1574    /// ```
1575    pub fn into_shape<E>(self, shape: E) -> Result<ArrayBase<S, E::Dim>, ShapeError>
1576    where
1577        E: IntoDimension,
1578    {
1579        let shape = shape.into_dimension();
1580        if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
1581            return Err(error::incompatible_shapes(&self.dim, &shape));
1582        }
1583        // Check if contiguous, if not => copy all, else just adapt strides
1584        unsafe {
1585            // safe because arrays are contiguous and len is unchanged
1586            if self.is_standard_layout() {
1587                Ok(self.with_strides_dim(shape.default_strides(), shape))
1588            } else if self.ndim() > 1 && self.raw_view().reversed_axes().is_standard_layout() {
1589                Ok(self.with_strides_dim(shape.fortran_strides(), shape))
1590            } else {
1591                Err(error::from_kind(error::ErrorKind::IncompatibleLayout))
1592            }
1593        }
1594    }
1595
1596    /// *Note: Reshape is for `ArcArray` only. Use `.into_shape()` for
1597    /// other arrays and array views.*
1598    ///
1599    /// Transform the array into `shape`; any shape with the same number of
1600    /// elements is accepted.
1601    ///
1602    /// May clone all elements if needed to arrange elements in standard
1603    /// layout (and break sharing).
1604    ///
1605    /// **Panics** if shapes are incompatible.
1606    ///
1607    /// ```
1608    /// use ndarray::{rcarr1, rcarr2};
1609    ///
1610    /// assert!(
1611    ///     rcarr1(&[1., 2., 3., 4.]).reshape((2, 2))
1612    ///     == rcarr2(&[[1., 2.],
1613    ///                 [3., 4.]])
1614    /// );
1615    /// ```
1616    pub fn reshape<E>(&self, shape: E) -> ArrayBase<S, E::Dim>
1617    where
1618        S: DataShared + DataOwned,
1619        A: Clone,
1620        E: IntoDimension,
1621    {
1622        let shape = shape.into_dimension();
1623        if size_of_shape_checked(&shape) != Ok(self.dim.size()) {
1624            panic!(
1625                "ndarray: incompatible shapes in reshape, attempted from: {:?}, to: {:?}",
1626                self.dim.slice(),
1627                shape.slice()
1628            )
1629        }
1630        // Check if contiguous, if not => copy all, else just adapt strides
1631        if self.is_standard_layout() {
1632            let cl = self.clone();
1633            // safe because array is contiguous and shape has equal number of elements
1634            unsafe {
1635                cl.with_strides_dim(shape.default_strides(), shape)
1636            }
1637        } else {
1638            let v = self.iter().cloned().collect::<Vec<A>>();
1639            unsafe { ArrayBase::from_shape_vec_unchecked(shape, v) }
1640        }
1641    }
1642
1643    /// Convert any array or array view to a dynamic dimensional array or
1644    /// array view (respectively).
1645    ///
1646    /// ```
1647    /// use ndarray::{arr2, ArrayD};
1648    ///
1649    /// let array: ArrayD<i32> = arr2(&[[1, 2],
1650    ///                                 [3, 4]]).into_dyn();
1651    /// ```
1652    pub fn into_dyn(self) -> ArrayBase<S, IxDyn> {
1653        // safe because new dims equivalent
1654        unsafe {
1655            ArrayBase::from_data_ptr(self.data, self.ptr)
1656                .with_strides_dim(self.strides.into_dyn(), self.dim.into_dyn())
1657        }
1658    }
1659
1660    /// Convert an array or array view to another with the same type, but different dimensionality
1661    /// type. Errors if the dimensions don't agree (the number of axes must match).
1662    ///
1663    /// Note that conversion to a dynamic dimensional array will never fail (and is equivalent to
1664    /// the `into_dyn` method).
1665    ///
1666    /// ```
1667    /// use ndarray::{ArrayD, Ix2, IxDyn};
1668    ///
1669    /// // Create a dynamic dimensionality array and convert it to an Array2
1670    /// // (Ix2 dimension type).
1671    ///
1672    /// let array = ArrayD::<f64>::zeros(IxDyn(&[10, 10]));
1673    ///
1674    /// assert!(array.into_dimensionality::<Ix2>().is_ok());
1675    /// ```
1676    pub fn into_dimensionality<D2>(self) -> Result<ArrayBase<S, D2>, ShapeError>
1677    where
1678        D2: Dimension,
1679    {
1680        unsafe {
1681            if D::NDIM == D2::NDIM {
1682                // safe because D == D2
1683                let dim = unlimited_transmute::<D, D2>(self.dim);
1684                let strides = unlimited_transmute::<D, D2>(self.strides);
1685                return Ok(ArrayBase::from_data_ptr(self.data, self.ptr)
1686                            .with_strides_dim(strides, dim));
1687            } else if D::NDIM == None || D2::NDIM == None { // one is dynamic dim
1688                // safe because dim, strides are equivalent under a different type
1689                if let Some(dim) = D2::from_dimension(&self.dim) {
1690                    if let Some(strides) = D2::from_dimension(&self.strides) {
1691                        return Ok(self.with_strides_dim(strides, dim));
1692                    }
1693                }
1694            }
1695        }
1696        Err(ShapeError::from_kind(ErrorKind::IncompatibleShape))
1697    }
1698
1699    /// Act like a larger size and/or shape array by *broadcasting*
1700    /// into a larger shape, if possible.
1701    ///
1702    /// Return `None` if shapes can not be broadcast together.
1703    ///
1704    /// ***Background***
1705    ///
1706    ///  * Two axes are compatible if they are equal, or one of them is 1.
1707    ///  * In this instance, only the axes of the smaller side (self) can be 1.
1708    ///
1709    /// Compare axes beginning with the *last* axis of each shape.
1710    ///
1711    /// For example (1, 2, 4) can be broadcast into (7, 6, 2, 4)
1712    /// because its axes are either equal or 1 (or missing);
1713    /// while (2, 2) can *not* be broadcast into (2, 4).
1714    ///
1715    /// The implementation creates a view with strides set to zero for the
1716    /// axes that are to be repeated.
1717    ///
1718    /// The broadcasting documentation for Numpy has more information.
1719    ///
1720    /// ```
1721    /// use ndarray::{aview1, aview2};
1722    ///
1723    /// assert!(
1724    ///     aview1(&[1., 0.]).broadcast((10, 2)).unwrap()
1725    ///     == aview2(&[[1., 0.]; 10])
1726    /// );
1727    /// ```
1728    pub fn broadcast<E>(&self, dim: E) -> Option<ArrayView<'_, A, E::Dim>>
1729    where
1730        E: IntoDimension,
1731        S: Data,
1732    {
1733        /// Return new stride when trying to grow `from` into shape `to`
1734        ///
1735        /// Broadcasting works by returning a "fake stride" where elements
1736        /// to repeat are in axes with 0 stride, so that several indexes point
1737        /// to the same element.
1738        ///
1739        /// **Note:** Cannot be used for mutable iterators, since repeating
1740        /// elements would create aliasing pointers.
1741        fn upcast<D: Dimension, E: Dimension>(to: &D, from: &E, stride: &E) -> Option<D> {
1742            // Make sure the product of non-zero axis lengths does not exceed
1743            // `isize::MAX`. This is the only safety check we need to perform
1744            // because all the other constraints of `ArrayBase` are guaranteed
1745            // to be met since we're starting from a valid `ArrayBase`.
1746            let _ = size_of_shape_checked(to).ok()?;
1747
1748            let mut new_stride = to.clone();
1749            // begin at the back (the least significant dimension)
1750            // size of the axis has to either agree or `from` has to be 1
1751            if to.ndim() < from.ndim() {
1752                return None;
1753            }
1754
1755            {
1756                let mut new_stride_iter = new_stride.slice_mut().iter_mut().rev();
1757                for ((er, es), dr) in from
1758                    .slice()
1759                    .iter()
1760                    .rev()
1761                    .zip(stride.slice().iter().rev())
1762                    .zip(new_stride_iter.by_ref())
1763                {
1764                    /* update strides */
1765                    if *dr == *er {
1766                        /* keep stride */
1767                        *dr = *es;
1768                    } else if *er == 1 {
1769                        /* dead dimension, zero stride */
1770                        *dr = 0
1771                    } else {
1772                        return None;
1773                    }
1774                }
1775
1776                /* set remaining strides to zero */
1777                for dr in new_stride_iter {
1778                    *dr = 0;
1779                }
1780            }
1781            Some(new_stride)
1782        }
1783        let dim = dim.into_dimension();
1784
1785        // Note: zero strides are safe precisely because we return an read-only view
1786        let broadcast_strides = match upcast(&dim, &self.dim, &self.strides) {
1787            Some(st) => st,
1788            None => return None,
1789        };
1790        unsafe { Some(ArrayView::new(self.ptr, dim, broadcast_strides)) }
1791    }
1792
1793    /// For two arrays or views, find their common shape if possible and
1794    /// broadcast them as array views into that shape.
1795    ///
1796    /// Return `ShapeError` if their shapes can not be broadcast together.
1797    #[allow(clippy::type_complexity)]
1798    pub(crate) fn broadcast_with<'a, 'b, B, S2, E>(&'a self, other: &'b ArrayBase<S2, E>) ->
1799        Result<(ArrayView<'a, A, DimMaxOf<D, E>>, ArrayView<'b, B, DimMaxOf<D, E>>), ShapeError>
1800    where
1801        S: Data<Elem=A>,
1802        S2: Data<Elem=B>,
1803        D: Dimension + DimMax<E>,
1804        E: Dimension,
1805    {
1806        let shape = co_broadcast::<D, E, <D as DimMax<E>>::Output>(&self.dim, &other.dim)?;
1807        if let Some(view1) = self.broadcast(shape.clone()) {
1808            if let Some(view2) = other.broadcast(shape) {
1809                return Ok((view1, view2));
1810            }
1811        }
1812        Err(from_kind(ErrorKind::IncompatibleShape))
1813    }
1814
1815    /// Swap axes `ax` and `bx`.
1816    ///
1817    /// This does not move any data, it just adjusts the array’s dimensions
1818    /// and strides.
1819    ///
1820    /// **Panics** if the axes are out of bounds.
1821    ///
1822    /// ```
1823    /// use ndarray::arr2;
1824    ///
1825    /// let mut a = arr2(&[[1., 2., 3.]]);
1826    /// a.swap_axes(0, 1);
1827    /// assert!(
1828    ///     a == arr2(&[[1.], [2.], [3.]])
1829    /// );
1830    /// ```
1831    pub fn swap_axes(&mut self, ax: usize, bx: usize) {
1832        self.dim.slice_mut().swap(ax, bx);
1833        self.strides.slice_mut().swap(ax, bx);
1834    }
1835
1836    /// Permute the axes.
1837    ///
1838    /// This does not move any data, it just adjusts the array’s dimensions
1839    /// and strides.
1840    ///
1841    /// *i* in the *j*-th place in the axes sequence means `self`'s *i*-th axis
1842    /// becomes `self.permuted_axes()`'s *j*-th axis
1843    ///
1844    /// **Panics** if any of the axes are out of bounds, if an axis is missing,
1845    /// or if an axis is repeated more than once.
1846    ///
1847    /// # Examples
1848    ///
1849    /// ```
1850    /// use ndarray::{arr2, Array3};
1851    ///
1852    /// let a = arr2(&[[0, 1], [2, 3]]);
1853    /// assert_eq!(a.view().permuted_axes([1, 0]), a.t());
1854    ///
1855    /// let b = Array3::<u8>::zeros((1, 2, 3));
1856    /// assert_eq!(b.permuted_axes([1, 0, 2]).shape(), &[2, 1, 3]);
1857    /// ```
1858    pub fn permuted_axes<T>(self, axes: T) -> ArrayBase<S, D>
1859    where
1860        T: IntoDimension<Dim = D>,
1861    {
1862        let axes = axes.into_dimension();
1863        // Ensure that each axis is used exactly once.
1864        let mut usage_counts = D::zeros(self.ndim());
1865        for axis in axes.slice() {
1866            usage_counts[*axis] += 1;
1867        }
1868        for count in usage_counts.slice() {
1869            assert_eq!(*count, 1, "each axis must be listed exactly once");
1870        }
1871        // Determine the new shape and strides.
1872        let mut new_dim = usage_counts; // reuse to avoid an allocation
1873        let mut new_strides = D::zeros(self.ndim());
1874        {
1875            let dim = self.dim.slice();
1876            let strides = self.strides.slice();
1877            for (new_axis, &axis) in axes.slice().iter().enumerate() {
1878                new_dim[new_axis] = dim[axis];
1879                new_strides[new_axis] = strides[axis];
1880            }
1881        }
1882        // safe because axis invariants are checked above; they are a permutation of the old
1883        unsafe {
1884            self.with_strides_dim(new_strides, new_dim)
1885        }
1886    }
1887
1888    /// Transpose the array by reversing axes.
1889    ///
1890    /// Transposition reverses the order of the axes (dimensions and strides)
1891    /// while retaining the same data.
1892    pub fn reversed_axes(mut self) -> ArrayBase<S, D> {
1893        self.dim.slice_mut().reverse();
1894        self.strides.slice_mut().reverse();
1895        self
1896    }
1897
1898    /// Return a transposed view of the array.
1899    ///
1900    /// This is a shorthand for `self.view().reversed_axes()`.
1901    ///
1902    /// See also the more general methods `.reversed_axes()` and `.swap_axes()`.
1903    pub fn t(&self) -> ArrayView<'_, A, D>
1904    where
1905        S: Data,
1906    {
1907        self.view().reversed_axes()
1908    }
1909
1910    /// Return an iterator over the length and stride of each axis.
1911    pub fn axes(&self) -> Axes<'_, D> {
1912        axes_of(&self.dim, &self.strides)
1913    }
1914
1915    /*
1916    /// Return the axis with the least stride (by absolute value)
1917    pub fn min_stride_axis(&self) -> Axis {
1918        self.dim.min_stride_axis(&self.strides)
1919    }
1920    */
1921
1922    /// Return the axis with the greatest stride (by absolute value),
1923    /// preferring axes with len > 1.
1924    pub fn max_stride_axis(&self) -> Axis {
1925        self.dim.max_stride_axis(&self.strides)
1926    }
1927
1928    /// Reverse the stride of `axis`.
1929    ///
1930    /// ***Panics*** if the axis is out of bounds.
1931    pub fn invert_axis(&mut self, axis: Axis) {
1932        unsafe {
1933            let s = self.strides.axis(axis) as Ixs;
1934            let m = self.dim.axis(axis);
1935            if m != 0 {
1936                self.ptr = self.ptr.offset(stride_offset(m - 1, s as Ix));
1937            }
1938            self.strides.set_axis(axis, (-s) as Ix);
1939        }
1940    }
1941
1942    /// If possible, merge in the axis `take` to `into`.
1943    ///
1944    /// Returns `true` iff the axes are now merged.
1945    ///
1946    /// This method merges the axes if movement along the two original axes
1947    /// (moving fastest along the `into` axis) can be equivalently represented
1948    /// as movement along one (merged) axis. Merging the axes preserves this
1949    /// order in the merged axis. If `take` and `into` are the same axis, then
1950    /// the axis is "merged" if its length is ≤ 1.
1951    ///
1952    /// If the return value is `true`, then the following hold:
1953    ///
1954    /// * The new length of the `into` axis is the product of the original
1955    ///   lengths of the two axes.
1956    ///
1957    /// * The new length of the `take` axis is 0 if the product of the original
1958    ///   lengths of the two axes is 0, and 1 otherwise.
1959    ///
1960    /// If the return value is `false`, then merging is not possible, and the
1961    /// original shape and strides have been preserved.
1962    ///
1963    /// Note that the ordering constraint means that if it's possible to merge
1964    /// `take` into `into`, it's usually not possible to merge `into` into
1965    /// `take`, and vice versa.
1966    ///
1967    /// ```
1968    /// use ndarray::Array3;
1969    /// use ndarray::Axis;
1970    ///
1971    /// let mut a = Array3::<f64>::zeros((2, 3, 4));
1972    /// assert!(a.merge_axes(Axis(1), Axis(2)));
1973    /// assert_eq!(a.shape(), &[2, 1, 12]);
1974    /// ```
1975    ///
1976    /// ***Panics*** if an axis is out of bounds.
1977    pub fn merge_axes(&mut self, take: Axis, into: Axis) -> bool {
1978        merge_axes(&mut self.dim, &mut self.strides, take, into)
1979    }
1980
1981    /// Insert new array axis at `axis` and return the result.
1982    ///
1983    /// ```
1984    /// use ndarray::{Array3, Axis, arr1, arr2};
1985    ///
1986    /// // Convert a 1-D array into a row vector (2-D).
1987    /// let a = arr1(&[1, 2, 3]);
1988    /// let row = a.insert_axis(Axis(0));
1989    /// assert_eq!(row, arr2(&[[1, 2, 3]]));
1990    ///
1991    /// // Convert a 1-D array into a column vector (2-D).
1992    /// let b = arr1(&[1, 2, 3]);
1993    /// let col = b.insert_axis(Axis(1));
1994    /// assert_eq!(col, arr2(&[[1], [2], [3]]));
1995    ///
1996    /// // The new axis always has length 1.
1997    /// let b = Array3::<f64>::zeros((3, 4, 5));
1998    /// assert_eq!(b.insert_axis(Axis(2)).shape(), &[3, 4, 1, 5]);
1999    /// ```
2000    ///
2001    /// ***Panics*** if the axis is out of bounds.
2002    pub fn insert_axis(self, axis: Axis) -> ArrayBase<S, D::Larger> {
2003        assert!(axis.index() <= self.ndim());
2004        // safe because a new axis of length one does not affect memory layout
2005        unsafe {
2006            let strides = self.strides.insert_axis(axis);
2007            let dim = self.dim.insert_axis(axis);
2008            self.with_strides_dim(strides, dim)
2009        }
2010    }
2011
2012    /// Remove array axis `axis` and return the result.
2013    ///
2014    /// This is equivalent to `.index_axis_move(axis, 0)` and makes most sense to use if the
2015    /// axis to remove is of length 1.
2016    ///
2017    /// **Panics** if the axis is out of bounds or its length is zero.
2018    pub fn remove_axis(self, axis: Axis) -> ArrayBase<S, D::Smaller>
2019    where
2020        D: RemoveAxis,
2021    {
2022        self.index_axis_move(axis, 0)
2023    }
2024
2025    pub(crate) fn pointer_is_inbounds(&self) -> bool {
2026        match self.data._data_slice() {
2027            None => {
2028                // special case for non-owned views
2029                true
2030            }
2031            Some(slc) => {
2032                let ptr = slc.as_ptr() as *mut A;
2033                let end = unsafe { ptr.add(slc.len()) };
2034                self.ptr.as_ptr() >= ptr && self.ptr.as_ptr() <= end
2035            }
2036        }
2037    }
2038
2039    /// Perform an elementwise assigment to `self` from `rhs`.
2040    ///
2041    /// If their shapes disagree, `rhs` is broadcast to the shape of `self`.
2042    ///
2043    /// **Panics** if broadcasting isn’t possible.
2044    pub fn assign<E: Dimension, S2>(&mut self, rhs: &ArrayBase<S2, E>)
2045    where
2046        S: DataMut,
2047        A: Clone,
2048        S2: Data<Elem = A>,
2049    {
2050        self.zip_mut_with(rhs, |x, y| *x = y.clone());
2051    }
2052
2053    /// Perform an elementwise assigment of values cloned from `self` into array or producer `to`.
2054    ///
2055    /// The destination `to` can be another array or a producer of assignable elements.
2056    /// [`AssignElem`] determines how elements are assigned.
2057    ///
2058    /// **Panics** if shapes disagree.
2059    pub fn assign_to<P>(&self, to: P)
2060    where
2061        S: Data,
2062        P: IntoNdProducer<Dim = D>,
2063        P::Item: AssignElem<A>,
2064        A: Clone,
2065    {
2066        Zip::from(self)
2067            .map_assign_into(to, A::clone);
2068    }
2069
2070    /// Perform an elementwise assigment to `self` from element `x`.
2071    pub fn fill(&mut self, x: A)
2072    where
2073        S: DataMut,
2074        A: Clone,
2075    {
2076        self.map_inplace(move |elt| *elt = x.clone());
2077    }
2078
2079    pub(crate) fn zip_mut_with_same_shape<B, S2, E, F>(&mut self, rhs: &ArrayBase<S2, E>, mut f: F)
2080    where
2081        S: DataMut,
2082        S2: Data<Elem = B>,
2083        E: Dimension,
2084        F: FnMut(&mut A, &B),
2085    {
2086        debug_assert_eq!(self.shape(), rhs.shape());
2087
2088        if self.dim.strides_equivalent(&self.strides, &rhs.strides) {
2089            if let Some(self_s) = self.as_slice_memory_order_mut() {
2090                if let Some(rhs_s) = rhs.as_slice_memory_order() {
2091                    for (s, r) in self_s.iter_mut().zip(rhs_s) {
2092                        f(s, &r);
2093                    }
2094                    return;
2095                }
2096            }
2097        }
2098
2099        // Otherwise, fall back to the outer iter
2100        self.zip_mut_with_by_rows(rhs, f);
2101    }
2102
2103    // zip two arrays where they have different layout or strides
2104    #[inline(always)]
2105    fn zip_mut_with_by_rows<B, S2, E, F>(&mut self, rhs: &ArrayBase<S2, E>, mut f: F)
2106    where
2107        S: DataMut,
2108        S2: Data<Elem = B>,
2109        E: Dimension,
2110        F: FnMut(&mut A, &B),
2111    {
2112        debug_assert_eq!(self.shape(), rhs.shape());
2113        debug_assert_ne!(self.ndim(), 0);
2114
2115        // break the arrays up into their inner rows
2116        let n = self.ndim();
2117        let dim = self.raw_dim();
2118        Zip::from(LanesMut::new(self.view_mut(), Axis(n - 1)))
2119            .and(Lanes::new(rhs.broadcast_assume(dim), Axis(n - 1)))
2120            .for_each(move |s_row, r_row| Zip::from(s_row).and(r_row).for_each(|a, b| f(a, b)));
2121    }
2122
2123    fn zip_mut_with_elem<B, F>(&mut self, rhs_elem: &B, mut f: F)
2124    where
2125        S: DataMut,
2126        F: FnMut(&mut A, &B),
2127    {
2128        self.map_inplace(move |elt| f(elt, rhs_elem));
2129    }
2130
2131    /// Traverse two arrays in unspecified order, in lock step,
2132    /// calling the closure `f` on each element pair.
2133    ///
2134    /// If their shapes disagree, `rhs` is broadcast to the shape of `self`.
2135    ///
2136    /// **Panics** if broadcasting isn’t possible.
2137    #[inline]
2138    pub fn zip_mut_with<B, S2, E, F>(&mut self, rhs: &ArrayBase<S2, E>, f: F)
2139    where
2140        S: DataMut,
2141        S2: Data<Elem = B>,
2142        E: Dimension,
2143        F: FnMut(&mut A, &B),
2144    {
2145        if rhs.dim.ndim() == 0 {
2146            // Skip broadcast from 0-dim array
2147            self.zip_mut_with_elem(rhs.get_0d(), f);
2148        } else if self.dim.ndim() == rhs.dim.ndim() && self.shape() == rhs.shape() {
2149            self.zip_mut_with_same_shape(rhs, f);
2150        } else {
2151            let rhs_broadcast = rhs.broadcast_unwrap(self.raw_dim());
2152            self.zip_mut_with_by_rows(&rhs_broadcast, f);
2153        }
2154    }
2155
2156    /// Traverse the array elements and apply a fold,
2157    /// returning the resulting value.
2158    ///
2159    /// Elements are visited in arbitrary order.
2160    pub fn fold<'a, F, B>(&'a self, init: B, f: F) -> B
2161    where
2162        F: FnMut(B, &'a A) -> B,
2163        A: 'a,
2164        S: Data,
2165    {
2166        if let Some(slc) = self.as_slice_memory_order() {
2167            slc.iter().fold(init, f)
2168        } else {
2169            let mut v = self.view();
2170            move_min_stride_axis_to_last(&mut v.dim, &mut v.strides);
2171            v.into_elements_base().fold(init, f)
2172        }
2173    }
2174
2175    /// Call `f` by reference on each element and create a new array
2176    /// with the new values.
2177    ///
2178    /// Elements are visited in arbitrary order.
2179    ///
2180    /// Return an array with the same shape as `self`.
2181    ///
2182    /// ```
2183    /// use ndarray::arr2;
2184    ///
2185    /// let a = arr2(&[[ 0., 1.],
2186    ///                [-1., 2.]]);
2187    /// assert!(
2188    ///     a.map(|x| *x >= 1.0)
2189    ///     == arr2(&[[false, true],
2190    ///               [false, true]])
2191    /// );
2192    /// ```
2193    pub fn map<'a, B, F>(&'a self, f: F) -> Array<B, D>
2194    where
2195        F: FnMut(&'a A) -> B,
2196        A: 'a,
2197        S: Data,
2198    {
2199        if let Some(slc) = self.as_slice_memory_order() {
2200            let v = crate::iterators::to_vec_mapped(slc.iter(), f);
2201            unsafe {
2202                ArrayBase::from_shape_vec_unchecked(
2203                    self.dim.clone().strides(self.strides.clone()),
2204                    v,
2205                )
2206            }
2207        } else {
2208            let v = crate::iterators::to_vec_mapped(self.iter(), f);
2209            unsafe { ArrayBase::from_shape_vec_unchecked(self.dim.clone(), v) }
2210        }
2211    }
2212
2213    /// Call `f` on a mutable reference of each element and create a new array
2214    /// with the new values.
2215    ///
2216    /// Elements are visited in arbitrary order.
2217    ///
2218    /// Return an array with the same shape as `self`.
2219    pub fn map_mut<'a, B, F>(&'a mut self, f: F) -> Array<B, D>
2220    where
2221        F: FnMut(&'a mut A) -> B,
2222        A: 'a,
2223        S: DataMut,
2224    {
2225        let dim = self.dim.clone();
2226        if self.is_contiguous() {
2227            let strides = self.strides.clone();
2228            let slc = self.as_slice_memory_order_mut().unwrap();
2229            let v = crate::iterators::to_vec_mapped(slc.iter_mut(), f);
2230            unsafe { ArrayBase::from_shape_vec_unchecked(dim.strides(strides), v) }
2231        } else {
2232            let v = crate::iterators::to_vec_mapped(self.iter_mut(), f);
2233            unsafe { ArrayBase::from_shape_vec_unchecked(dim, v) }
2234        }
2235    }
2236
2237    /// Call `f` by **v**alue on each element and create a new array
2238    /// with the new values.
2239    ///
2240    /// Elements are visited in arbitrary order.
2241    ///
2242    /// Return an array with the same shape as `self`.
2243    ///
2244    /// ```
2245    /// use ndarray::arr2;
2246    ///
2247    /// let a = arr2(&[[ 0., 1.],
2248    ///                [-1., 2.]]);
2249    /// assert!(
2250    ///     a.mapv(f32::abs) == arr2(&[[0., 1.],
2251    ///                                [1., 2.]])
2252    /// );
2253    /// ```
2254    pub fn mapv<B, F>(&self, mut f: F) -> Array<B, D>
2255    where
2256        F: FnMut(A) -> B,
2257        A: Clone,
2258        S: Data,
2259    {
2260        self.map(move |x| f(x.clone()))
2261    }
2262
2263    /// Call `f` by **v**alue on each element, update the array with the new values
2264    /// and return it.
2265    ///
2266    /// Elements are visited in arbitrary order.
2267    pub fn mapv_into<F>(mut self, f: F) -> Self
2268    where
2269        S: DataMut,
2270        F: FnMut(A) -> A,
2271        A: Clone,
2272    {
2273        self.mapv_inplace(f);
2274        self
2275    }
2276
2277    /// Modify the array in place by calling `f` by mutable reference on each element.
2278    ///
2279    /// Elements are visited in arbitrary order.
2280    pub fn map_inplace<'a, F>(&'a mut self, f: F)
2281    where
2282        S: DataMut,
2283        A: 'a,
2284        F: FnMut(&'a mut A),
2285    {
2286        match self.try_as_slice_memory_order_mut() {
2287            Ok(slc) => slc.iter_mut().for_each(f),
2288            Err(arr) => {
2289                let mut v = arr.view_mut();
2290                move_min_stride_axis_to_last(&mut v.dim, &mut v.strides);
2291                v.into_elements_base().for_each(f);
2292            }
2293        }
2294    }
2295
2296    /// Modify the array in place by calling `f` by **v**alue on each element.
2297    /// The array is updated with the new values.
2298    ///
2299    /// Elements are visited in arbitrary order.
2300    ///
2301    /// ```
2302    /// use approx::assert_abs_diff_eq;
2303    /// use ndarray::arr2;
2304    ///
2305    /// # #[cfg(feature = "approx")] {
2306    /// let mut a = arr2(&[[ 0., 1.],
2307    ///                    [-1., 2.]]);
2308    /// a.mapv_inplace(f32::exp);
2309    /// assert_abs_diff_eq!(
2310    ///     a,
2311    ///     arr2(&[[1.00000, 2.71828],
2312    ///            [0.36788, 7.38906]]),
2313    ///     epsilon = 1e-5,
2314    /// );
2315    /// # }
2316    /// ```
2317    pub fn mapv_inplace<F>(&mut self, mut f: F)
2318    where
2319        S: DataMut,
2320        F: FnMut(A) -> A,
2321        A: Clone,
2322    {
2323        self.map_inplace(move |x| *x = f(x.clone()));
2324    }
2325
2326    /// Call `f` for each element in the array.
2327    ///
2328    /// Elements are visited in arbitrary order.
2329    pub fn for_each<'a, F>(&'a self, mut f: F)
2330    where
2331        F: FnMut(&'a A),
2332        A: 'a,
2333        S: Data,
2334    {
2335        self.fold((), move |(), elt| f(elt))
2336    }
2337
2338    /// Visit each element in the array by calling `f` by reference
2339    /// on each element.
2340    ///
2341    /// Elements are visited in arbitrary order.
2342    #[deprecated(note="Renamed to .for_each()", since="0.15.0")]
2343    pub fn visit<'a, F>(&'a self, f: F)
2344    where
2345        F: FnMut(&'a A),
2346        A: 'a,
2347        S: Data,
2348    {
2349        self.for_each(f)
2350    }
2351
2352    /// Fold along an axis.
2353    ///
2354    /// Combine the elements of each subview with the previous using the `fold`
2355    /// function and initial value `init`.
2356    ///
2357    /// Return the result as an `Array`.
2358    ///
2359    /// **Panics** if `axis` is out of bounds.
2360    pub fn fold_axis<B, F>(&self, axis: Axis, init: B, mut fold: F) -> Array<B, D::Smaller>
2361    where
2362        D: RemoveAxis,
2363        F: FnMut(&B, &A) -> B,
2364        B: Clone,
2365        S: Data,
2366    {
2367        let mut res = Array::from_elem(self.raw_dim().remove_axis(axis), init);
2368        for subview in self.axis_iter(axis) {
2369            res.zip_mut_with(&subview, |x, y| *x = fold(x, y));
2370        }
2371        res
2372    }
2373
2374    /// Reduce the values along an axis into just one value, producing a new
2375    /// array with one less dimension.
2376    ///
2377    /// Elements are visited in arbitrary order.
2378    ///
2379    /// Return the result as an `Array`.
2380    ///
2381    /// **Panics** if `axis` is out of bounds.
2382    pub fn map_axis<'a, B, F>(&'a self, axis: Axis, mut mapping: F) -> Array<B, D::Smaller>
2383    where
2384        D: RemoveAxis,
2385        F: FnMut(ArrayView1<'a, A>) -> B,
2386        A: 'a,
2387        S: Data,
2388    {
2389        let view_len = self.len_of(axis);
2390        let view_stride = self.strides.axis(axis);
2391        if view_len == 0 {
2392            let new_dim = self.dim.remove_axis(axis);
2393            Array::from_shape_simple_fn(new_dim, move || mapping(ArrayView::from(&[])))
2394        } else {
2395            // use the 0th subview as a map to each 1d array view extended from
2396            // the 0th element.
2397            self.index_axis(axis, 0).map(|first_elt| unsafe {
2398                mapping(ArrayView::new_(first_elt, Ix1(view_len), Ix1(view_stride)))
2399            })
2400        }
2401    }
2402
2403    /// Reduce the values along an axis into just one value, producing a new
2404    /// array with one less dimension.
2405    /// 1-dimensional lanes are passed as mutable references to the reducer,
2406    /// allowing for side-effects.
2407    ///
2408    /// Elements are visited in arbitrary order.
2409    ///
2410    /// Return the result as an `Array`.
2411    ///
2412    /// **Panics** if `axis` is out of bounds.
2413    pub fn map_axis_mut<'a, B, F>(&'a mut self, axis: Axis, mut mapping: F) -> Array<B, D::Smaller>
2414    where
2415        D: RemoveAxis,
2416        F: FnMut(ArrayViewMut1<'a, A>) -> B,
2417        A: 'a,
2418        S: DataMut,
2419    {
2420        let view_len = self.len_of(axis);
2421        let view_stride = self.strides.axis(axis);
2422        if view_len == 0 {
2423            let new_dim = self.dim.remove_axis(axis);
2424            Array::from_shape_simple_fn(new_dim, move || mapping(ArrayViewMut::from(&mut [])))
2425        } else {
2426            // use the 0th subview as a map to each 1d array view extended from
2427            // the 0th element.
2428            self.index_axis_mut(axis, 0).map_mut(|first_elt| unsafe {
2429                mapping(ArrayViewMut::new_(
2430                    first_elt,
2431                    Ix1(view_len),
2432                    Ix1(view_stride),
2433                ))
2434            })
2435        }
2436    }
2437
2438    /// Iterates over pairs of consecutive elements along the axis.
2439    ///
2440    /// The first argument to the closure is an element, and the second
2441    /// argument is the next element along the axis. Iteration is guaranteed to
2442    /// proceed in order along the specified axis, but in all other respects
2443    /// the iteration order is unspecified.
2444    ///
2445    /// # Example
2446    ///
2447    /// For example, this can be used to compute the cumulative sum along an
2448    /// axis:
2449    ///
2450    /// ```
2451    /// use ndarray::{array, Axis};
2452    ///
2453    /// let mut arr = array![
2454    ///     [[1, 2], [3, 4], [5, 6]],
2455    ///     [[7, 8], [9, 10], [11, 12]],
2456    /// ];
2457    /// arr.accumulate_axis_inplace(Axis(1), |&prev, curr| *curr += prev);
2458    /// assert_eq!(
2459    ///     arr,
2460    ///     array![
2461    ///         [[1, 2], [4, 6], [9, 12]],
2462    ///         [[7, 8], [16, 18], [27, 30]],
2463    ///     ],
2464    /// );
2465    /// ```
2466    pub fn accumulate_axis_inplace<F>(&mut self, axis: Axis, mut f: F)
2467    where
2468        F: FnMut(&A, &mut A),
2469        S: DataMut,
2470    {
2471        if self.len_of(axis) <= 1 {
2472            return;
2473        }
2474        let mut curr = self.raw_view_mut(); // mut borrow of the array here
2475        let mut prev = curr.raw_view(); // derive further raw views from the same borrow
2476        prev.slice_axis_inplace(axis, Slice::from(..-1));
2477        curr.slice_axis_inplace(axis, Slice::from(1..));
2478        // This implementation relies on `Zip` iterating along `axis` in order.
2479        Zip::from(prev).and(curr).for_each(|prev, curr| unsafe {
2480            // These pointer dereferences and borrows are safe because:
2481            //
2482            // 1. They're pointers to elements in the array.
2483            //
2484            // 2. `S: DataMut` guarantees that elements are safe to borrow
2485            //    mutably and that they don't alias.
2486            //
2487            // 3. The lifetimes of the borrows last only for the duration
2488            //    of the call to `f`, so aliasing across calls to `f`
2489            //    cannot occur.
2490            f(&*prev, &mut *curr)
2491        });
2492    }
2493}
2494
2495
2496/// Transmute from A to B.
2497///
2498/// Like transmute, but does not have the compile-time size check which blocks
2499/// using regular transmute in some cases.
2500///
2501/// **Panics** if the size of A and B are different.
2502#[inline]
2503unsafe fn unlimited_transmute<A, B>(data: A) -> B {
2504    // safe when sizes are equal and caller guarantees that representations are equal
2505    assert_eq!(size_of::<A>(), size_of::<B>());
2506    let old_data = ManuallyDrop::new(data);
2507    (&*old_data as *const A as *const B).read()
2508}
2509
2510type DimMaxOf<A, B> = <A as DimMax<B>>::Output;