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;