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