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